blob: 80807ee0f334ad7ec6f84387395bb6a2e8afadd2 [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
c_hpothu79aab322014-07-14 21:11:01 +0530540/*array index points to MCS and array value points respective rssi*/
541static int rssiMcsTbl[][10] =
542{
543/*MCS 0 1 2 3 4 5 6 7 8 9*/
544 {-82, -79, -77, -74, -70, -66, -65, -64, -59, -57}, //20
545 {-79, -76, -74, -71, -67, -63, -62, -61, -56, -54}, //40
546 {-76, -73, -71, -68, -64, -60, -59, -58, -53, -51} //80
547};
548
Jeff Johnson295189b2012-06-20 16:38:30 -0700549extern struct net_device_ops net_ops_struct;
550
Leo Chang9056f462013-08-01 19:21:11 -0700551#ifdef WLAN_NL80211_TESTMODE
552enum wlan_hdd_tm_attr
553{
554 WLAN_HDD_TM_ATTR_INVALID = 0,
555 WLAN_HDD_TM_ATTR_CMD = 1,
556 WLAN_HDD_TM_ATTR_DATA = 2,
557 WLAN_HDD_TM_ATTR_TYPE = 3,
558 /* keep last */
559 WLAN_HDD_TM_ATTR_AFTER_LAST,
560 WLAN_HDD_TM_ATTR_MAX = WLAN_HDD_TM_ATTR_AFTER_LAST - 1,
561};
562
563enum wlan_hdd_tm_cmd
564{
565 WLAN_HDD_TM_CMD_WLAN_HB = 1,
566};
567
568#define WLAN_HDD_TM_DATA_MAX_LEN 5000
569
570static const struct nla_policy wlan_hdd_tm_policy[WLAN_HDD_TM_ATTR_MAX + 1] =
571{
572 [WLAN_HDD_TM_ATTR_CMD] = { .type = NLA_U32 },
573 [WLAN_HDD_TM_ATTR_DATA] = { .type = NLA_BINARY,
574 .len = WLAN_HDD_TM_DATA_MAX_LEN },
575};
576#endif /* WLAN_NL80211_TESTMODE */
577
Rajesh Chauhan98a31f82014-01-06 20:15:25 -0800578#ifdef FEATURE_WLAN_CH_AVOID
579/*
580 * FUNCTION: wlan_hdd_send_avoid_freq_event
581 * This is called when wlan driver needs to send vendor specific
582 * avoid frequency range event to userspace
583 */
584int wlan_hdd_send_avoid_freq_event(hdd_context_t *pHddCtx,
585 tHddAvoidFreqList *pAvoidFreqList)
586{
587 struct sk_buff *vendor_event;
588
589 ENTER();
590
591 if (!pHddCtx)
592 {
593 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
594 "%s: HDD context is null", __func__);
595 return -1;
596 }
597
598 if (!pAvoidFreqList)
599 {
600 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
601 "%s: pAvoidFreqList is null", __func__);
602 return -1;
603 }
604
605 vendor_event = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
606 sizeof(tHddAvoidFreqList),
Sunil Duttc69bccb2014-05-26 21:30:20 +0530607 QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY_INDEX,
Rajesh Chauhan98a31f82014-01-06 20:15:25 -0800608 GFP_KERNEL);
609 if (!vendor_event)
610 {
611 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
612 "%s: cfg80211_vendor_event_alloc failed", __func__);
613 return -1;
614 }
615
616 memcpy(skb_put(vendor_event, sizeof(tHddAvoidFreqList)),
617 (void *)pAvoidFreqList, sizeof(tHddAvoidFreqList));
618
619 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
620
621 EXIT();
622 return 0;
623}
624#endif /* FEATURE_WLAN_CH_AVOID */
625
Sunil Duttc69bccb2014-05-26 21:30:20 +0530626#ifdef WLAN_FEATURE_LINK_LAYER_STATS
627
628static v_BOOL_t put_wifi_rate_stat( tpSirWifiRateStat stats,
629 struct sk_buff *vendor_event)
630{
631 if (nla_put_u8(vendor_event,
632 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_PREAMBLE,
633 stats->rate.preamble) ||
634 nla_put_u8(vendor_event,
635 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_NSS,
636 stats->rate.nss) ||
637 nla_put_u8(vendor_event,
638 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_BW,
639 stats->rate.bw) ||
640 nla_put_u8(vendor_event,
641 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_MCS_INDEX,
642 stats->rate.rateMcsIdx) ||
643 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_BIT_RATE,
644 stats->rate.bitrate ) ||
645 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_TX_MPDU,
646 stats->txMpdu ) ||
647 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RX_MPDU,
648 stats->rxMpdu ) ||
649 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_MPDU_LOST,
650 stats->mpduLost ) ||
651 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES,
652 stats->retries) ||
653 nla_put_u32(vendor_event,
654 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES_SHORT,
655 stats->retriesShort ) ||
656 nla_put_u32(vendor_event,
657 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES_LONG,
658 stats->retriesLong))
659 {
660 hddLog(VOS_TRACE_LEVEL_ERROR,
661 FL("QCA_WLAN_VENDOR_ATTR put fail"));
662 return FALSE;
663 }
664 return TRUE;
665}
666
667static v_BOOL_t put_wifi_peer_info( tpSirWifiPeerInfo stats,
668 struct sk_buff *vendor_event)
669{
670 u32 i = 0;
671 struct nlattr *rateInfo;
672 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_TYPE,
673 stats->type) ||
674 nla_put(vendor_event,
675 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_MAC_ADDRESS,
676 VOS_MAC_ADDR_SIZE, &stats->peerMacAddress[0]) ||
677 nla_put_u32(vendor_event,
678 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_CAPABILITIES,
679 stats->capabilities) ||
680 nla_put_u32(vendor_event,
681 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_NUM_RATES,
682 stats->numRate))
683 {
684 hddLog(VOS_TRACE_LEVEL_ERROR,
685 FL("QCA_WLAN_VENDOR_ATTR put fail"));
686 goto error;
687 }
688
689 rateInfo = nla_nest_start(vendor_event,
690 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_RATE_INFO);
691 for (i = 0; i < stats->numRate; i++)
692 {
693 struct nlattr *rates;
694 tpSirWifiRateStat pRateStats = (tpSirWifiRateStat )((uint8 *)
695 stats->rateStats +
696 (i * sizeof(tSirWifiRateStat)));
697 rates = nla_nest_start(vendor_event, i);
698
699 if (FALSE == put_wifi_rate_stat(pRateStats, vendor_event))
700 {
701 hddLog(VOS_TRACE_LEVEL_ERROR,
702 FL("QCA_WLAN_VENDOR_ATTR put fail"));
703 return FALSE;
704 }
705 nla_nest_end(vendor_event, rates);
706 }
707 nla_nest_end(vendor_event, rateInfo);
708
709 return TRUE;
710error:
711 return FALSE;
712}
713
714static v_BOOL_t put_wifi_wmm_ac_stat( tpSirWifiWmmAcStat stats,
715 struct sk_buff *vendor_event)
716{
717 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_AC,
718 stats->ac ) ||
719 nla_put_u32(vendor_event,
720 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_MPDU,
721 stats->txMpdu ) ||
722 nla_put_u32(vendor_event,
723 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_MPDU,
724 stats->rxMpdu ) ||
725 nla_put_u32(vendor_event,
726 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_MCAST,
727 stats->txMcast ) ||
728 nla_put_u32(vendor_event,
729 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_MCAST,
730 stats->rxMcast ) ||
731 nla_put_u32(vendor_event,
732 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_AMPDU,
733 stats->rxAmpdu ) ||
734 nla_put_u32(vendor_event,
735 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_AMPDU,
736 stats->txAmpdu ) ||
737 nla_put_u32(vendor_event,
738 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_MPDU_LOST,
739 stats->mpduLost )||
740 nla_put_u32(vendor_event,
741 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES,
742 stats->retries ) ||
743 nla_put_u32(vendor_event,
744 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES_SHORT,
745 stats->retriesShort ) ||
746 nla_put_u32(vendor_event,
747 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES_LONG,
748 stats->retriesLong ) ||
749 nla_put_u32(vendor_event,
750 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_MIN,
751 stats->contentionTimeMin ) ||
752 nla_put_u32(vendor_event,
753 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_MAX,
754 stats->contentionTimeMax ) ||
755 nla_put_u32(vendor_event,
756 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_AVG,
757 stats->contentionTimeAvg ) ||
758 nla_put_u32(vendor_event,
759 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_NUM_SAMPLES,
760 stats->contentionNumSamples ))
761 {
762 hddLog(VOS_TRACE_LEVEL_ERROR,
763 FL("QCA_WLAN_VENDOR_ATTR put fail") );
764 return FALSE;
765 }
766 return TRUE;
767}
768
769static v_BOOL_t put_wifi_interface_info(tpSirWifiInterfaceInfo stats,
770 struct sk_buff *vendor_event)
771{
772 if (nla_put_u32(vendor_event,
773 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_MODE, stats->mode ) ||
774 nla_put(vendor_event,
775 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_MAC_ADDR,
776 VOS_MAC_ADDR_SIZE, stats->macAddr) ||
777 nla_put_u32(vendor_event,
778 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_STATE,
779 stats->state ) ||
780 nla_put_u32(vendor_event,
781 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_ROAMING,
782 stats->roaming ) ||
783 nla_put_u32(vendor_event,
784 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_CAPABILITIES,
785 stats->capabilities ) ||
786 nla_put(vendor_event,
787 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_SSID,
788 strlen(stats->ssid), stats->ssid) ||
789 nla_put(vendor_event,
790 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_BSSID,
791 WNI_CFG_BSSID_LEN, stats->bssid) ||
792 nla_put(vendor_event,
793 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_AP_COUNTRY_STR,
794 WNI_CFG_COUNTRY_CODE_LEN, stats->apCountryStr) ||
795 nla_put(vendor_event,
796 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_COUNTRY_STR,
797 WNI_CFG_COUNTRY_CODE_LEN, stats->countryStr)
798 )
799 {
800 hddLog(VOS_TRACE_LEVEL_ERROR,
801 FL("QCA_WLAN_VENDOR_ATTR put fail") );
802 return FALSE;
803 }
804 return TRUE;
805}
806
807static v_BOOL_t put_wifi_iface_stats(tpSirWifiIfaceStat pWifiIfaceStat,
808 struct sk_buff *vendor_event)
809{
810 int i = 0;
811 struct nlattr *wmmInfo;
812 if (FALSE == put_wifi_interface_info(
813 &pWifiIfaceStat->info,
814 vendor_event))
815 {
816 hddLog(VOS_TRACE_LEVEL_ERROR,
817 FL("QCA_WLAN_VENDOR_ATTR put fail") );
818 return FALSE;
819
820 }
821
822 if (nla_put_u32(vendor_event,
823 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_BEACON_RX,
824 pWifiIfaceStat->beaconRx) ||
825 nla_put_u32(vendor_event,
826 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_RX,
827 pWifiIfaceStat->mgmtRx) ||
828 nla_put_u32(vendor_event,
829 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_ACTION_RX,
830 pWifiIfaceStat->mgmtActionRx) ||
831 nla_put_u32(vendor_event,
832 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_ACTION_TX,
833 pWifiIfaceStat->mgmtActionTx) ||
834 nla_put_u32(vendor_event,
835 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_MGMT,
836 pWifiIfaceStat->rssiMgmt) ||
837 nla_put_u32(vendor_event,
838 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_DATA,
839 pWifiIfaceStat->rssiData) ||
840 nla_put_u32(vendor_event,
841 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_ACK,
842 pWifiIfaceStat->rssiAck))
843 {
844 hddLog(VOS_TRACE_LEVEL_ERROR,
845 FL("QCA_WLAN_VENDOR_ATTR put fail"));
846 return FALSE;
847 }
848
849 wmmInfo = nla_nest_start(vendor_event,
850 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_INFO);
851 for (i = 0; i < WIFI_AC_MAX; i++)
852 {
853 struct nlattr *wmmStats;
854 wmmStats = nla_nest_start(vendor_event, i);
855 if (FALSE == put_wifi_wmm_ac_stat(
856 &pWifiIfaceStat->AccessclassStats[i],
857 vendor_event))
858 {
859 hddLog(VOS_TRACE_LEVEL_ERROR,
860 FL("QCA_WLAN_VENDOR_ATTR put Fail"));
861 return FALSE;
862 }
863
864 nla_nest_end(vendor_event, wmmStats);
865 }
866 nla_nest_end(vendor_event, wmmInfo);
867 return TRUE;
868}
869
870static tSirWifiInterfaceMode
871 hdd_map_device_to_ll_iface_mode ( int deviceMode )
872{
873 switch (deviceMode)
874 {
875 case WLAN_HDD_INFRA_STATION:
876 return WIFI_INTERFACE_STA;
877 case WLAN_HDD_SOFTAP:
878 return WIFI_INTERFACE_SOFTAP;
879 case WLAN_HDD_P2P_CLIENT:
880 return WIFI_INTERFACE_P2P_CLIENT;
881 case WLAN_HDD_P2P_GO:
882 return WIFI_INTERFACE_P2P_GO;
883 case WLAN_HDD_IBSS:
884 return WIFI_INTERFACE_IBSS;
885 default:
886 /* Return Interface Mode as STA for all the unsupported modes */
887 return WIFI_INTERFACE_STA;
888 }
889}
890
891static v_BOOL_t hdd_get_interface_info(hdd_adapter_t *pAdapter,
892 tpSirWifiInterfaceInfo pInfo)
893{
894 v_U8_t *staMac = NULL;
895 hdd_station_ctx_t *pHddStaCtx;
896 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
897 tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
898
899 pInfo->mode = hdd_map_device_to_ll_iface_mode(pAdapter->device_mode);
900
901 vos_mem_copy(pInfo->macAddr,
902 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
903
904 if (((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
905 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
906 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode)))
907 {
908 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
909 if (eConnectionState_NotConnected == pHddStaCtx->conn_info.connState)
910 {
911 pInfo->state = WIFI_DISCONNECTED;
912 }
913 if (eConnectionState_Connecting == pHddStaCtx->conn_info.connState)
914 {
915 hddLog(VOS_TRACE_LEVEL_ERROR,
916 "%s: Session ID %d, Connection is in progress", __func__,
917 pAdapter->sessionId);
918 pInfo->state = WIFI_ASSOCIATING;
919 }
920 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
921 (VOS_FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
922 {
923 staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]);
924 hddLog(VOS_TRACE_LEVEL_ERROR,
925 "%s: client " MAC_ADDRESS_STR
926 " is in the middle of WPS/EAPOL exchange.", __func__,
927 MAC_ADDR_ARRAY(staMac));
928 pInfo->state = WIFI_AUTHENTICATING;
929 }
930 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
931 {
932 pInfo->state = WIFI_ASSOCIATED;
933 vos_mem_copy(pInfo->bssid,
934 &pHddStaCtx->conn_info.bssId, WNI_CFG_BSSID_LEN);
935 vos_mem_copy(pInfo->ssid,
936 pHddStaCtx->conn_info.SSID.SSID.ssId,
937 pHddStaCtx->conn_info.SSID.SSID.length);
938 //NULL Terminate the string.
939 pInfo->ssid[pHddStaCtx->conn_info.SSID.SSID.length] = 0;
940 }
941 }
942 vos_mem_copy(pInfo->countryStr,
943 pMac->scan.countryCodeCurrent, WNI_CFG_COUNTRY_CODE_LEN);
944
945 vos_mem_copy(pInfo->apCountryStr,
946 pMac->scan.countryCodeCurrent, WNI_CFG_COUNTRY_CODE_LEN);
947
948 return TRUE;
949}
950
951/*
952 * hdd_link_layer_process_peer_stats () - This function is called after
953 * receiving Link Layer Peer statistics from FW.This function converts
954 * the firmware data to the NL data and sends the same to the kernel/upper
955 * layers.
956 */
957static v_VOID_t hdd_link_layer_process_peer_stats(hdd_adapter_t *pAdapter,
958 v_VOID_t *pData)
959{
960 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
961 tpSirWifiRateStat pWifiRateStat;
962 tpSirWifiPeerStat pWifiPeerStat;
963 tpSirWifiPeerInfo pWifiPeerInfo;
964 struct nlattr *peerInfo;
965 struct sk_buff *vendor_event;
966 int status, i;
967
968 status = wlan_hdd_validate_context(pHddCtx);
969 if (0 != status)
970 {
971 hddLog(VOS_TRACE_LEVEL_ERROR,
972 FL("HDD context is not valid") );
973 return;
974 }
975
976 pWifiPeerStat = (tpSirWifiPeerStat) pData;
977
978 hddLog(VOS_TRACE_LEVEL_INFO,
979 "LL_STATS_PEER_ALL : numPeers %u",
980 pWifiPeerStat->numPeers);
981 {
982 for (i = 0; i < pWifiPeerStat->numPeers; i++)
983 {
984 pWifiPeerInfo = (tpSirWifiPeerInfo)
985 ((uint8 *)pWifiPeerStat->peerInfo +
986 ( i * sizeof(tSirWifiPeerInfo)));
987
988 hddLog(VOS_TRACE_LEVEL_INFO,
989 " %d) LL_STATS Channel Stats "
990 " Peer Type %u "
991 " peerMacAddress %pM "
992 " capabilities 0x%x "
993 " numRate %u ",
994 i,
995 pWifiPeerInfo->type,
996 pWifiPeerInfo->peerMacAddress,
997 pWifiPeerInfo->capabilities,
998 pWifiPeerInfo->numRate);
999 {
1000 int j;
1001 for (j = 0; j < pWifiPeerInfo->numRate; j++)
1002 {
1003 pWifiRateStat = (tpSirWifiRateStat)
1004 ((tANI_U8 *) pWifiPeerInfo->rateStats +
1005 ( j * sizeof(tSirWifiRateStat)));
1006
1007 hddLog(VOS_TRACE_LEVEL_INFO,
1008 " peer Rate Stats "
1009 " preamble %u "
1010 " nss %u "
1011 " bw %u "
1012 " rateMcsIdx %u "
1013 " reserved %u "
1014 " bitrate %u "
1015 " txMpdu %u "
1016 " rxMpdu %u "
1017 " mpduLost %u "
1018 " retries %u "
1019 " retriesShort %u "
1020 " retriesLong %u",
1021 pWifiRateStat->rate.preamble,
1022 pWifiRateStat->rate.nss,
1023 pWifiRateStat->rate.bw,
1024 pWifiRateStat->rate.rateMcsIdx,
1025 pWifiRateStat->rate.reserved,
1026 pWifiRateStat->rate.bitrate,
1027 pWifiRateStat->txMpdu,
1028 pWifiRateStat->rxMpdu,
1029 pWifiRateStat->mpduLost,
1030 pWifiRateStat->retries,
1031 pWifiRateStat->retriesShort,
1032 pWifiRateStat->retriesLong);
1033 }
1034 }
1035 }
1036 }
1037
1038 /*
1039 * Allocate a size of 4096 for the peer stats comprising
1040 * each of size = sizeof (tSirWifiPeerInfo) + numRate *
1041 * sizeof (tSirWifiRateStat).Each field is put with an
1042 * NL attribute.The size of 4096 is considered assuming
1043 * that number of rates shall not exceed beyond 50 with
1044 * the sizeof (tSirWifiRateStat) being 32.
1045 */
1046 vendor_event = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
1047 LL_STATS_EVENT_BUF_SIZE + NLMSG_HDRLEN,
1048 QCA_NL80211_VENDOR_SUBCMD_LL_PEER_INFO_STATS_INDEX,
1049 GFP_KERNEL);
1050 if (!vendor_event)
1051 {
1052 hddLog(VOS_TRACE_LEVEL_ERROR,
1053 "%s: cfg80211_vendor_event_alloc failed",
1054 __func__);
1055 return;
1056 }
1057 if (nla_put_u32(vendor_event,
1058 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_NUM_PEERS,
1059 pWifiPeerStat->numPeers))
1060 {
1061 hddLog(VOS_TRACE_LEVEL_ERROR,
1062 "%s: QCA_WLAN_VENDOR_ATTR put fail", __func__);
1063 kfree_skb(vendor_event);
1064 return;
1065 }
1066
1067 peerInfo = nla_nest_start(vendor_event,
1068 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO);
1069
1070 pWifiPeerInfo = (tpSirWifiPeerInfo) ((uint8 *)
1071 pWifiPeerStat->peerInfo);
1072
1073 for (i = 1; i <= pWifiPeerStat->numPeers; i++)
1074 {
1075 struct nlattr *peers = nla_nest_start(vendor_event, i);
1076 int numRate = pWifiPeerInfo->numRate;
1077
1078 if (FALSE == put_wifi_peer_info(
1079 pWifiPeerInfo, vendor_event))
1080 {
1081 hddLog(VOS_TRACE_LEVEL_ERROR,
1082 "%s: put_wifi_peer_info put fail", __func__);
1083 kfree_skb(vendor_event);
1084 return;
1085 }
1086
1087 pWifiPeerInfo = (tpSirWifiPeerInfo) ((uint8 *)
1088 pWifiPeerStat->peerInfo +
1089 (i * sizeof(tSirWifiPeerInfo)) +
1090 (numRate * sizeof (tSirWifiRateStat)));
1091 nla_nest_end(vendor_event, peers);
1092 }
1093 nla_nest_end(vendor_event, peerInfo);
1094 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
1095}
1096
1097/*
1098 * hdd_link_layer_process_iface_stats () - This function is called after
1099 * receiving Link Layer Interface statistics from FW.This function converts
1100 * the firmware data to the NL data and sends the same to the kernel/upper
1101 * layers.
1102 */
1103static v_VOID_t hdd_link_layer_process_iface_stats(hdd_adapter_t *pAdapter,
1104 v_VOID_t *pData)
1105{
1106 tpSirWifiIfaceStat pWifiIfaceStat;
1107 struct sk_buff *vendor_event;
1108 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1109 int status;
1110
1111 status = wlan_hdd_validate_context(pHddCtx);
1112 if (0 != status)
1113 {
1114 hddLog(VOS_TRACE_LEVEL_ERROR,
1115 FL("HDD context is not valid") );
1116 return;
1117 }
1118 /*
1119 * Allocate a size of 4096 for the interface stats comprising
1120 * sizeof (tpSirWifiIfaceStat).The size of 4096 is considered
1121 * assuming that all these fit with in the limit.Please take
1122 * a call on the limit based on the data requirements on
1123 * interface statistics.
1124 */
1125 vendor_event = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
1126 LL_STATS_EVENT_BUF_SIZE + NLMSG_HDRLEN,
1127 QCA_NL80211_VENDOR_SUBCMD_LL_IFACE_STATS_INDEX,
1128 GFP_KERNEL);
1129 if (!vendor_event)
1130 {
1131 hddLog(VOS_TRACE_LEVEL_ERROR,
1132 FL("cfg80211_vendor_event_alloc failed") );
1133 return;
1134 }
1135
1136 pWifiIfaceStat = (tpSirWifiIfaceStat) pData;
1137
1138 hddLog(VOS_TRACE_LEVEL_INFO,
1139 "WMI_LINK_STATS_IFACE Data");
1140
1141 hddLog(VOS_TRACE_LEVEL_INFO,
1142 "LL_STATS_IFACE: "
1143 " Mode %u "
1144 " MAC %pM "
1145 " State %u "
1146 " Roaming %u "
1147 " capabilities 0x%x "
1148 " SSID %s "
1149 " BSSID %pM",
1150 pWifiIfaceStat->info.mode,
1151 pWifiIfaceStat->info.macAddr,
1152 pWifiIfaceStat->info.state,
1153 pWifiIfaceStat->info.roaming,
1154 pWifiIfaceStat->info.capabilities,
1155 pWifiIfaceStat->info.ssid,
1156 pWifiIfaceStat->info.bssid);
1157
1158 hddLog(VOS_TRACE_LEVEL_INFO,
1159 " AP country str: %c%c%c",
1160 pWifiIfaceStat->info.apCountryStr[0],
1161 pWifiIfaceStat->info.apCountryStr[1],
1162 pWifiIfaceStat->info.apCountryStr[2]);
1163
1164
1165 hddLog(VOS_TRACE_LEVEL_INFO,
1166 " Country Str Association: %c%c%c",
1167 pWifiIfaceStat->info.countryStr[0],
1168 pWifiIfaceStat->info.countryStr[1],
1169 pWifiIfaceStat->info.countryStr[2]);
1170
1171 hddLog(VOS_TRACE_LEVEL_INFO,
1172 " beaconRx %u "
1173 " mgmtRx %u "
1174 " mgmtActionRx %u "
1175 " mgmtActionTx %u "
1176 " rssiMgmt %u "
1177 " rssiData %u "
1178 " rssiAck %u",
1179 pWifiIfaceStat->beaconRx,
1180 pWifiIfaceStat->mgmtRx,
1181 pWifiIfaceStat->mgmtActionRx,
1182 pWifiIfaceStat->mgmtActionTx,
1183 pWifiIfaceStat->rssiMgmt,
1184 pWifiIfaceStat->rssiData,
1185 pWifiIfaceStat->rssiAck );
1186
1187
1188 {
1189 int i;
1190 for (i = 0 ; i < WIFI_AC_MAX; i ++)
1191 {
1192 hddLog(VOS_TRACE_LEVEL_INFO,
1193
1194 " %d) LL_STATS IFACE: "
1195 " ac: %u txMpdu: %u "
1196 " rxMpdu: %u txMcast: %u "
1197 " rxMcast: %u rxAmpdu: %u "
1198 " txAmpdu: %u mpduLost: %u "
1199 " retries: %u retriesShort: %u "
1200 " retriesLong: %u contentionTimeMin: %u "
1201 " contentionTimeMax: %u contentionTimeAvg: %u "
1202 " contentionNumSamples: %u",
1203 i,
1204 pWifiIfaceStat->AccessclassStats[i].ac,
1205 pWifiIfaceStat->AccessclassStats[i].txMpdu,
1206 pWifiIfaceStat->AccessclassStats[i].rxMpdu,
1207 pWifiIfaceStat->AccessclassStats[i].txMcast,
1208 pWifiIfaceStat->AccessclassStats[i].rxMcast,
1209 pWifiIfaceStat->AccessclassStats[i].rxAmpdu,
1210 pWifiIfaceStat->AccessclassStats[i].txAmpdu,
1211 pWifiIfaceStat->AccessclassStats[i].mpduLost,
1212 pWifiIfaceStat->AccessclassStats[i].retries,
1213 pWifiIfaceStat->
1214 AccessclassStats[i].retriesShort,
1215 pWifiIfaceStat->AccessclassStats[i].retriesLong,
1216 pWifiIfaceStat->
1217 AccessclassStats[i].contentionTimeMin,
1218 pWifiIfaceStat->
1219 AccessclassStats[i].contentionTimeMax,
1220 pWifiIfaceStat->
1221 AccessclassStats[i].contentionTimeAvg,
1222 pWifiIfaceStat->
1223 AccessclassStats[i].contentionNumSamples);
1224
1225 }
1226 }
1227
1228 if (FALSE == hdd_get_interface_info( pAdapter,
1229 &pWifiIfaceStat->info))
1230 {
1231 hddLog(VOS_TRACE_LEVEL_ERROR,
1232 FL("hdd_get_interface_info get fail") );
1233 kfree_skb(vendor_event);
1234 return;
1235 }
1236
1237 if (FALSE == put_wifi_iface_stats( pWifiIfaceStat,
1238 vendor_event))
1239 {
1240 hddLog(VOS_TRACE_LEVEL_ERROR,
1241 FL("put_wifi_iface_stats fail") );
1242 kfree_skb(vendor_event);
1243 return;
1244 }
1245 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
1246}
1247
1248/*
1249 * hdd_link_layer_process_radio_stats () - This function is called after
1250 * receiving Link Layer Radio statistics from FW.This function converts
1251 * the firmware data to the NL data and sends the same to the kernel/upper
1252 * layers.
1253 */
1254static v_VOID_t hdd_link_layer_process_radio_stats(hdd_adapter_t *pAdapter,
1255 v_VOID_t *pData)
1256{
1257 int status, i;
1258 tpSirWifiRadioStat pWifiRadioStat;
1259 tpSirWifiChannelStats pWifiChannelStats;
1260 struct sk_buff *vendor_event;
1261 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1262 struct nlattr *chList;
1263
1264 status = wlan_hdd_validate_context(pHddCtx);
1265 if (0 != status)
1266 {
1267 hddLog(VOS_TRACE_LEVEL_ERROR,
1268 FL("HDD context is not valid") );
1269 return;
1270 }
1271 pWifiRadioStat = (tpSirWifiRadioStat) pData;
1272
1273 hddLog(VOS_TRACE_LEVEL_INFO,
1274 "LL_STATS_RADIO"
1275 " radio is %d onTime is %u "
1276 " txTime is %u rxTime is %u "
1277 " onTimeScan is %u onTimeNbd is %u "
Dino Mycle6fb96c12014-06-10 11:52:40 +05301278 " onTimeEXTScan is %u onTimeRoamScan is %u "
Sunil Duttc69bccb2014-05-26 21:30:20 +05301279 " onTimePnoScan is %u onTimeHs20 is %u "
1280 " numChannels is %u",
1281 pWifiRadioStat->radio, pWifiRadioStat->onTime,
1282 pWifiRadioStat->txTime, pWifiRadioStat->rxTime,
1283 pWifiRadioStat->onTimeScan, pWifiRadioStat->onTimeNbd,
Dino Mycle6fb96c12014-06-10 11:52:40 +05301284 pWifiRadioStat->onTimeEXTScan,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301285 pWifiRadioStat->onTimeRoamScan,
1286 pWifiRadioStat->onTimePnoScan,
1287 pWifiRadioStat->onTimeHs20,
1288 pWifiRadioStat->numChannels);
1289 /*
1290 * Allocate a size of 4096 for the Radio stats comprising
1291 * sizeof (tSirWifiRadioStat) + numChannels * sizeof
1292 * (tSirWifiChannelStats).Each channel data is put with an
1293 * NL attribute.The size of 4096 is considered assuming that
1294 * number of channels shall not exceed beyond 60 with the
1295 * sizeof (tSirWifiChannelStats) being 24 bytes.
1296 */
1297
1298 vendor_event = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
1299 LL_STATS_EVENT_BUF_SIZE + NLMSG_HDRLEN ,
1300 QCA_NL80211_VENDOR_SUBCMD_LL_RADIO_STATS_INDEX,
1301 GFP_KERNEL);
1302
1303 if (!vendor_event)
1304 {
1305 hddLog(VOS_TRACE_LEVEL_ERROR,
1306 FL("cfg80211_vendor_event_alloc failed") );
1307 return;
1308 }
1309
1310 if (nla_put_u32(vendor_event,
1311 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ID,
1312 pWifiRadioStat->radio) ||
1313 nla_put_u32(vendor_event,
1314 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME,
1315 pWifiRadioStat->onTime) ||
1316 nla_put_u32(vendor_event,
1317 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_TX_TIME,
1318 pWifiRadioStat->txTime) ||
1319 nla_put_u32(vendor_event,
1320 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_RX_TIME,
1321 pWifiRadioStat->rxTime) ||
1322 nla_put_u32(vendor_event,
1323 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_SCAN,
1324 pWifiRadioStat->onTimeScan) ||
1325 nla_put_u32(vendor_event,
1326 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_NBD,
1327 pWifiRadioStat->onTimeNbd) ||
1328 nla_put_u32(vendor_event,
Dino Mycle6fb96c12014-06-10 11:52:40 +05301329 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_EXTSCAN,
1330 pWifiRadioStat->onTimeEXTScan)||
Sunil Duttc69bccb2014-05-26 21:30:20 +05301331 nla_put_u32(vendor_event,
1332 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_ROAM_SCAN,
1333 pWifiRadioStat->onTimeRoamScan) ||
1334 nla_put_u32(vendor_event,
1335 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_PNO_SCAN,
1336 pWifiRadioStat->onTimePnoScan) ||
1337 nla_put_u32(vendor_event,
1338 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_HS20,
1339 pWifiRadioStat->onTimeHs20) ||
1340 nla_put_u32(vendor_event,
1341 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_NUM_CHANNELS,
1342 pWifiRadioStat->numChannels))
1343 {
1344 hddLog(VOS_TRACE_LEVEL_ERROR,
1345 FL("QCA_WLAN_VENDOR_ATTR put fail"));
1346 kfree_skb(vendor_event);
1347 return ;
1348 }
1349
1350 chList = nla_nest_start(vendor_event,
1351 QCA_WLAN_VENDOR_ATTR_LL_STATS_CH_INFO);
1352 for (i = 0; i < pWifiRadioStat->numChannels; i++)
1353 {
1354 struct nlattr *chInfo;
1355
1356 pWifiChannelStats = (tpSirWifiChannelStats) ((uint8*)
1357 pWifiRadioStat->channels +
1358 (i * sizeof(tSirWifiChannelStats)));
1359
1360 hddLog(VOS_TRACE_LEVEL_INFO,
1361 " %d) Channel Info"
1362 " width is %u "
1363 " CenterFreq %u "
1364 " CenterFreq0 %u "
1365 " CenterFreq1 %u "
1366 " onTime %u "
1367 " ccaBusyTime %u",
1368 i,
1369 pWifiChannelStats->channel.width,
1370 pWifiChannelStats->channel.centerFreq,
1371 pWifiChannelStats->channel.centerFreq0,
1372 pWifiChannelStats->channel.centerFreq1,
1373 pWifiChannelStats->onTime,
1374 pWifiChannelStats->ccaBusyTime);
1375
1376
1377 chInfo = nla_nest_start(vendor_event, i);
1378
1379 if (nla_put_u32(vendor_event,
1380 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_WIDTH,
1381 pWifiChannelStats->channel.width) ||
1382 nla_put_u32(vendor_event,
1383 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ,
1384 pWifiChannelStats->channel.centerFreq) ||
1385 nla_put_u32(vendor_event,
1386 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ0,
1387 pWifiChannelStats->channel.centerFreq0) ||
1388 nla_put_u32(vendor_event,
1389 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ1,
1390 pWifiChannelStats->channel.centerFreq1) ||
1391 nla_put_u32(vendor_event,
1392 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_ON_TIME,
1393 pWifiChannelStats->onTime) ||
1394 nla_put_u32(vendor_event,
1395 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_CCA_BUSY_TIME,
1396 pWifiChannelStats->ccaBusyTime))
1397 {
1398 hddLog(VOS_TRACE_LEVEL_ERROR,
1399 FL("cfg80211_vendor_event_alloc failed") );
1400 kfree_skb(vendor_event);
1401 return ;
1402 }
1403 nla_nest_end(vendor_event, chInfo);
1404 }
1405 nla_nest_end(vendor_event, chList);
1406
1407 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
1408 return;
1409}
1410
1411/*
1412 * hdd_link_layer_stats_ind_callback () - This function is called after
1413 * receiving Link Layer indications from FW.This callback converts the firmware
1414 * data to the NL data and send the same to the kernel/upper layers.
1415 */
1416static void hdd_link_layer_stats_ind_callback ( void *pCtx,
1417 int indType,
Dino Mycled3d50022014-07-07 12:58:25 +05301418 void *pRsp, u8 *macAddr)
Sunil Duttc69bccb2014-05-26 21:30:20 +05301419{
Dino Mycled3d50022014-07-07 12:58:25 +05301420 hdd_context_t *pHddCtx = (hdd_context_t *)pCtx;
1421 hdd_adapter_t *pAdapter = NULL;
1422 tpSirLLStatsResults linkLayerStatsResults = (tpSirLLStatsResults)pRsp;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301423 int status;
1424
1425 status = wlan_hdd_validate_context(pHddCtx);
1426
1427 if (0 != status)
1428 {
1429 hddLog(VOS_TRACE_LEVEL_ERROR,
1430 FL("HDD context is not valid"));
1431 return;
1432 }
1433
Dino Mycled3d50022014-07-07 12:58:25 +05301434
1435
1436 pAdapter = hdd_get_adapter_by_macaddr(pHddCtx, macAddr);
1437 if (NULL == pAdapter)
1438 {
1439 hddLog(VOS_TRACE_LEVEL_ERROR,
1440 FL(" MAC address %pM does not exist with host"),
1441 macAddr);
1442 return;
1443 }
1444
Sunil Duttc69bccb2014-05-26 21:30:20 +05301445 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Dino Mycled3d50022014-07-07 12:58:25 +05301446 "%s: Interface: %s LLStats indType: %d", __func__,
1447 pAdapter->dev->name, indType);
1448
Sunil Duttc69bccb2014-05-26 21:30:20 +05301449 switch (indType)
1450 {
1451 case SIR_HAL_LL_STATS_RESULTS_RSP:
1452 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301453 hddLog(VOS_TRACE_LEVEL_INFO,
1454 FL("RESPONSE SIR_HAL_LL_STATS_RESULTS_RSP") );
1455 hddLog(VOS_TRACE_LEVEL_INFO,
1456 "LL_STATS RESULTS RESPONSE paramID = 0x%x",
1457 linkLayerStatsResults->paramId);
1458 hddLog(VOS_TRACE_LEVEL_INFO,
Dino Mycled3d50022014-07-07 12:58:25 +05301459 "LL_STATS RESULTS RESPONSE ifaceId = %u MAC: %pM",
1460 linkLayerStatsResults->ifaceId, macAddr);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301461 hddLog(VOS_TRACE_LEVEL_INFO,
1462 "LL_STATS RESULTS RESPONSE respId = %u",
1463 linkLayerStatsResults->respId);
1464 hddLog(VOS_TRACE_LEVEL_INFO,
1465 "LL_STATS RESULTS RESPONSE moreResultToFollow = %u",
1466 linkLayerStatsResults->moreResultToFollow);
1467 hddLog(VOS_TRACE_LEVEL_INFO,
1468 "LL_STATS RESULTS RESPONSE result = %p",
1469 linkLayerStatsResults->result);
1470 if ( linkLayerStatsResults->paramId & WMI_LINK_STATS_RADIO )
1471 {
1472 hdd_link_layer_process_radio_stats(pAdapter,
1473 (v_VOID_t *)linkLayerStatsResults->result);
1474 }
1475 else if ( linkLayerStatsResults->paramId & WMI_LINK_STATS_IFACE )
1476 {
1477 hdd_link_layer_process_iface_stats(pAdapter,
1478 (v_VOID_t *)linkLayerStatsResults->result);
1479 }
1480 else if ( linkLayerStatsResults->paramId &
1481 WMI_LINK_STATS_ALL_PEER )
1482 {
1483 hdd_link_layer_process_peer_stats(pAdapter,
1484 (v_VOID_t *)linkLayerStatsResults->result);
1485 } /* WMI_LINK_STATS_ALL_PEER */
1486 else
1487 {
1488 hddLog(VOS_TRACE_LEVEL_ERROR,
1489 FL("INVALID LL_STATS_NOTIFY RESPONSE ***********"));
1490 }
1491
1492 break;
1493 }
1494 default:
1495 hddLog(VOS_TRACE_LEVEL_ERROR, "invalid event type %d", indType);
1496 break;
1497 }
1498 return;
1499}
1500
1501const struct
1502nla_policy
1503qca_wlan_vendor_ll_set_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX +1] =
1504{
1505 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD] =
1506 { .type = NLA_U32 },
1507 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING] =
1508 { .type = NLA_U32 },
1509};
1510
1511static int wlan_hdd_cfg80211_ll_stats_set(struct wiphy *wiphy,
1512 struct wireless_dev *wdev,
1513 void *data,
1514 int data_len)
1515{
1516 int status;
1517 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05301518 tSirLLStatsSetReq linkLayerStatsSetReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301519 struct net_device *dev = wdev->netdev;
1520 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
1521 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
1522
1523 status = wlan_hdd_validate_context(pHddCtx);
1524 if (0 != status)
1525 {
1526 hddLog(VOS_TRACE_LEVEL_ERROR,
1527 FL("HDD context is not valid"));
1528 return -EINVAL;
1529 }
1530
1531 if (NULL == pAdapter)
1532 {
1533 hddLog(VOS_TRACE_LEVEL_ERROR,
1534 FL("HDD adapter is Null"));
1535 return -ENODEV;
1536 }
Dino Mycledf0a5d92014-07-04 09:41:55 +05301537 /* check the LLStats Capability */
1538 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
1539 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
1540 {
1541 hddLog(VOS_TRACE_LEVEL_ERROR,
1542 FL("Link Layer Statistics not supported by Firmware"));
1543 return -EINVAL;
1544 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301545
1546 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX,
1547 (struct nlattr *)data,
1548 data_len, qca_wlan_vendor_ll_set_policy))
1549 {
1550 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
1551 return -EINVAL;
1552 }
1553 if (!tb_vendor
1554 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD])
1555 {
1556 hddLog(VOS_TRACE_LEVEL_ERROR, FL("MPDU size Not present"));
1557 return -EINVAL;
1558 }
1559 if (!tb_vendor[
1560 QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING])
1561 {
1562 hddLog(VOS_TRACE_LEVEL_ERROR, FL(" Stats Gathering Not Present"));
1563 return -EINVAL;
1564 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301565 // Shall take the request Id if the Upper layers pass. 1 For now.
Dino Mycledf0a5d92014-07-04 09:41:55 +05301566 linkLayerStatsSetReq.reqId = 1;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301567
Dino Mycledf0a5d92014-07-04 09:41:55 +05301568 linkLayerStatsSetReq.mpduSizeThreshold =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301569 nla_get_u32(
1570 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD]);
1571
Dino Mycledf0a5d92014-07-04 09:41:55 +05301572 linkLayerStatsSetReq.aggressiveStatisticsGathering =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301573 nla_get_u32(
1574 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING]);
1575
Dino Mycled3d50022014-07-07 12:58:25 +05301576 vos_mem_copy(linkLayerStatsSetReq.macAddr,
1577 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05301578
1579
1580 hddLog(VOS_TRACE_LEVEL_INFO,
Dino Mycled3d50022014-07-07 12:58:25 +05301581 "LL_STATS_SET reqId = %d", linkLayerStatsSetReq.reqId);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301582 hddLog(VOS_TRACE_LEVEL_INFO,
Dino Mycled3d50022014-07-07 12:58:25 +05301583 "LL_STATS_SET MAC = %pM", linkLayerStatsSetReq.macAddr);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301584 hddLog(VOS_TRACE_LEVEL_INFO,
1585 "LL_STATS_SET mpduSizeThreshold = %d",
Dino Mycledf0a5d92014-07-04 09:41:55 +05301586 linkLayerStatsSetReq.mpduSizeThreshold);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301587 hddLog(VOS_TRACE_LEVEL_INFO,
1588 "LL_STATS_SET aggressive Statistics Gathering = %d",
Dino Mycledf0a5d92014-07-04 09:41:55 +05301589 linkLayerStatsSetReq.aggressiveStatisticsGathering);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301590
1591 if (eHAL_STATUS_SUCCESS != sme_SetLinkLayerStatsIndCB(
1592 pHddCtx->hHal,
Dino Mycled3d50022014-07-07 12:58:25 +05301593 hdd_link_layer_stats_ind_callback))
Sunil Duttc69bccb2014-05-26 21:30:20 +05301594 {
1595 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
1596 "sme_SetLinkLayerStatsIndCB Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301597 return -EINVAL;
1598
1599 }
1600 if (eHAL_STATUS_SUCCESS != sme_LLStatsSetReq( pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05301601 &linkLayerStatsSetReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05301602 {
1603 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
1604 "sme_LLStatsSetReq Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301605 return -EINVAL;
1606 }
1607
1608 pAdapter->isLinkLayerStatsSet = 1;
1609
1610 return 0;
1611}
1612
1613const struct
1614nla_policy
1615qca_wlan_vendor_ll_get_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX +1] =
1616{
1617 /* Unsigned 32bit value provided by the caller issuing the GET stats
1618 * command. When reporting
1619 * the stats results, the driver uses the same value to indicate
1620 * which GET request the results
1621 * correspond to.
1622 */
1623 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID] = { .type = NLA_U32 },
1624
1625 /* Unsigned 32bit value . bit mask to identify what statistics are
1626 requested for retrieval */
1627 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK] = { .type = NLA_U32 },
1628};
1629
1630static int wlan_hdd_cfg80211_ll_stats_get(struct wiphy *wiphy,
1631 struct wireless_dev *wdev,
1632 void *data,
1633 int data_len)
1634{
1635 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
1636 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05301637 tSirLLStatsGetReq linkLayerStatsGetReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301638 struct net_device *dev = wdev->netdev;
1639 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
1640 int status;
1641
1642 status = wlan_hdd_validate_context(pHddCtx);
1643 if (0 != status)
1644 {
1645 hddLog(VOS_TRACE_LEVEL_ERROR,
1646 FL("HDD context is not valid"));
1647 return -EINVAL ;
1648 }
1649
1650 if (NULL == pAdapter)
1651 {
1652 hddLog(VOS_TRACE_LEVEL_FATAL,
1653 "%s: HDD adapter is Null", __func__);
1654 return -ENODEV;
1655 }
Dino Mycledf0a5d92014-07-04 09:41:55 +05301656 /* check the LLStats Capability */
1657 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
1658 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
1659 {
1660 hddLog(VOS_TRACE_LEVEL_ERROR,
1661 FL("Link Layer Statistics not supported by Firmware"));
1662 return -EINVAL;
1663 }
1664
Sunil Duttc69bccb2014-05-26 21:30:20 +05301665
1666 if (!pAdapter->isLinkLayerStatsSet)
1667 {
1668 hddLog(VOS_TRACE_LEVEL_FATAL,
1669 "%s: isLinkLayerStatsSet : %d",
1670 __func__, pAdapter->isLinkLayerStatsSet);
1671 return -EINVAL;
1672 }
1673
1674 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX,
1675 (struct nlattr *)data,
1676 data_len, qca_wlan_vendor_ll_get_policy))
1677 {
1678 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
1679 return -EINVAL;
1680 }
1681
1682 if (!tb_vendor
1683 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID])
1684 {
1685 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Request Id Not present"));
1686 return -EINVAL;
1687 }
1688
1689 if (!tb_vendor
1690 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK])
1691 {
1692 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Req Mask Not present"));
1693 return -EINVAL;
1694 }
1695
Sunil Duttc69bccb2014-05-26 21:30:20 +05301696
Dino Mycledf0a5d92014-07-04 09:41:55 +05301697 linkLayerStatsGetReq.reqId =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301698 nla_get_u32( tb_vendor[
1699 QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID]);
Dino Mycledf0a5d92014-07-04 09:41:55 +05301700 linkLayerStatsGetReq.paramIdMask =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301701 nla_get_u32( tb_vendor[
1702 QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK]);
1703
Dino Mycled3d50022014-07-07 12:58:25 +05301704 vos_mem_copy(linkLayerStatsGetReq.macAddr,
1705 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05301706
1707 hddLog(VOS_TRACE_LEVEL_INFO,
Dino Mycledf0a5d92014-07-04 09:41:55 +05301708 "LL_STATS_GET reqId = %d", linkLayerStatsGetReq.reqId);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301709 hddLog(VOS_TRACE_LEVEL_INFO,
Dino Mycled3d50022014-07-07 12:58:25 +05301710 "LL_STATS_GET MAC = %pM", linkLayerStatsGetReq.macAddr);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301711 hddLog(VOS_TRACE_LEVEL_INFO,
1712 "LL_STATS_GET paramIdMask = %d",
Dino Mycledf0a5d92014-07-04 09:41:55 +05301713 linkLayerStatsGetReq.paramIdMask);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301714
1715 if (eHAL_STATUS_SUCCESS != sme_LLStatsGetReq( pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05301716 &linkLayerStatsGetReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05301717 {
1718 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
1719 "sme_LLStatsGetReq Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301720 return -EINVAL;
1721 }
1722 return 0;
1723}
1724
1725const struct
1726nla_policy
1727qca_wlan_vendor_ll_clr_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX +1] =
1728{
1729 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK] = {.type = NLA_U32 },
1730 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ] = {.type = NLA_U8 },
1731 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_RSP_MASK] = {.type = NLA_U32 },
1732 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_RSP] = {.type = NLA_U8 },
1733};
1734
1735static int wlan_hdd_cfg80211_ll_stats_clear(struct wiphy *wiphy,
1736 struct wireless_dev *wdev,
1737 void *data,
1738 int data_len)
1739{
1740 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
1741 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05301742 tSirLLStatsClearReq linkLayerStatsClearReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301743 struct net_device *dev = wdev->netdev;
1744 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
1745 u32 statsClearReqMask;
1746 u8 stopReq;
1747 int status;
1748
1749 status = wlan_hdd_validate_context(pHddCtx);
1750 if (0 != status)
1751 {
1752 hddLog(VOS_TRACE_LEVEL_ERROR,
1753 FL("HDD context is not valid"));
1754 return -EINVAL;
1755 }
1756
1757 if (NULL == pAdapter)
1758 {
1759 hddLog(VOS_TRACE_LEVEL_FATAL,
1760 "%s: HDD adapter is Null", __func__);
1761 return -ENODEV;
1762 }
Dino Mycledf0a5d92014-07-04 09:41:55 +05301763 /* check the LLStats Capability */
1764 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
1765 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
1766 {
1767 hddLog(VOS_TRACE_LEVEL_ERROR,
1768 FL("Enable LLStats Capability"));
1769 return -EINVAL;
1770 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301771
1772 if (!pAdapter->isLinkLayerStatsSet)
1773 {
1774 hddLog(VOS_TRACE_LEVEL_FATAL,
1775 "%s: isLinkLayerStatsSet : %d",
1776 __func__, pAdapter->isLinkLayerStatsSet);
1777 return -EINVAL;
1778 }
1779
1780 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX,
1781 (struct nlattr *)data,
1782 data_len, qca_wlan_vendor_ll_clr_policy))
1783 {
1784 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
1785 return -EINVAL;
1786 }
1787
1788 if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK] ||
1789
1790 !tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ])
1791 {
1792 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Error in LL_STATS CLR CONFIG PARA") );
1793 return -EINVAL;
1794
1795 }
1796
Sunil Duttc69bccb2014-05-26 21:30:20 +05301797
Dino Mycledf0a5d92014-07-04 09:41:55 +05301798 statsClearReqMask = linkLayerStatsClearReq.statsClearReqMask =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301799 nla_get_u32(
1800 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK]);
1801
Dino Mycledf0a5d92014-07-04 09:41:55 +05301802 stopReq = linkLayerStatsClearReq.stopReq =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301803 nla_get_u8(
1804 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ]);
1805
1806 // Shall take the request Id if the Upper layers pass. 1 For now.
Dino Mycledf0a5d92014-07-04 09:41:55 +05301807 linkLayerStatsClearReq.reqId = 1;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301808
Dino Mycled3d50022014-07-07 12:58:25 +05301809 vos_mem_copy(linkLayerStatsClearReq.macAddr,
1810 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05301811
1812 hddLog(VOS_TRACE_LEVEL_INFO,
Dino Mycledf0a5d92014-07-04 09:41:55 +05301813 "LL_STATS_CLEAR reqId = %d", linkLayerStatsClearReq.reqId);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301814 hddLog(VOS_TRACE_LEVEL_INFO,
Dino Mycled3d50022014-07-07 12:58:25 +05301815 "LL_STATS_CLEAR MAC = %pM", linkLayerStatsClearReq.macAddr);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301816 hddLog(VOS_TRACE_LEVEL_INFO,
1817 "LL_STATS_CLEAR statsClearReqMask = 0x%X",
Dino Mycledf0a5d92014-07-04 09:41:55 +05301818 linkLayerStatsClearReq.statsClearReqMask);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301819 hddLog(VOS_TRACE_LEVEL_INFO,
1820 "LL_STATS_CLEAR stopReq = %d",
Dino Mycledf0a5d92014-07-04 09:41:55 +05301821 linkLayerStatsClearReq.stopReq);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301822
1823 if (eHAL_STATUS_SUCCESS == sme_LLStatsClearReq(pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05301824 &linkLayerStatsClearReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05301825 {
1826 struct sk_buff *temp_skbuff;
1827 temp_skbuff = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
1828 2 * sizeof(u32) +
1829 NLMSG_HDRLEN);
1830
1831 if (temp_skbuff != NULL)
1832 {
1833
1834 if (nla_put_u32(temp_skbuff,
1835 QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_RSP_MASK,
1836 statsClearReqMask) ||
1837 nla_put_u32(temp_skbuff,
1838 QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_RSP,
1839 stopReq))
1840 {
1841 hddLog(VOS_TRACE_LEVEL_ERROR, FL("LL_STATS_CLR put fail"));
1842 kfree_skb(temp_skbuff);
1843 return -EINVAL;
1844 }
1845 /* If the ask is to stop the stats collection as part of clear
1846 * (stopReq = 1) , ensure that no further requests of get
1847 * go to the firmware by having isLinkLayerStatsSet set to 0.
1848 * However it the stopReq as part of the clear request is 0 ,
Dino Mycledf0a5d92014-07-04 09:41:55 +05301849 * the request to get the statistics are honoured as in this
Sunil Duttc69bccb2014-05-26 21:30:20 +05301850 * case the firmware is just asked to clear the statistics.
1851 */
Dino Mycledf0a5d92014-07-04 09:41:55 +05301852 if (linkLayerStatsClearReq.stopReq == 1)
Sunil Duttc69bccb2014-05-26 21:30:20 +05301853 pAdapter->isLinkLayerStatsSet = 0;
1854 return cfg80211_vendor_cmd_reply(temp_skbuff);
1855 }
1856 return -ENOMEM;
1857 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301858 return -EINVAL;
1859}
1860#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
1861
Dino Mycle6fb96c12014-06-10 11:52:40 +05301862#ifdef WLAN_FEATURE_EXTSCAN
1863static const struct nla_policy
1864wlan_hdd_extscan_config_policy
1865 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1] =
1866{
1867 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID] =
1868 { .type = NLA_U32 },
1869 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND] =
1870 { .type = NLA_U32 },
1871 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL] = { .type = NLA_U32 },
1872 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME] =
1873 { .type = NLA_U32 },
1874 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE] = { .type = NLA_U8 },
1875 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CLASS] = { .type = NLA_U8 },
1876
1877 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX] = { .type = NLA_U8 },
1878 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND] = { .type = NLA_U8 },
1879 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD] = { .type = NLA_U32 },
1880 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS] =
1881 { .type = NLA_U8 },
1882 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS] =
1883 { .type = NLA_U32 },
1884 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_BASE_PERIOD] =
1885 { .type = NLA_U32 },
1886 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_MAX_AP_PER_SCAN] =
1887 { .type = NLA_U32 },
1888 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD] =
1889 { .type = NLA_U8 },
1890 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS] =
1891 { .type = NLA_U8 },
1892 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH] =
1893 { .type = NLA_U8 },
1894
1895 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_MAX] =
1896 { .type = NLA_U32 },
1897 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID] =
1898 { .type = NLA_UNSPEC },
1899 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW] =
1900 { .type = NLA_S32 },
1901 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH] =
1902 { .type = NLA_S32 },
1903 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL] =
1904 { .type = NLA_U32 },
1905 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP] =
1906 { .type = NLA_U32 },
1907 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_RSSI_SAMPLE_SIZE] =
1908 { .type = NLA_U32 },
1909 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_LOST_AP_SAMPLE_SIZE]
1910 = { .type = NLA_U32 },
1911 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_MIN_BREACHING] =
1912 { .type = NLA_U32 },
1913 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_NUM_AP] = { .type =
1914 NLA_U32 },
1915};
1916
1917static void wlan_hdd_cfg80211_extscan_get_capabilities_ind(void *ctx, void *pMsg)
1918{
1919 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
1920 struct sk_buff *skb = NULL;
1921 tpSirEXTScanCapabilitiesEvent pData =
1922 (tpSirEXTScanCapabilitiesEvent) pMsg;
1923
1924 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
1925 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
1926 "or pData(%p) is null"), pData);
1927 return;
1928 }
1929
1930 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
1931 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
1932 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES_INDEX,
1933 GFP_KERNEL);
1934
1935 if (!skb) {
1936 hddLog(VOS_TRACE_LEVEL_ERROR,
1937 FL("cfg80211_vendor_event_alloc failed"));
1938 return;
1939 }
1940
1941 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
1942 hddLog(VOS_TRACE_LEVEL_INFO, "Scan cache size (%u)", pData->scanCacheSize);
1943 hddLog(VOS_TRACE_LEVEL_INFO, "Scan buckets (%u)", pData->scanBuckets);
1944 hddLog(VOS_TRACE_LEVEL_INFO, "Max AP per scan (%u)", pData->maxApPerScan);
1945 hddLog(VOS_TRACE_LEVEL_INFO, "maxRssiSampleSize (%u)",
1946 pData->maxRssiSampleSize);
1947 hddLog(VOS_TRACE_LEVEL_INFO, "maxScanReportingThreshold (%u)",
1948 pData->maxScanReportingThreshold);
1949 hddLog(VOS_TRACE_LEVEL_INFO, "maxHotlistAPs (%u)", pData->maxHotlistAPs);
1950 hddLog(VOS_TRACE_LEVEL_INFO, "maxSignificantWifiChangeAPs (%u)",
1951 pData->maxSignificantWifiChangeAPs);
1952 hddLog(VOS_TRACE_LEVEL_INFO, "maxBsidHistoryEntries (%u)",
1953 pData->maxBsidHistoryEntries);
1954
1955 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
1956 pData->requestId) ||
1957 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status) ||
1958 nla_put_u32(skb,
1959 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_CACHE_SIZE,
1960 pData->scanCacheSize) ||
1961 nla_put_u32(skb,
1962 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_BUCKETS,
1963 pData->scanBuckets) ||
1964 nla_put_u32(skb,
1965 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_AP_CACHE_PER_SCAN,
1966 pData->maxApPerScan) ||
1967 nla_put_u32(skb,
1968 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_RSSI_SAMPLE_SIZE,
1969 pData->maxRssiSampleSize) ||
1970 nla_put_u32(skb,
1971 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_REPORTING_THRESHOLD,
1972 pData->maxScanReportingThreshold) ||
1973 nla_put_u32(skb,
1974 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_HOTLIST_APS,
1975 pData->maxHotlistAPs) ||
1976 nla_put_u32(skb,
1977 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SIGNIFICANT_WIFI_CHANGE_APS,
1978 pData->maxSignificantWifiChangeAPs) ||
1979 nla_put_u32(skb,
1980 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_BSSID_HISTORY_ENTRIES,
1981 pData->maxBsidHistoryEntries)) {
1982 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
1983 goto nla_put_failure;
1984 }
1985
1986 cfg80211_vendor_event(skb, GFP_KERNEL);
1987 return;
1988
1989nla_put_failure:
1990 kfree_skb(skb);
1991 return;
1992}
1993
1994
1995static void wlan_hdd_cfg80211_extscan_start_rsp(void *ctx, void *pMsg)
1996{
1997 tpSirEXTScanStartRspParams pData = (tpSirEXTScanStartRspParams) pMsg;
1998 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
1999 struct sk_buff *skb = NULL;
2000 tpAniSirGlobal pMac = PMAC_STRUCT( pHddCtx->hHal );
2001
2002
2003 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2004 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2005 "or pData(%p) is null"), pData);
2006 return;
2007 }
2008
2009 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2010 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2011 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START_INDEX,
2012 GFP_KERNEL);
2013
2014 if (!skb) {
2015 hddLog(VOS_TRACE_LEVEL_ERROR,
2016 FL("cfg80211_vendor_event_alloc failed"));
2017 return;
2018 }
2019 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2020 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2021 hddLog(VOS_TRACE_LEVEL_INFO, "Status (%u)", pData->status);
2022
2023 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2024 pData->requestId) ||
2025 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status)) {
2026 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2027 goto nla_put_failure;
2028 }
2029
2030 /*
2031 * Store the Request ID for comparing with the requestID obtained
2032 * in other requests.HDD shall return a failure is the extscan_stop
2033 * request is issued with a different requestId as that of the
2034 * extscan_start request. Also, This requestId shall be used while
2035 * indicating the full scan results to the upper layers.
2036 * The requestId is stored with the assumption that the firmware
2037 * shall return the ext scan start request's requestId in ext scan
2038 * start response.
2039 */
2040 if (pData->status == 0)
2041 pMac->sme.extScanStartReqId = pData->requestId;
2042
2043
2044 cfg80211_vendor_event(skb, GFP_KERNEL);
2045 return;
2046
2047nla_put_failure:
2048 kfree_skb(skb);
2049 return;
2050}
2051
2052
2053static void wlan_hdd_cfg80211_extscan_stop_rsp(void *ctx, void *pMsg)
2054{
2055 tpSirEXTScanStopRspParams pData = (tpSirEXTScanStopRspParams) pMsg;
2056 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2057 struct sk_buff *skb = NULL;
2058
2059 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2060 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2061 "or pData(%p) is null"), pData);
2062 return;
2063 }
2064
2065 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2066 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2067 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP_INDEX,
2068 GFP_KERNEL);
2069
2070 if (!skb) {
2071 hddLog(VOS_TRACE_LEVEL_ERROR,
2072 FL("cfg80211_vendor_event_alloc failed"));
2073 return;
2074 }
2075 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2076 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2077
2078 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2079 pData->requestId) ||
2080 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status)) {
2081 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2082 goto nla_put_failure;
2083 }
2084
2085 cfg80211_vendor_event(skb, GFP_KERNEL);
2086 return;
2087
2088nla_put_failure:
2089 kfree_skb(skb);
2090 return;
2091}
2092
2093
2094static void wlan_hdd_cfg80211_extscan_set_bss_hotlist_rsp(void *ctx,
2095 void *pMsg)
2096{
2097 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2098 struct sk_buff *skb = NULL;
2099 tpSirEXTScanSetBssidHotListRspParams pData =
2100 (tpSirEXTScanSetBssidHotListRspParams) pMsg;
2101
2102 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2103 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2104 "or pData(%p) is null"), pData);
2105 return;
2106 }
2107 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2108 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2109 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST_INDEX,
2110 GFP_KERNEL);
2111
2112 if (!skb) {
2113 hddLog(VOS_TRACE_LEVEL_ERROR,
2114 FL("cfg80211_vendor_event_alloc failed"));
2115 return;
2116 }
2117 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2118 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2119 hddLog(VOS_TRACE_LEVEL_INFO, "Status (%u)", pData->status);
2120
2121 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2122 pData->requestId) ||
2123 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status)) {
2124 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2125 goto nla_put_failure;
2126 }
2127
2128 cfg80211_vendor_event(skb, GFP_KERNEL);
2129 return;
2130
2131nla_put_failure:
2132 kfree_skb(skb);
2133 return;
2134}
2135
2136static void wlan_hdd_cfg80211_extscan_reset_bss_hotlist_rsp(void *ctx,
2137 void *pMsg)
2138{
2139 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2140 struct sk_buff *skb = NULL;
2141 tpSirEXTScanResetBssidHotlistRspParams pData =
2142 (tpSirEXTScanResetBssidHotlistRspParams) pMsg;
2143
2144 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2145 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2146 "or pData(%p) is null"), pData);
2147 return;
2148 }
2149
2150 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2151 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2152 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST_INDEX,
2153 GFP_KERNEL);
2154
2155 if (!skb) {
2156 hddLog(VOS_TRACE_LEVEL_ERROR,
2157 FL("cfg80211_vendor_event_alloc failed"));
2158 return;
2159 }
2160 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2161 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2162
2163 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2164 pData->requestId) ||
2165 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status)) {
2166 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2167 goto nla_put_failure;
2168 }
2169
2170 cfg80211_vendor_event(skb, GFP_KERNEL);
2171 return;
2172
2173nla_put_failure:
2174 kfree_skb(skb);
2175 return;
2176}
2177
2178
2179static void wlan_hdd_cfg80211_extscan_set_signf_wifi_change_rsp(void *ctx,
2180 void *pMsg)
2181{
2182 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2183 struct sk_buff *skb = NULL;
2184 tpSirEXTScanSetSignificantChangeRspParams pData =
2185 (tpSirEXTScanSetSignificantChangeRspParams) pMsg;
2186
2187 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2188 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2189 "or pData(%p) is null"), pData);
2190 return;
2191 }
2192
2193 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2194 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2195 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_SIGNIFICANT_CHANGE_INDEX,
2196 GFP_KERNEL);
2197
2198 if (!skb) {
2199 hddLog(VOS_TRACE_LEVEL_ERROR,
2200 FL("cfg80211_vendor_event_alloc failed"));
2201 return;
2202 }
2203 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2204 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2205 hddLog(VOS_TRACE_LEVEL_INFO, "Status (%u)", pData->status);
2206
2207 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2208 pData->requestId) ||
2209 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status)) {
2210 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2211 goto nla_put_failure;
2212 }
2213
2214 cfg80211_vendor_event(skb, GFP_KERNEL);
2215 return;
2216
2217nla_put_failure:
2218 kfree_skb(skb);
2219 return;
2220}
2221
2222
2223static void wlan_hdd_cfg80211_extscan_reset_signf_wifi_change_rsp(void *ctx,
2224 void *pMsg)
2225{
2226 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2227 struct sk_buff *skb = NULL;
2228 tpSirEXTScanResetSignificantChangeRspParams pData =
2229 (tpSirEXTScanResetSignificantChangeRspParams) pMsg;
2230
2231 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2232 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2233 "or pData(%p) is null"), pData);
2234 return;
2235 }
2236
2237 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2238 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2239 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_SIGNIFICANT_CHANGE_INDEX,
2240 GFP_KERNEL);
2241
2242 if (!skb) {
2243 hddLog(VOS_TRACE_LEVEL_ERROR,
2244 FL("cfg80211_vendor_event_alloc failed"));
2245 return;
2246 }
2247 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2248 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2249 hddLog(VOS_TRACE_LEVEL_INFO, "Status (%u)", pData->status);
2250
2251 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2252 pData->requestId) ||
2253 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status)) {
2254 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2255 goto nla_put_failure;
2256 }
2257
2258 cfg80211_vendor_event(skb, GFP_KERNEL);
2259 return;
2260
2261nla_put_failure:
2262 kfree_skb(skb);
2263 return;
2264}
2265
2266static void wlan_hdd_cfg80211_extscan_cached_results_ind(void *ctx,
2267 void *pMsg)
2268{
2269 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2270 struct sk_buff *skb = NULL;
2271 tANI_U32 i = 0, j, resultsPerEvent;
2272 tANI_S32 totalResults;
2273 tpSirWifiScanResultEvent pData = (tpSirWifiScanResultEvent) pMsg;
2274 tpSirWifiScanResult pSirWifiScanResult;
2275
2276 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2277 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2278 "or pData(%p) is null"), pData);
2279 return;
2280 }
2281 totalResults = pData->numOfAps;
2282 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2283 hddLog(VOS_TRACE_LEVEL_INFO, "Num results (%u)", pData->numOfAps);
2284 hddLog(VOS_TRACE_LEVEL_INFO, "More Data (%u)", pData->moreData);
2285
2286 do{
2287 resultsPerEvent = ((totalResults >= EXTSCAN_MAX_CACHED_RESULTS_PER_IND) ?
2288 EXTSCAN_MAX_CACHED_RESULTS_PER_IND : totalResults);
2289 totalResults -= EXTSCAN_MAX_CACHED_RESULTS_PER_IND;
2290
2291 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2292 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2293 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS_INDEX,
2294 GFP_KERNEL);
2295
2296 if (!skb) {
2297 hddLog(VOS_TRACE_LEVEL_ERROR,
2298 FL("cfg80211_vendor_event_alloc failed"));
2299 return;
2300 }
2301
2302 hddLog(VOS_TRACE_LEVEL_INFO, "resultsPerEvent (%u)", resultsPerEvent);
2303
2304 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2305 pData->requestId) ||
2306 nla_put_u32(skb,
2307 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
2308 resultsPerEvent)) {
2309 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2310 goto fail;
2311 }
2312 if (nla_put_u8(skb,
2313 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
2314 pData->moreData ? 1 : (totalResults > 0 ? 1 : 0 )))
2315 {
2316 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2317 goto fail;
2318 }
2319
2320 if (resultsPerEvent) {
2321 struct nlattr *aps;
2322
2323 aps = nla_nest_start(skb,
2324 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
2325 if (!aps)
2326 {
2327 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2328 goto fail;
2329 }
2330
2331 for (j = 0; j < resultsPerEvent; j++, i++) {
2332 struct nlattr *ap;
2333 pSirWifiScanResult = (tpSirWifiScanResult) ((tANI_U8 *)
2334 pData->ap + ( i* sizeof(tSirWifiScanResult)));
2335
2336 hddLog(VOS_TRACE_LEVEL_INFO, "[index=%u] Timestamp(%llu) "
2337 "Ssid (%s)"
2338 "Bssid: %pM "
2339 "Channel (%u)"
2340 "Rssi (%d)"
2341 "RTT (%u)"
2342 "RTT_SD (%u)",
2343 i,
2344 pSirWifiScanResult->ts,
2345 pSirWifiScanResult->ssid,
2346 pSirWifiScanResult->bssid,
2347 pSirWifiScanResult->channel,
2348 pSirWifiScanResult->rssi,
2349 pSirWifiScanResult->rtt,
2350 pSirWifiScanResult->rtt_sd);
2351
2352 ap = nla_nest_start(skb, j + 1);
2353 if (!ap)
2354 {
2355 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2356 goto fail;
2357 }
2358
2359 if (nla_put_u64(skb,
2360 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
2361 pSirWifiScanResult->ts) )
2362 {
2363 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2364 goto fail;
2365 }
2366 if (nla_put(skb,
2367 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
2368 sizeof(pSirWifiScanResult->ssid),
2369 pSirWifiScanResult->ssid) )
2370 {
2371 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2372 goto fail;
2373 }
2374 if (nla_put(skb,
2375 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
2376 sizeof(pSirWifiScanResult->bssid),
2377 pSirWifiScanResult->bssid) )
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_CHANNEL,
2384 pSirWifiScanResult->channel) )
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_RSSI,
2391 pSirWifiScanResult->rssi) )
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,
2398 pSirWifiScanResult->rtt) )
2399 {
2400 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2401 goto fail;
2402 }
2403 if (nla_put_u32(skb,
2404 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
2405 pSirWifiScanResult->rtt_sd))
2406 {
2407 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2408 goto fail;
2409 }
2410
2411 nla_nest_end(skb, ap);
2412 }
2413 nla_nest_end(skb, aps);
2414
2415 }
2416 cfg80211_vendor_event(skb, GFP_KERNEL);
2417 } while (totalResults > 0);
2418
2419 return;
2420fail:
2421 kfree_skb(skb);
2422 return;
2423}
2424
2425static void wlan_hdd_cfg80211_extscan_hotlist_match_ind(void *ctx,
2426 void *pMsg)
2427{
2428 tpSirWifiScanResultEvent pData = (tpSirWifiScanResultEvent) pMsg;
2429 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2430 struct sk_buff *skb = NULL;
2431 tANI_U32 i;
2432
2433 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2434 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2435 "or pData(%p) is null"), pData);
2436 return;
2437 }
2438
2439 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2440 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2441 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_FOUND_INDEX,
2442 GFP_KERNEL);
2443
2444 if (!skb) {
2445 hddLog(VOS_TRACE_LEVEL_ERROR,
2446 FL("cfg80211_vendor_event_alloc failed"));
2447 return;
2448 }
2449 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2450 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2451 hddLog(VOS_TRACE_LEVEL_INFO, "Num results (%u)", pData->numOfAps);
2452 hddLog(VOS_TRACE_LEVEL_INFO, "More Data (%u)", pData->moreData);
2453
2454 for (i = 0; i < pData->numOfAps; i++) {
2455 hddLog(VOS_TRACE_LEVEL_INFO, "[index=%u] Timestamp(0x%lld) "
2456 "Ssid (%s) "
2457 "Bssid (" MAC_ADDRESS_STR ") "
2458 "Channel (%u) "
2459 "Rssi (%d) "
2460 "RTT (%u) "
2461 "RTT_SD (%u) ",
2462 i,
2463 pData->ap[i].ts,
2464 pData->ap[i].ssid,
2465 MAC_ADDR_ARRAY(pData->ap[i].bssid),
2466 pData->ap[i].channel,
2467 pData->ap[i].rssi,
2468 pData->ap[i].rtt,
2469 pData->ap[i].rtt_sd);
2470 }
2471
2472 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2473 pData->requestId) ||
2474 nla_put_u32(skb,
2475 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
2476 pData->numOfAps)) {
2477 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2478 goto fail;
2479 }
2480 if (pData->numOfAps) {
2481 struct nlattr *aps;
2482
2483 aps = nla_nest_start(skb,
2484 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
2485 if (!aps)
2486 goto fail;
2487
2488 for (i = 0; i < pData->numOfAps; i++) {
2489 struct nlattr *ap;
2490
2491 ap = nla_nest_start(skb, i + 1);
2492 if (!ap)
2493 goto fail;
2494
2495 if (nla_put_u64(skb,
2496 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
2497 pData->ap[i].ts) ||
2498 nla_put(skb,
2499 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
2500 sizeof(pData->ap[i].ssid),
2501 pData->ap[i].ssid) ||
2502 nla_put(skb,
2503 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
2504 sizeof(pData->ap[i].bssid),
2505 pData->ap[i].bssid) ||
2506 nla_put_u32(skb,
2507 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
2508 pData->ap[i].channel) ||
2509 nla_put_s32(skb,
2510 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
2511 pData->ap[i].rssi) ||
2512 nla_put_u32(skb,
2513 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
2514 pData->ap[i].rtt) ||
2515 nla_put_u32(skb,
2516 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
2517 pData->ap[i].rtt_sd))
2518 goto fail;
2519
2520 nla_nest_end(skb, ap);
2521 }
2522 nla_nest_end(skb, aps);
2523
2524 if (nla_put_u8(skb,
2525 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
2526 pData->moreData))
2527 goto fail;
2528 }
2529
2530 cfg80211_vendor_event(skb, GFP_KERNEL);
2531 return;
2532
2533fail:
2534 kfree_skb(skb);
2535 return;
2536
2537}
2538static void wlan_hdd_cfg80211_extscan_signif_wifi_change_results_ind(void *ctx,
2539 void *pMsg)
2540{
2541 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2542 struct sk_buff *skb = NULL;
2543 tANI_U32 i, j;
2544 tpSirWifiSignificantChangeEvent pData =
2545 (tpSirWifiSignificantChangeEvent) pMsg;
2546
2547 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2548 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2549 "or pData(%p) is null"), pData);
2550 return;
2551 }
2552 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2553 EXTSCAN_EVENT_BUF_SIZE,
2554 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SIGNIFICANT_CHANGE_INDEX,
2555 GFP_KERNEL);
2556
2557 if (!skb) {
2558 hddLog(VOS_TRACE_LEVEL_ERROR,
2559 FL("cfg80211_vendor_event_alloc failed"));
2560 return;
2561 }
2562 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2563 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2564 hddLog(VOS_TRACE_LEVEL_INFO, "total List Size %u ", pData->numSigRssiBss);
2565 hddLog(VOS_TRACE_LEVEL_INFO, " CUrrent List size (%u)",
2566 pData->numSigRssiBss);
2567 hddLog(VOS_TRACE_LEVEL_INFO, "moreData (%u)", pData->moreData);
2568
2569 for (i = 0; i < pData->numSigRssiBss; i++) {
2570 hddLog(VOS_TRACE_LEVEL_INFO , "Rssi List [%d] BSSID: (%pM) Channel %u "
2571 " num RSSI %u ",
2572 i, pData->sigRssiResult[i].bssid,
2573 pData->sigRssiResult[i].channel,
2574 pData->sigRssiResult[i].numRssi);
2575
2576 for (j = 0; j < pData->sigRssiResult[i].numRssi; j++){
2577
2578 hddLog(VOS_TRACE_LEVEL_INFO,
2579 " [%d]",
2580 pData->sigRssiResult[i].rssi[0]);
2581
2582 }
2583 }
2584
2585
2586 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2587 pData->requestId) ||
2588 nla_put_u32(skb,
2589 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
2590 pData->numSigRssiBss)) {
2591 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2592 goto fail;
2593 }
2594
2595 if (pData->numSigRssiBss) {
2596 struct nlattr *aps;
2597 aps = nla_nest_start(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
2598 if (!aps)
2599 goto fail;
2600 for (i = 0; i < pData->numSigRssiBss; i++) {
2601 struct nlattr *ap;
2602
2603 ap = nla_nest_start(skb, i);
2604 if (!ap)
2605 goto fail;
2606 if (nla_put(skb,
2607 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SIGNIFICANT_CHANGE_RESULT_BSSID,
2608 sizeof(tSirMacAddr), pData->sigRssiResult[i].bssid) ||
2609 nla_put_u32(skb,
2610 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SIGNIFICANT_CHANGE_RESULT_CHANNEL,
2611 pData->sigRssiResult[i].channel) ||
2612 nla_put_u32(skb,
2613 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SIGNIFICANT_CHANGE_RESULT_NUM_RSSI,
2614 pData->sigRssiResult[i].numRssi) ||
2615 nla_put(skb,
2616 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SIGNIFICANT_CHANGE_RESULT_RSSI_LIST,
2617 sizeof(s32) * pData->sigRssiResult[i].numRssi,
2618 pData->sigRssiResult[i].rssi))
2619 goto fail;
2620 nla_nest_end(skb, ap);
2621 }
2622 nla_nest_end(skb, aps);
2623 if (nla_put_u8(skb,
2624 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
2625 pData->moreData))
2626 goto fail;
2627 }
2628 cfg80211_vendor_event(skb, GFP_KERNEL);
2629 return;
2630fail:
2631 kfree_skb(skb);
2632 return;
2633}
2634
2635static void wlan_hdd_cfg80211_extscan_full_scan_result_event(void *ctx,
2636 void *pMsg)
2637{
2638 struct sk_buff *skb;
2639 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2640 tpSirWifiFullScanResultEvent pData =
2641 (tpSirWifiFullScanResultEvent) (pMsg);
2642
2643 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2644 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2645 "or pData(%p) is null"), pData);
2646 return;
2647 }
2648
2649 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2650 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2651 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_FULL_SCAN_RESULT_INDEX,
2652 GFP_KERNEL);
2653
2654 if (!skb) {
2655 hddLog(VOS_TRACE_LEVEL_ERROR,
2656 FL("cfg80211_vendor_event_alloc failed"));
2657 return;
2658 }
2659
2660 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2661 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%u)"), pData->requestId);
2662 hddLog(VOS_TRACE_LEVEL_INFO, FL("More Data (%u)"), pData->moreData);
2663 hddLog(VOS_TRACE_LEVEL_INFO, FL("AP Info: Timestamp(0x%llX) "
2664 "Ssid (%s)"
2665 "Bssid (" MAC_ADDRESS_STR ")"
2666 "Channel (%u)"
2667 "Rssi (%d)"
2668 "RTT (%u)"
2669 "RTT_SD (%u)"),
2670 pData->ap.ts,
2671 pData->ap.ssid,
2672 MAC_ADDR_ARRAY(pData->ap.bssid),
2673 pData->ap.channel,
2674 pData->ap.rssi,
2675 pData->ap.rtt,
2676 pData->ap.rtt_sd);
2677 hddLog(VOS_TRACE_LEVEL_INFO, "IE Length (%u)", pData->ieLength);
2678 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2679 pData->requestId) ||
2680 nla_put_u64(skb,
2681 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
2682 pData->ap.ts) ||
2683 nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
2684 sizeof(pData->ap.ssid),
2685 pData->ap.ssid) ||
2686 nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
2687 WNI_CFG_BSSID_LEN,
2688 pData->ap.bssid) ||
2689 nla_put_u32(skb,
2690 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
2691 pData->ap.channel) ||
2692 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
2693 pData->ap.rssi) ||
2694 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
2695 pData->ap.rtt) ||
2696 nla_put_u32(skb,
2697 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
2698 pData->ap.rtt_sd) ||
2699 nla_put_u16(skb,
2700 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BEACON_PERIOD,
2701 pData->ap.beaconPeriod) ||
2702 nla_put_u16(skb,
2703 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CAPABILITY,
2704 pData->ap.capability) ||
2705 nla_put_u32(skb,
2706 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_LENGTH,
2707 pData->ieLength))
2708 {
2709 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2710 goto nla_put_failure;
2711 }
2712 if (nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_DATA,
2713 pData->ieLength,
2714 pData->ie))
2715 {
2716 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2717 goto nla_put_failure;
2718 }
2719
2720 cfg80211_vendor_event(skb, GFP_KERNEL);
2721 return;
2722
2723nla_put_failure:
2724 kfree_skb(skb);
2725 return;
2726}
2727
2728static void wlan_hdd_cfg80211_extscan_scan_res_available_event(void *ctx,
2729 void *pMsg)
2730{
2731 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2732 struct sk_buff *skb = NULL;
2733 tpSirEXTScanResultsAvailableIndParams pData =
2734 (tpSirEXTScanResultsAvailableIndParams) pMsg;
2735
2736 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2737 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2738 "or pData(%p) is null"), pData);
2739 return;
2740 }
2741
2742 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2743 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2744 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_RESULTS_AVAILABLE_INDEX,
2745 GFP_KERNEL);
2746
2747 if (!skb) {
2748 hddLog(VOS_TRACE_LEVEL_ERROR,
2749 FL("cfg80211_vendor_event_alloc failed"));
2750 return;
2751 }
2752
2753 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2754 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2755 hddLog(VOS_TRACE_LEVEL_INFO, "Num results (%u)",
2756 pData->numResultsAvailable);
2757 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2758 pData->requestId) ||
2759 nla_put_u32(skb,
2760 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
2761 pData->numResultsAvailable)) {
2762 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2763 goto nla_put_failure;
2764 }
2765
2766 cfg80211_vendor_event(skb, GFP_KERNEL);
2767 return;
2768
2769nla_put_failure:
2770 kfree_skb(skb);
2771 return;
2772}
2773
2774static void wlan_hdd_cfg80211_extscan_scan_progress_event(void *ctx, void *pMsg)
2775{
2776 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2777 struct sk_buff *skb = NULL;
2778 tpSirEXTScanProgressIndParams pData =
2779 (tpSirEXTScanProgressIndParams) pMsg;
2780
2781 if (wlan_hdd_validate_context(pHddCtx) || !pData) {
2782 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid "
2783 "or pData(%p) is null"), pData);
2784 return;
2785 }
2786
2787 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
2788 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2789 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_EVENT_INDEX,
2790 GFP_KERNEL);
2791
2792 if (!skb) {
2793 hddLog(VOS_TRACE_LEVEL_ERROR,
2794 FL("cfg80211_vendor_event_alloc failed"));
2795 return;
2796 }
2797 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2798 hddLog(VOS_TRACE_LEVEL_INFO, "Scan event type (%u)",
2799 pData->extScanEventType);
2800 hddLog(VOS_TRACE_LEVEL_INFO, "Scan event status (%u)",
2801 pData->status);
2802
2803 if (nla_put_u8(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_EVENT_TYPE,
2804 pData->extScanEventType) ||
2805 nla_put_u32(skb,
Dasari Srinivas5a288652014-06-30 17:13:22 +05302806 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2807 pData->requestId) ||
2808 nla_put_u32(skb,
Dino Mycle6fb96c12014-06-10 11:52:40 +05302809 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_EVENT_STATUS,
2810 pData->status)) {
2811 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2812 goto nla_put_failure;
2813 }
2814
2815 cfg80211_vendor_event(skb, GFP_KERNEL);
2816 return;
2817
2818nla_put_failure:
2819 kfree_skb(skb);
2820 return;
2821}
2822
2823void wlan_hdd_cfg80211_extscan_callback(void *ctx, const tANI_U16 evType,
2824 void *pMsg)
2825{
2826 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2827
2828 if (wlan_hdd_validate_context(pHddCtx)) {
2829 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid"));
2830 return;
2831 }
2832
2833 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rcvd Event (%d)"), evType);
2834
2835
2836 switch(evType) {
2837 case SIR_HAL_EXTSCAN_START_RSP:
2838 wlan_hdd_cfg80211_extscan_start_rsp(ctx, pMsg);
2839 break;
2840
2841 case SIR_HAL_EXTSCAN_STOP_RSP:
2842 wlan_hdd_cfg80211_extscan_stop_rsp(ctx, pMsg);
2843 break;
2844 case SIR_HAL_EXTSCAN_GET_CACHED_RESULTS_RSP:
2845 /* There is no need to send this response to upper layer
2846 Just log the message */
2847 hddLog(VOS_TRACE_LEVEL_INFO,
2848 FL("Rcvd SIR_HAL_EXTSCAN_CACHED_RESULTS_RSP"));
2849 break;
2850 case SIR_HAL_EXTSCAN_SET_BSS_HOTLIST_RSP:
2851 wlan_hdd_cfg80211_extscan_set_bss_hotlist_rsp(ctx, pMsg);
2852 break;
2853
2854 case SIR_HAL_EXTSCAN_RESET_BSS_HOTLIST_RSP:
2855 wlan_hdd_cfg80211_extscan_reset_bss_hotlist_rsp(ctx, pMsg);
2856 break;
2857
2858 case SIR_HAL_EXTSCAN_SET_SIGNF_RSSI_CHANGE_RSP:
2859 wlan_hdd_cfg80211_extscan_set_signf_wifi_change_rsp(ctx, pMsg);
2860 break;
2861
2862 case SIR_HAL_EXTSCAN_RESET_SIGNF_RSSI_CHANGE_RSP:
2863 wlan_hdd_cfg80211_extscan_reset_signf_wifi_change_rsp(ctx, pMsg);
2864 break;
2865 case SIR_HAL_EXTSCAN_GET_CAPABILITIES_RSP:
2866 wlan_hdd_cfg80211_extscan_get_capabilities_ind(ctx, pMsg);
2867 break;
2868 case SIR_HAL_EXTSCAN_PROGRESS_IND:
2869 wlan_hdd_cfg80211_extscan_scan_progress_event(ctx, pMsg);
2870 break;
2871 case SIR_HAL_EXTSCAN_SCAN_AVAILABLE_IND:
2872 wlan_hdd_cfg80211_extscan_scan_res_available_event(ctx, pMsg);
2873 break;
2874 case SIR_HAL_EXTSCAN_SCAN_RESULT_IND:
2875 wlan_hdd_cfg80211_extscan_cached_results_ind(ctx, pMsg);
2876 break;
2877 case SIR_HAL_EXTSCAN_HOTLIST_MATCH_IND:
2878 wlan_hdd_cfg80211_extscan_hotlist_match_ind(ctx, pMsg);
2879 break;
2880 case SIR_HAL_EXTSCAN_SIGNF_WIFI_CHANGE_IND:
2881 wlan_hdd_cfg80211_extscan_signif_wifi_change_results_ind(ctx, pMsg);
2882 break;
2883 case SIR_HAL_EXTSCAN_FULL_SCAN_RESULT_IND:
2884 wlan_hdd_cfg80211_extscan_full_scan_result_event(ctx, pMsg);
2885 break;
2886 default:
2887 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid event type %d "), evType);
2888 break;
2889 }
2890}
2891
2892static int wlan_hdd_cfg80211_extscan_get_capabilities(struct wiphy *wiphy,
2893 struct wireless_dev *wdev,
2894 void *data, int dataLen)
2895{
Dino Myclee8843b32014-07-04 14:21:45 +05302896 tSirGetEXTScanCapabilitiesReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302897 struct net_device *dev = wdev->netdev;
2898 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2899 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
2900 struct nlattr
2901 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
2902 eHalStatus status;
2903
2904 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering"));
2905 status = wlan_hdd_validate_context(pHddCtx);
2906 if (0 != status)
2907 {
2908 hddLog(VOS_TRACE_LEVEL_ERROR,
2909 FL("HDD context is not valid"));
2910 return -EINVAL;
2911 }
Dino Myclee8843b32014-07-04 14:21:45 +05302912 /* check the EXTScan Capability */
2913 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
2914 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
2915 {
2916 hddLog(VOS_TRACE_LEVEL_ERROR,
2917 FL("EXTScan not enabled/supported by Firmware"));
2918 return -EINVAL;
2919 }
2920
Dino Mycle6fb96c12014-06-10 11:52:40 +05302921 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
2922 data, dataLen,
2923 wlan_hdd_extscan_config_policy)) {
2924 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
2925 return -EINVAL;
2926 }
2927
2928 /* Parse and fetch request Id */
2929 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
2930 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
2931 return -EINVAL;
2932 }
2933
Dino Mycle6fb96c12014-06-10 11:52:40 +05302934
Dino Myclee8843b32014-07-04 14:21:45 +05302935 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05302936 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05302937 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302938
Dino Myclee8843b32014-07-04 14:21:45 +05302939 reqMsg.sessionId = pAdapter->sessionId;
2940 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302941
Dino Myclee8843b32014-07-04 14:21:45 +05302942 status = sme_EXTScanGetCapabilities(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302943 if (!HAL_STATUS_SUCCESS(status)) {
2944 hddLog(VOS_TRACE_LEVEL_ERROR,
2945 FL("sme_EXTScanGetCapabilities failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302946 return -EINVAL;
2947 }
2948
2949 return 0;
2950}
2951
2952
2953static int wlan_hdd_cfg80211_extscan_get_cached_results(struct wiphy *wiphy,
2954 struct wireless_dev *wdev,
2955 void *data, int dataLen)
2956{
Dino Myclee8843b32014-07-04 14:21:45 +05302957 tSirEXTScanGetCachedResultsReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302958 struct net_device *dev = wdev->netdev;
2959 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2960 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
2961 struct nlattr
2962 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
2963 eHalStatus status;
2964
2965 status = wlan_hdd_validate_context(pHddCtx);
2966 if (0 != status)
2967 {
2968 hddLog(VOS_TRACE_LEVEL_ERROR,
2969 FL("HDD context is not valid"));
2970 return -EINVAL;
2971 }
Dino Myclee8843b32014-07-04 14:21:45 +05302972 /* check the EXTScan Capability */
2973 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
2974 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
2975 {
2976 hddLog(VOS_TRACE_LEVEL_ERROR,
2977 FL("EXTScan not enabled/supported by Firmware"));
2978 return -EINVAL;
2979 }
2980
Dino Mycle6fb96c12014-06-10 11:52:40 +05302981 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
2982 data, dataLen,
2983 wlan_hdd_extscan_config_policy)) {
2984 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
2985 return -EINVAL;
2986 }
2987 /* Parse and fetch request Id */
2988 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
2989 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
2990 return -EINVAL;
2991 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05302992
Dino Myclee8843b32014-07-04 14:21:45 +05302993 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05302994 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
2995
Dino Myclee8843b32014-07-04 14:21:45 +05302996 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302997
Dino Myclee8843b32014-07-04 14:21:45 +05302998 reqMsg.sessionId = pAdapter->sessionId;
2999 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303000
3001 /* Parse and fetch flush parameter */
3002 if (!tb
3003 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH])
3004 {
3005 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr flush failed"));
3006 goto failed;
3007 }
Dino Myclee8843b32014-07-04 14:21:45 +05303008 reqMsg.flush = nla_get_u8(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303009 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH]);
3010
Dino Myclee8843b32014-07-04 14:21:45 +05303011 hddLog(VOS_TRACE_LEVEL_INFO, FL("Flush (%d)"), reqMsg.flush);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303012
Dino Myclee8843b32014-07-04 14:21:45 +05303013 status = sme_getCachedResults(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303014 if (!HAL_STATUS_SUCCESS(status)) {
3015 hddLog(VOS_TRACE_LEVEL_ERROR,
3016 FL("sme_getCachedResults failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303017 return -EINVAL;
3018 }
3019 return 0;
3020
3021failed:
Dino Mycle6fb96c12014-06-10 11:52:40 +05303022 return -EINVAL;
3023}
3024
3025static int wlan_hdd_cfg80211_extscan_set_bssid_hotlist(struct wiphy *wiphy,
3026 struct wireless_dev *wdev,
3027 void *data, int dataLen)
3028{
3029 tpSirEXTScanSetBssidHotListReqParams pReqMsg = NULL;
3030 struct net_device *dev = wdev->netdev;
3031 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3032 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3033 struct nlattr
3034 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3035 struct nlattr
3036 *tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3037 struct nlattr *apTh;
3038 eHalStatus status;
3039 tANI_U8 i = 0;
3040 int rem;
3041
3042 status = wlan_hdd_validate_context(pHddCtx);
3043 if (0 != status)
3044 {
3045 hddLog(VOS_TRACE_LEVEL_ERROR,
3046 FL("HDD context is not valid"));
3047 return -EINVAL;
3048 }
Dino Myclee8843b32014-07-04 14:21:45 +05303049 /* check the EXTScan Capability */
3050 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
3051 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
3052 {
3053 hddLog(VOS_TRACE_LEVEL_ERROR,
3054 FL("EXTScan not enabled/supported by Firmware"));
3055 return -EINVAL;
3056 }
3057
Dino Mycle6fb96c12014-06-10 11:52:40 +05303058 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3059 data, dataLen,
3060 wlan_hdd_extscan_config_policy)) {
3061 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3062 return -EINVAL;
3063 }
3064
3065 /* Parse and fetch request Id */
3066 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3067 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3068 return -EINVAL;
3069 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303070 pReqMsg = (tpSirEXTScanSetBssidHotListReqParams)
3071 vos_mem_malloc(sizeof(*pReqMsg));
3072 if (!pReqMsg) {
3073 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
3074 return -ENOMEM;
3075 }
3076
Dino Myclee8843b32014-07-04 14:21:45 +05303077
Dino Mycle6fb96c12014-06-10 11:52:40 +05303078 pReqMsg->requestId = nla_get_u32(
3079 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
3080 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
3081
3082 /* Parse and fetch number of APs */
3083 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP]) {
3084 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr number of AP failed"));
3085 goto fail;
3086 }
3087
3088 pReqMsg->sessionId = pAdapter->sessionId;
3089 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
3090
3091 pReqMsg->numAp = nla_get_u32(
3092 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP]);
3093 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of AP (%d)"), pReqMsg->numAp);
3094
3095 nla_for_each_nested(apTh,
3096 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM], rem) {
3097 if(nla_parse(tb2, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3098 nla_data(apTh), nla_len(apTh),
3099 NULL)) {
3100 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_parse failed"));
3101 goto fail;
3102 }
3103
3104 /* Parse and fetch MAC address */
3105 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]) {
3106 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac address failed"));
3107 goto fail;
3108 }
3109 memcpy(pReqMsg->ap[i].bssid, nla_data(
3110 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]),
3111 sizeof(tSirMacAddr));
3112 hddLog(VOS_TRACE_LEVEL_INFO, FL("BSSID: %pM "), pReqMsg->ap[i].bssid);
3113
3114 /* Parse and fetch low RSSI */
3115 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]) {
3116 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr low RSSI failed"));
3117 goto fail;
3118 }
3119 pReqMsg->ap[i].low = nla_get_s32(
3120 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]);
3121 hddLog(VOS_TRACE_LEVEL_INFO, FL("RSSI low (%d)"), pReqMsg->ap[i].low);
3122
3123 /* Parse and fetch high RSSI */
3124 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]) {
3125 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr high RSSI failed"));
3126 goto fail;
3127 }
3128 pReqMsg->ap[i].high = nla_get_s32(
3129 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]);
3130 hddLog(VOS_TRACE_LEVEL_INFO, FL("RSSI High (%d)"),
3131 pReqMsg->ap[i].high);
3132
3133 /* Parse and fetch channel */
3134 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL]) {
3135 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr channel failed"));
3136 goto fail;
3137 }
3138 pReqMsg->ap[i].channel = nla_get_u32(
3139 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL]);
3140 hddLog(VOS_TRACE_LEVEL_INFO,
3141 FL("Channel (%u)"), pReqMsg->ap[i].channel);
3142 i++;
3143 }
3144 status = sme_SetBssHotlist(pHddCtx->hHal, pReqMsg);
3145 if (!HAL_STATUS_SUCCESS(status)) {
3146 hddLog(VOS_TRACE_LEVEL_ERROR,
3147 FL("sme_SetBssHotlist failed(err=%d)"), status);
3148 vos_mem_free(pReqMsg);
3149 return -EINVAL;
3150 }
3151
Dino Myclee8843b32014-07-04 14:21:45 +05303152 vos_mem_free(pReqMsg);
3153
Dino Mycle6fb96c12014-06-10 11:52:40 +05303154 return 0;
3155
3156fail:
3157 vos_mem_free(pReqMsg);
3158 return -EINVAL;
3159}
3160
3161static int wlan_hdd_cfg80211_extscan_set_significant_change(struct wiphy *wiphy,
3162 struct wireless_dev *wdev,
3163 void *data, int dataLen)
3164{
3165 tpSirEXTScanSetSignificantChangeReqParams pReqMsg = NULL;
3166 struct net_device *dev = wdev->netdev;
3167 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3168 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3169 struct nlattr
3170 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3171 struct nlattr
3172 *tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3173 struct nlattr *apTh;
3174 eHalStatus status;
3175 int i = 0;
3176 int rem;
3177
3178 status = wlan_hdd_validate_context(pHddCtx);
3179 if (0 != status)
3180 {
3181 hddLog(VOS_TRACE_LEVEL_ERROR,
3182 FL("HDD context is not valid"));
3183 return -EINVAL;
3184 }
Dino Myclee8843b32014-07-04 14:21:45 +05303185 /* check the EXTScan Capability */
3186 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
3187 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
3188 {
3189 hddLog(VOS_TRACE_LEVEL_ERROR,
3190 FL("EXTScan not enabled/supported by Firmware"));
3191 return -EINVAL;
3192 }
3193
Dino Mycle6fb96c12014-06-10 11:52:40 +05303194 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3195 data, dataLen,
3196 wlan_hdd_extscan_config_policy)) {
3197 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3198 return -EINVAL;
3199 }
3200
3201 /* Parse and fetch request Id */
3202 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3203 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3204 return -EINVAL;
3205 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303206 pReqMsg = (tpSirEXTScanSetSignificantChangeReqParams)
Dino Myclee8843b32014-07-04 14:21:45 +05303207 vos_mem_malloc(sizeof(*pReqMsg));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303208 if (!pReqMsg) {
Dino Myclee8843b32014-07-04 14:21:45 +05303209 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
3210 return -ENOMEM;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303211 }
3212
Dino Myclee8843b32014-07-04 14:21:45 +05303213
3214
Dino Mycle6fb96c12014-06-10 11:52:40 +05303215 pReqMsg->requestId = nla_get_u32(
3216 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
3217 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
3218
3219 /* Parse and fetch RSSI sample size */
3220 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_RSSI_SAMPLE_SIZE])
3221 {
3222 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr RSSI sample size failed"));
3223 goto fail;
3224 }
3225 pReqMsg->rssiSampleSize = nla_get_u32(
3226 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_RSSI_SAMPLE_SIZE]);
3227 hddLog(VOS_TRACE_LEVEL_INFO,
3228 FL("RSSI sample size (%u)"), pReqMsg->rssiSampleSize);
3229
3230 /* Parse and fetch lost AP sample size */
3231 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_LOST_AP_SAMPLE_SIZE])
3232 {
3233 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr lost AP sample size failed"));
3234 goto fail;
3235 }
3236 pReqMsg->lostApSampleSize = nla_get_u32(
3237 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_LOST_AP_SAMPLE_SIZE]);
3238 hddLog(VOS_TRACE_LEVEL_INFO,
3239 FL("Lost AP sample size (%u)"), pReqMsg->lostApSampleSize);
3240 /* Parse and fetch minimum Breaching */
3241 if (!tb
3242 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_MIN_BREACHING]) {
3243 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr minBreaching failed"));
3244 goto fail;
3245 }
3246 pReqMsg->minBreaching = nla_get_u32(
3247 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_MIN_BREACHING]);
3248 hddLog(VOS_TRACE_LEVEL_INFO, FL(" Breaching (%d)"), pReqMsg->minBreaching);
3249
3250 /* Parse and fetch number of APs */
3251 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_NUM_AP]) {
3252 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr number of AP failed"));
3253 goto fail;
3254 }
3255 pReqMsg->numAp = nla_get_u32(
3256 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_NUM_AP]);
3257 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of AP (%d)"), pReqMsg->numAp);
3258
3259 pReqMsg->sessionId = pAdapter->sessionId;
3260 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
3261
3262 nla_for_each_nested(apTh,
3263 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM], rem) {
3264 if(nla_parse(tb2,
3265 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3266 nla_data(apTh), nla_len(apTh),
3267 NULL)) {
3268 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_parse failed"));
3269 goto fail;
3270 }
3271
3272 /* Parse and fetch MAC address */
3273 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]) {
3274 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac address failed"));
3275 goto fail;
3276 }
3277 memcpy(pReqMsg->ap[i].bssid, nla_data(
3278 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]),
3279 sizeof(tSirMacAddr));
3280
3281 /* Parse and fetch low RSSI */
3282 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]) {
3283 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr low RSSI failed"));
3284 goto fail;
3285 }
3286 pReqMsg->ap[i].low = nla_get_s32(
3287 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]);
3288 hddLog(VOS_TRACE_LEVEL_INFO, FL("RSSI low (%d)"), pReqMsg->ap[i].low);
3289
3290 /* Parse and fetch high RSSI */
3291 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]) {
3292 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr high RSSI failed"));
3293 goto fail;
3294 }
3295 pReqMsg->ap[i].high = nla_get_s32(
3296 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]);
3297 hddLog(VOS_TRACE_LEVEL_INFO,
3298 FL("RSSI High (%d)"), pReqMsg->ap[i].high);
3299
3300 /* Parse and fetch channel */
3301 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL]) {
3302 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr channel failed"));
3303 goto fail;
3304 }
3305 pReqMsg->ap[i].channel = nla_get_u32(
3306 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL]);
3307 hddLog(VOS_TRACE_LEVEL_INFO,
3308 FL("Channel (%u)"), pReqMsg->ap[i].channel);
3309 i++;
3310 }
3311
3312 status = sme_SetSignificantChange(pHddCtx->hHal, pReqMsg);
3313 if (!HAL_STATUS_SUCCESS(status)) {
3314 hddLog(VOS_TRACE_LEVEL_ERROR,
3315 FL("sme_SetSignificantChange failed(err=%d)"), status);
3316 vos_mem_free(pReqMsg);
3317 return -EINVAL;
3318 }
Dino Myclee8843b32014-07-04 14:21:45 +05303319 vos_mem_free(pReqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303320 hddLog(VOS_TRACE_LEVEL_ERROR, FL(" Exiting"));
3321 return 0;
3322
3323fail:
3324 vos_mem_free(pReqMsg);
3325 return -EINVAL;
3326}
3327
3328static int wlan_hdd_cfg80211_extscan_get_valid_channels(struct wiphy *wiphy,
3329 struct wireless_dev *wdev,
3330 void *data, int dataLen)
3331{
3332 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3333 tANI_U32 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
3334 tANI_U8 numChannels = 0;
3335 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3336 tANI_U32 requestId;
3337 tWifiBand wifiBand;
3338 eHalStatus status;
3339 struct sk_buff *replySkb;
3340 tANI_U8 i;
3341
3342 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering"));
3343 status = wlan_hdd_validate_context(pHddCtx);
3344 if (0 != status)
3345 {
3346 hddLog(VOS_TRACE_LEVEL_ERROR,
3347 FL("HDD context is not valid"));
3348 return -EINVAL;
3349 }
Dino Myclee8843b32014-07-04 14:21:45 +05303350 /* check the EXTScan Capability */
3351 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
3352 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
3353 {
3354 hddLog(VOS_TRACE_LEVEL_ERROR,
3355 FL("EXTScan not enabled/supported by Firmware"));
3356 return -EINVAL;
3357 }
3358
Dino Mycle6fb96c12014-06-10 11:52:40 +05303359 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3360 data, dataLen,
3361 wlan_hdd_extscan_config_policy)) {
3362 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3363 return -EINVAL;
3364 }
3365
3366 /* Parse and fetch request Id */
3367 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3368 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3369 return -EINVAL;
3370 }
3371 requestId = nla_get_u32(
3372 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
3373 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), requestId);
3374
3375 /* Parse and fetch wifi band */
3376 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND])
3377 {
3378 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr wifi band failed"));
3379 return -EINVAL;
3380 }
3381 wifiBand = nla_get_u32(
3382 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND]);
3383 hddLog(VOS_TRACE_LEVEL_INFO, FL("Wifi band (%d)"), wifiBand);
3384
3385 status = sme_GetValidChannelsByBand((tHalHandle)(pHddCtx->hHal),
3386 wifiBand, ChannelList,
3387 &numChannels);
3388 if (eHAL_STATUS_SUCCESS != status) {
3389 hddLog(VOS_TRACE_LEVEL_ERROR,
3390 FL("sme_GetValidChannelsByBand failed (err=%d)"), status);
3391 return -EINVAL;
3392 }
3393 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of channels (%d)"), numChannels);
3394 for (i = 0; i < numChannels; i++)
3395 hddLog(VOS_TRACE_LEVEL_INFO, "Channel: %u ", ChannelList[i]);
3396
3397 replySkb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(u32) +
3398 sizeof(u32) * numChannels +
3399 NLMSG_HDRLEN);
3400
3401 if (!replySkb) {
3402 hddLog(VOS_TRACE_LEVEL_ERROR,
3403 FL("valid channels: buffer alloc fail"));
3404 return -EINVAL;
3405 }
3406 if (nla_put_u32(replySkb,
3407 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_CHANNELS,
3408 numChannels) ||
3409 nla_put(replySkb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CHANNELS,
3410 sizeof(u32) * numChannels, ChannelList)) {
3411
3412 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
3413 kfree_skb(replySkb);
3414 return -EINVAL;
3415 }
3416
3417 return cfg80211_vendor_cmd_reply(replySkb);
3418}
3419
3420static int wlan_hdd_cfg80211_extscan_start(struct wiphy *wiphy,
3421 struct wireless_dev *wdev,
3422 void *data, int dataLen)
3423{
Dino Myclee8843b32014-07-04 14:21:45 +05303424 tpSirEXTScanStartReqParams pReqMsg = NULL;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303425 struct net_device *dev = wdev->netdev;
3426 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3427 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3428 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3429 struct nlattr *bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3430 struct nlattr *channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3431 struct nlattr *buckets;
3432 struct nlattr *channels;
3433 int rem1;
3434 int rem2;
3435 eHalStatus status;
3436 tANI_U8 bktIndex;
3437 tANI_U32 i = 0, j = 0;
3438
3439 status = wlan_hdd_validate_context(pHddCtx);
3440 if (0 != status)
3441 {
3442 hddLog(VOS_TRACE_LEVEL_ERROR,
3443 FL("HDD context is not valid"));
3444 return -EINVAL;
3445 }
Dino Myclee8843b32014-07-04 14:21:45 +05303446 /* check the EXTScan Capability */
3447 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
3448 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
3449 {
3450 hddLog(VOS_TRACE_LEVEL_ERROR,
3451 FL("EXTScan not enabled/supported by Firmware"));
3452 return -EINVAL;
3453 }
3454
Dino Mycle6fb96c12014-06-10 11:52:40 +05303455 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3456 data, dataLen,
3457 wlan_hdd_extscan_config_policy)) {
3458 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3459 return -EINVAL;
3460 }
3461
3462 /* Parse and fetch request Id */
3463 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3464 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3465 return -EINVAL;
3466 }
3467
Dino Myclee8843b32014-07-04 14:21:45 +05303468 pReqMsg = (tpSirEXTScanStartReqParams)
3469 vos_mem_malloc(sizeof(*pReqMsg));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303470 if (!pReqMsg) {
Dino Myclee8843b32014-07-04 14:21:45 +05303471 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
3472 return -ENOMEM;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303473 }
3474
3475 pReqMsg->requestId = nla_get_u32(
3476 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
3477 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
3478
3479 pReqMsg->sessionId = pAdapter->sessionId;
3480 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
3481
3482 /* Parse and fetch base period */
3483 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_BASE_PERIOD]) {
3484 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr base period failed"));
3485 goto fail;
3486 }
3487 pReqMsg->basePeriod = nla_get_u32(
3488 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_BASE_PERIOD]);
3489 hddLog(VOS_TRACE_LEVEL_INFO, FL("Base Period (%d)"),
3490 pReqMsg->basePeriod);
3491
3492 /* Parse and fetch max AP per scan */
3493 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_MAX_AP_PER_SCAN]) {
3494 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr max_ap_per_scan failed"));
3495 goto fail;
3496 }
3497 pReqMsg->maxAPperScan = nla_get_u32(
3498 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_MAX_AP_PER_SCAN]);
3499 hddLog(VOS_TRACE_LEVEL_INFO, FL("Max AP per Scan (%d)"),
3500 pReqMsg->maxAPperScan);
3501
3502 /* Parse and fetch report threshold */
3503 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD]) {
3504 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr report_threshold failed"));
3505 goto fail;
3506 }
3507 pReqMsg->reportThreshold = nla_get_u8(
3508 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD]);
3509 hddLog(VOS_TRACE_LEVEL_INFO, FL("Report Threshold (%d)"),
3510 pReqMsg->reportThreshold);
3511
3512 /* Parse and fetch number of buckets */
3513 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS]) {
3514 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr number of buckets failed"));
3515 goto fail;
3516 }
3517 pReqMsg->numBuckets = nla_get_u8(
3518 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS]);
3519 if (pReqMsg->numBuckets > WLAN_EXTSCAN_MAX_BUCKETS) {
3520 hddLog(VOS_TRACE_LEVEL_WARN, FL("Exceeded MAX number of buckets "
3521 "Setting numBuckets to %u"), WLAN_EXTSCAN_MAX_BUCKETS);
3522 pReqMsg->numBuckets = WLAN_EXTSCAN_MAX_BUCKETS;
3523 }
3524 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of Buckets (%d)"),
3525 pReqMsg->numBuckets);
3526 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC]) {
3527 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bucket spec failed"));
3528 goto fail;
3529 }
3530
3531 nla_for_each_nested(buckets,
3532 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC], rem1) {
3533 if(nla_parse(bucket,
3534 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3535 nla_data(buckets), nla_len(buckets), NULL)) { //policy
3536 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_parse failed"));
3537 goto fail;
3538 }
3539
3540 /* Parse and fetch bucket spec */
3541 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX]) {
3542 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bucket index failed"));
3543 goto fail;
3544 }
3545 bktIndex = nla_get_u8(
3546 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX]);
3547 hddLog(VOS_TRACE_LEVEL_INFO, FL("Bucket spec Index (%d)"), bktIndex);
3548 pReqMsg->buckets[bktIndex].bucket = bktIndex;
3549
3550 /* Parse and fetch wifi band */
3551 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND]) {
3552 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr wifi band failed"));
3553 goto fail;
3554 }
3555 pReqMsg->buckets[bktIndex].band = nla_get_u8(
3556 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND]);
3557 hddLog(VOS_TRACE_LEVEL_INFO, FL("Wifi band (%d)"),
3558 pReqMsg->buckets[bktIndex].band);
3559
3560 /* Parse and fetch period */
3561 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD]) {
3562 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr period failed"));
3563 goto fail;
3564 }
3565 pReqMsg->buckets[bktIndex].period = nla_get_u32(
3566 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD]);
3567 hddLog(VOS_TRACE_LEVEL_INFO, FL("period (%d)"),
3568 pReqMsg->buckets[bktIndex].period);
3569
3570 /* Parse and fetch report events */
3571 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS]) {
3572 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr report events failed"));
3573 goto fail;
3574 }
3575 pReqMsg->buckets[bktIndex].reportEvents = nla_get_u8(
3576 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS]);
3577 hddLog(VOS_TRACE_LEVEL_INFO, FL("report events (%d)"),
3578 pReqMsg->buckets[bktIndex].reportEvents);
3579
3580 /* Parse and fetch number of channels */
3581 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS]) {
3582 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr num channels failed"));
3583 goto fail;
3584 }
3585 pReqMsg->buckets[bktIndex].numChannels = nla_get_u32(
3586 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS]);
3587 hddLog(VOS_TRACE_LEVEL_INFO, FL("num channels (%d)"),
3588 pReqMsg->buckets[bktIndex].numChannels);
3589
3590 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC]) {
3591 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr channel spec failed"));
3592 goto fail;
3593 }
3594
3595 j = 0;
3596 nla_for_each_nested(channels,
3597 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC], rem2) {
3598 if(nla_parse(channel,
3599 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3600 nla_data(channels), nla_len(channels),
3601 NULL)) { //wlan_hdd_extscan_config_policy here
3602 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_parse failed"));
3603 goto fail;
3604 }
3605
3606 /* Parse and fetch channel */
3607 if (!channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL]) {
3608 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr channel failed"));
3609 goto fail;
3610 }
3611 pReqMsg->buckets[bktIndex].channels[j].channel = nla_get_u32(
3612 channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL]);
3613 hddLog(VOS_TRACE_LEVEL_INFO, FL("channel (%u)"),
3614 pReqMsg->buckets[bktIndex].channels[j].channel);
3615
3616 /* Parse and fetch dwell time */
3617 if (!channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME]) {
3618 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr dwelltime failed"));
3619 goto fail;
3620 }
3621 pReqMsg->buckets[bktIndex].channels[j].dwellTimeMs = nla_get_u32(
3622 channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME]);
3623 hddLog(VOS_TRACE_LEVEL_INFO, FL("Dwell time (%u ms)"),
3624 pReqMsg->buckets[bktIndex].channels[j].dwellTimeMs);
3625
3626 /* Parse and fetch channel spec passive */
3627 if (!channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE]) {
3628 hddLog(VOS_TRACE_LEVEL_ERROR,
3629 FL("attr channel spec passive failed"));
3630 goto fail;
3631 }
3632 pReqMsg->buckets[bktIndex].channels[j].passive = nla_get_u8(
3633 channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE]);
3634 hddLog(VOS_TRACE_LEVEL_INFO, FL("Chnl spec passive (%u)"),
3635 pReqMsg->buckets[bktIndex].channels[j].passive);
3636 j++;
3637 }
3638 i++;
3639 }
3640 status = sme_EXTScanStart(pHddCtx->hHal, pReqMsg);
3641 if (!HAL_STATUS_SUCCESS(status)) {
3642 hddLog(VOS_TRACE_LEVEL_ERROR,
3643 FL("sme_EXTScanStart failed(err=%d)"), status);
3644 vos_mem_free(pReqMsg);
3645 return -EINVAL;
3646 }
3647
Dino Myclee8843b32014-07-04 14:21:45 +05303648 vos_mem_free(pReqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303649 return 0;
3650
3651fail:
3652 vos_mem_free(pReqMsg);
3653 return -EINVAL;
3654}
3655
3656static int wlan_hdd_cfg80211_extscan_stop(struct wiphy *wiphy,
3657 struct wireless_dev *wdev,
3658 void *data, int dataLen)
3659{
Dino Myclee8843b32014-07-04 14:21:45 +05303660 tSirEXTScanStopReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303661 struct net_device *dev = wdev->netdev;
3662 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3663 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3664 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3665 eHalStatus status;
3666
3667 status = wlan_hdd_validate_context(pHddCtx);
3668 if (0 != status)
3669 {
3670 hddLog(VOS_TRACE_LEVEL_ERROR,
3671 FL("HDD context is not valid"));
3672 return -EINVAL;
3673 }
Dino Myclee8843b32014-07-04 14:21:45 +05303674 /* check the EXTScan Capability */
3675 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
3676 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
3677 {
3678 hddLog(VOS_TRACE_LEVEL_ERROR,
3679 FL("EXTScan not enabled/supported by Firmware"));
3680 return -EINVAL;
3681 }
3682
Dino Mycle6fb96c12014-06-10 11:52:40 +05303683 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3684 data, dataLen,
3685 wlan_hdd_extscan_config_policy)) {
3686 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3687 return -EINVAL;
3688 }
3689
3690 /* Parse and fetch request Id */
3691 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3692 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3693 return -EINVAL;
3694 }
3695
Dino Myclee8843b32014-07-04 14:21:45 +05303696 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303697 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05303698 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303699
Dino Myclee8843b32014-07-04 14:21:45 +05303700 reqMsg.sessionId = pAdapter->sessionId;
3701 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303702
Dino Myclee8843b32014-07-04 14:21:45 +05303703 status = sme_EXTScanStop(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303704 if (!HAL_STATUS_SUCCESS(status)) {
3705 hddLog(VOS_TRACE_LEVEL_ERROR,
3706 FL("sme_EXTScanStop failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303707 return -EINVAL;
3708 }
3709
3710 return 0;
3711}
3712
3713static int wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(struct wiphy *wiphy,
3714 struct wireless_dev *wdev,
3715 void *data, int dataLen)
3716{
Dino Myclee8843b32014-07-04 14:21:45 +05303717 tSirEXTScanResetBssidHotlistReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303718 struct net_device *dev = wdev->netdev;
3719 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3720 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3721 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3722 eHalStatus status;
3723
3724 status = wlan_hdd_validate_context(pHddCtx);
3725 if (0 != status)
3726 {
3727 hddLog(VOS_TRACE_LEVEL_ERROR,
3728 FL("HDD context is not valid"));
3729 return -EINVAL;
3730 }
Dino Myclee8843b32014-07-04 14:21:45 +05303731 /* check the EXTScan Capability */
3732 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
3733 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
3734 {
3735 hddLog(VOS_TRACE_LEVEL_ERROR,
3736 FL("EXTScan not enabled/supported by Firmware"));
3737 return -EINVAL;
3738 }
3739
Dino Mycle6fb96c12014-06-10 11:52:40 +05303740 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3741 data, dataLen,
3742 wlan_hdd_extscan_config_policy)) {
3743 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3744 return -EINVAL;
3745 }
3746
3747 /* Parse and fetch request Id */
3748 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3749 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3750 return -EINVAL;
3751 }
3752
Dino Myclee8843b32014-07-04 14:21:45 +05303753 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303754 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05303755 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303756
Dino Myclee8843b32014-07-04 14:21:45 +05303757 reqMsg.sessionId = pAdapter->sessionId;
3758 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303759
Dino Myclee8843b32014-07-04 14:21:45 +05303760 status = sme_ResetBssHotlist(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303761 if (!HAL_STATUS_SUCCESS(status)) {
3762 hddLog(VOS_TRACE_LEVEL_ERROR,
3763 FL("sme_ResetBssHotlist failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303764 return -EINVAL;
3765 }
3766
3767 return 0;
3768}
3769
3770static int wlan_hdd_cfg80211_extscan_reset_significant_change(
3771 struct wiphy *wiphy,
3772 struct wireless_dev *wdev,
3773 void *data, int dataLen)
3774{
Dino Myclee8843b32014-07-04 14:21:45 +05303775 tSirEXTScanResetSignificantChangeReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303776 struct net_device *dev = wdev->netdev;
3777 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3778 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3779 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3780 eHalStatus status;
3781
3782 hddLog(VOS_TRACE_LEVEL_INFO, FL(" Entering"));
3783 status = wlan_hdd_validate_context(pHddCtx);
3784 if (0 != status)
3785 {
3786 hddLog(VOS_TRACE_LEVEL_ERROR,
3787 FL("HDD context is not valid"));
3788 return -EINVAL;
3789 }
Dino Myclee8843b32014-07-04 14:21:45 +05303790 /* check the EXTScan Capability */
3791 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
3792 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
3793 {
3794 hddLog(VOS_TRACE_LEVEL_ERROR,
3795 FL("EXTScan not enabled/supported by Firmware"));
3796 return -EINVAL;
3797 }
3798
Dino Mycle6fb96c12014-06-10 11:52:40 +05303799 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3800 data, dataLen,
3801 wlan_hdd_extscan_config_policy)) {
3802 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3803 return -EINVAL;
3804 }
3805
3806 /* Parse and fetch request Id */
3807 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3808 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3809 return -EINVAL;
3810 }
3811
Dino Mycle6fb96c12014-06-10 11:52:40 +05303812
Dino Myclee8843b32014-07-04 14:21:45 +05303813 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303814 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05303815 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303816
Dino Myclee8843b32014-07-04 14:21:45 +05303817 reqMsg.sessionId = pAdapter->sessionId;
3818 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303819
Dino Myclee8843b32014-07-04 14:21:45 +05303820 status = sme_ResetSignificantChange(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303821 if (!HAL_STATUS_SUCCESS(status)) {
3822 hddLog(VOS_TRACE_LEVEL_ERROR,
3823 FL("sme_ResetSignificantChange failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303824 return -EINVAL;
3825 }
3826
3827 hddLog(VOS_TRACE_LEVEL_ERROR, FL(" Exiting"));
3828 return 0;
3829}
3830
3831#endif /* WLAN_FEATURE_EXTSCAN */
3832
Sunil Duttc69bccb2014-05-26 21:30:20 +05303833const struct wiphy_vendor_command hdd_wiphy_vendor_commands[] =
3834{
3835#ifdef WLAN_FEATURE_LINK_LAYER_STATS
3836 {
3837 .info.vendor_id = QCA_NL80211_VENDOR_ID,
3838 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR,
3839 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
3840 WIPHY_VENDOR_CMD_NEED_NETDEV |
3841 WIPHY_VENDOR_CMD_NEED_RUNNING,
3842 .doit = wlan_hdd_cfg80211_ll_stats_clear
3843 },
3844
3845 {
3846 .info.vendor_id = QCA_NL80211_VENDOR_ID,
3847 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET,
3848 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
3849 WIPHY_VENDOR_CMD_NEED_NETDEV |
3850 WIPHY_VENDOR_CMD_NEED_RUNNING,
3851 .doit = wlan_hdd_cfg80211_ll_stats_set
3852 },
3853
3854 {
3855 .info.vendor_id = QCA_NL80211_VENDOR_ID,
3856 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET,
3857 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
3858 WIPHY_VENDOR_CMD_NEED_NETDEV |
3859 WIPHY_VENDOR_CMD_NEED_RUNNING,
3860 .doit = wlan_hdd_cfg80211_ll_stats_get
Dino Mycle6fb96c12014-06-10 11:52:40 +05303861 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05303862#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
Dino Mycle6fb96c12014-06-10 11:52:40 +05303863#ifdef WLAN_FEATURE_EXTSCAN
3864 {
3865 .info.vendor_id = QCA_NL80211_VENDOR_ID,
3866 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START,
3867 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
3868 WIPHY_VENDOR_CMD_NEED_NETDEV |
3869 WIPHY_VENDOR_CMD_NEED_RUNNING,
3870 .doit = wlan_hdd_cfg80211_extscan_start
3871 },
3872 {
3873 .info.vendor_id = QCA_NL80211_VENDOR_ID,
3874 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP,
3875 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
3876 WIPHY_VENDOR_CMD_NEED_NETDEV |
3877 WIPHY_VENDOR_CMD_NEED_RUNNING,
3878 .doit = wlan_hdd_cfg80211_extscan_stop
3879 },
3880 {
3881 .info.vendor_id = QCA_NL80211_VENDOR_ID,
3882 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_VALID_CHANNELS,
3883 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
3884 WIPHY_VENDOR_CMD_NEED_NETDEV,
3885 .doit = wlan_hdd_cfg80211_extscan_get_valid_channels
3886 },
3887 {
3888 .info.vendor_id = QCA_NL80211_VENDOR_ID,
3889 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES,
3890 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
3891 WIPHY_VENDOR_CMD_NEED_NETDEV |
3892 WIPHY_VENDOR_CMD_NEED_RUNNING,
3893 .doit = wlan_hdd_cfg80211_extscan_get_capabilities
3894 },
3895 {
3896 .info.vendor_id = QCA_NL80211_VENDOR_ID,
3897 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS,
3898 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
3899 WIPHY_VENDOR_CMD_NEED_NETDEV |
3900 WIPHY_VENDOR_CMD_NEED_RUNNING,
3901 .doit = wlan_hdd_cfg80211_extscan_get_cached_results
3902 },
3903 {
3904 .info.vendor_id = QCA_NL80211_VENDOR_ID,
3905 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST,
3906 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
3907 WIPHY_VENDOR_CMD_NEED_NETDEV |
3908 WIPHY_VENDOR_CMD_NEED_RUNNING,
3909 .doit = wlan_hdd_cfg80211_extscan_set_bssid_hotlist
3910 },
3911 {
3912 .info.vendor_id = QCA_NL80211_VENDOR_ID,
3913 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST,
3914 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
3915 WIPHY_VENDOR_CMD_NEED_NETDEV |
3916 WIPHY_VENDOR_CMD_NEED_RUNNING,
3917 .doit = wlan_hdd_cfg80211_extscan_reset_bssid_hotlist
3918 },
3919 {
3920 .info.vendor_id = QCA_NL80211_VENDOR_ID,
3921 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_SIGNIFICANT_CHANGE,
3922 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
3923 WIPHY_VENDOR_CMD_NEED_NETDEV |
3924 WIPHY_VENDOR_CMD_NEED_RUNNING,
3925 .doit = wlan_hdd_cfg80211_extscan_set_significant_change
3926 },
3927 {
3928 .info.vendor_id = QCA_NL80211_VENDOR_ID,
3929 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_SIGNIFICANT_CHANGE,
3930 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
3931 WIPHY_VENDOR_CMD_NEED_NETDEV |
3932 WIPHY_VENDOR_CMD_NEED_RUNNING,
3933 .doit = wlan_hdd_cfg80211_extscan_reset_significant_change
3934 },
3935#endif /* WLAN_FEATURE_EXTSCAN */
Sunil Duttc69bccb2014-05-26 21:30:20 +05303936};
3937
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08003938/* vendor specific events */
Sunil Duttc69bccb2014-05-26 21:30:20 +05303939static const
3940struct nl80211_vendor_cmd_info wlan_hdd_cfg80211_vendor_events[] =
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08003941{
3942#ifdef FEATURE_WLAN_CH_AVOID
3943 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05303944 .vendor_id = QCA_NL80211_VENDOR_ID,
3945 .subcmd = QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08003946 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05303947#endif /* FEATURE_WLAN_CH_AVOID Index = 0*/
3948#ifdef WLAN_FEATURE_LINK_LAYER_STATS
3949 {
3950 /* Index = 1*/
3951 .vendor_id = QCA_NL80211_VENDOR_ID,
3952 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET
3953 },
3954 {
3955 /* Index = 2*/
3956 .vendor_id = QCA_NL80211_VENDOR_ID,
3957 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET
3958 },
3959 {
3960 /* Index = 3*/
3961 .vendor_id = QCA_NL80211_VENDOR_ID,
3962 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR
3963 },
3964 {
3965 /* Index = 4*/
3966 .vendor_id = QCA_NL80211_VENDOR_ID,
3967 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_RADIO_RESULTS
3968 },
3969 {
3970 /* Index = 5*/
3971 .vendor_id = QCA_NL80211_VENDOR_ID,
3972 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_IFACE_RESULTS
3973 },
3974 {
3975 /* Index = 6*/
3976 .vendor_id = QCA_NL80211_VENDOR_ID,
3977 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_PEERS_RESULTS
3978 },
3979#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
Dino Mycle6fb96c12014-06-10 11:52:40 +05303980#ifdef WLAN_FEATURE_EXTSCAN
3981 {
3982 .vendor_id = QCA_NL80211_VENDOR_ID,
3983 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START
3984 },
3985 {
3986 .vendor_id = QCA_NL80211_VENDOR_ID,
3987 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP
3988 },
3989 {
3990 .vendor_id = QCA_NL80211_VENDOR_ID,
3991 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES
3992 },
3993 {
3994 .vendor_id = QCA_NL80211_VENDOR_ID,
3995 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS
3996 },
3997 {
3998 .vendor_id = QCA_NL80211_VENDOR_ID,
3999 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_RESULTS_AVAILABLE
4000 },
4001 {
4002 .vendor_id = QCA_NL80211_VENDOR_ID,
4003 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_FULL_SCAN_RESULT
4004 },
4005 {
4006 .vendor_id = QCA_NL80211_VENDOR_ID,
4007 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_EVENT
4008 },
4009 {
4010 .vendor_id = QCA_NL80211_VENDOR_ID,
4011 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_FOUND
4012 },
4013 {
4014 .vendor_id = QCA_NL80211_VENDOR_ID,
4015 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST
4016 },
4017 {
4018 .vendor_id = QCA_NL80211_VENDOR_ID,
4019 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST
4020 },
4021 {
4022 .vendor_id = QCA_NL80211_VENDOR_ID,
4023 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SIGNIFICANT_CHANGE
4024 },
4025 {
4026 .vendor_id = QCA_NL80211_VENDOR_ID,
4027 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_SIGNIFICANT_CHANGE
4028 },
4029 {
4030 .vendor_id = QCA_NL80211_VENDOR_ID,
4031 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_SIGNIFICANT_CHANGE
4032 },
4033#endif /* WLAN_FEATURE_EXTSCAN */
Sunil Duttc69bccb2014-05-26 21:30:20 +05304034
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08004035};
4036
Jeff Johnson295189b2012-06-20 16:38:30 -07004037/*
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05304038 * FUNCTION: wlan_hdd_cfg80211_wiphy_alloc
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304039 * This function is called by hdd_wlan_startup()
4040 * during initialization.
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05304041 * This function is used to allocate wiphy structure.
Jeff Johnson295189b2012-06-20 16:38:30 -07004042 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05304043struct wiphy *wlan_hdd_cfg80211_wiphy_alloc(int priv_size)
Jeff Johnson295189b2012-06-20 16:38:30 -07004044{
4045 struct wiphy *wiphy;
4046 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304047 /*
4048 * Create wiphy device
Jeff Johnson295189b2012-06-20 16:38:30 -07004049 */
4050 wiphy = wiphy_new(&wlan_hdd_cfg80211_ops, priv_size);
4051
4052 if (!wiphy)
4053 {
4054 /* Print error and jump into err label and free the memory */
4055 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wiphy init failed", __func__);
4056 return NULL;
4057 }
4058
Sunil Duttc69bccb2014-05-26 21:30:20 +05304059
Jeff Johnson295189b2012-06-20 16:38:30 -07004060 return wiphy;
4061}
4062
4063/*
4064 * FUNCTION: wlan_hdd_cfg80211_update_band
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304065 * This function is called from the supplicant through a
Jeff Johnson295189b2012-06-20 16:38:30 -07004066 * private ioctl to change the band value
4067 */
4068int wlan_hdd_cfg80211_update_band(struct wiphy *wiphy, eCsrBand eBand)
4069{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05304070 int i, j;
4071 eNVChannelEnabledType channelEnabledState;
4072
Jeff Johnsone7245742012-09-05 17:12:55 -07004073 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05304074
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05304075 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
Jeff Johnson295189b2012-06-20 16:38:30 -07004076 {
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05304077
4078 if (NULL == wiphy->bands[i])
4079 {
4080 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[i] is NULL, i = %d",
4081 __func__, i);
4082 continue;
4083 }
4084
4085 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
4086 {
4087 struct ieee80211_supported_band *band = wiphy->bands[i];
4088
4089 channelEnabledState = vos_nv_getChannelEnabledState(
4090 band->channels[j].hw_value);
4091
4092 if (IEEE80211_BAND_2GHZ == i && eCSR_BAND_5G == eBand) // 5G only
4093 {
4094 // Enable Social channels for P2P
4095 if (WLAN_HDD_IS_SOCIAL_CHANNEL(band->channels[j].center_freq) &&
4096 NV_CHANNEL_ENABLE == channelEnabledState)
4097 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
4098 else
4099 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
4100 continue;
4101 }
4102 else if (IEEE80211_BAND_5GHZ == i && eCSR_BAND_24 == eBand) // 2G only
4103 {
4104 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
4105 continue;
4106 }
4107
4108 if (NV_CHANNEL_DISABLE == channelEnabledState ||
4109 NV_CHANNEL_INVALID == channelEnabledState)
4110 {
4111 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
4112 }
4113 else if (NV_CHANNEL_DFS == channelEnabledState)
4114 {
4115 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
4116 band->channels[j].flags |= IEEE80211_CHAN_RADAR;
4117 }
4118 else
4119 {
4120 band->channels[j].flags &= ~(IEEE80211_CHAN_DISABLED
4121 |IEEE80211_CHAN_RADAR);
4122 }
4123 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004124 }
4125 return 0;
4126}
4127/*
4128 * FUNCTION: wlan_hdd_cfg80211_init
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304129 * This function is called by hdd_wlan_startup()
4130 * during initialization.
Jeff Johnson295189b2012-06-20 16:38:30 -07004131 * This function is used to initialize and register wiphy structure.
4132 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05304133int wlan_hdd_cfg80211_init(struct device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -07004134 struct wiphy *wiphy,
4135 hdd_config_t *pCfg
4136 )
4137{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05304138 int i, j;
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +05304139 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4140
Jeff Johnsone7245742012-09-05 17:12:55 -07004141 ENTER();
4142
Jeff Johnson295189b2012-06-20 16:38:30 -07004143 /* Now bind the underlying wlan device with wiphy */
4144 set_wiphy_dev(wiphy, dev);
4145
4146 wiphy->mgmt_stypes = wlan_hdd_txrx_stypes;
Amar Singhalfddc28c2013-09-05 13:03:40 -07004147
Kiet Lam6c583332013-10-14 05:37:09 +05304148#ifndef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -07004149 /* the flag for the other case would be initialzed in
4150 vos_init_wiphy_from_nv_bin */
Amar Singhal0a402232013-10-11 20:57:16 -07004151 wiphy->flags |= WIPHY_FLAG_STRICT_REGULATORY;
Kiet Lam6c583332013-10-14 05:37:09 +05304152#endif
Amar Singhala49cbc52013-10-08 18:37:44 -07004153
Amar Singhalfddc28c2013-09-05 13:03:40 -07004154 /* This will disable updating of NL channels from passive to
4155 * active if a beacon is received on passive channel. */
4156 wiphy->flags |= WIPHY_FLAG_DISABLE_BEACON_HINTS;
Amar Singhalf0073192013-09-20 12:34:56 -07004157
Amar Singhalfddc28c2013-09-05 13:03:40 -07004158
Amar Singhala49cbc52013-10-08 18:37:44 -07004159
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004160#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -07004161 wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME
4162 | WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD
4163 | WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL
Jeff Johnsone7245742012-09-05 17:12:55 -07004164 | WIPHY_FLAG_OFFCHAN_TX;
Kiet Lam6c583332013-10-14 05:37:09 +05304165 wiphy->country_ie_pref = NL80211_COUNTRY_IE_IGNORE_CORE;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004166#endif
Amar Singhala49cbc52013-10-08 18:37:44 -07004167
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004168#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowda640728a2013-03-28 12:21:54 -07004169 if (pCfg->isFastTransitionEnabled
James Zmuda77fb5ae2013-01-29 08:00:17 -08004170#ifdef FEATURE_WLAN_LFR
Srinivas Girigowda640728a2013-03-28 12:21:54 -07004171 || pCfg->isFastRoamIniFeatureEnabled
4172#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08004173#ifdef FEATURE_WLAN_ESE
4174 || pCfg->isEseIniFeatureEnabled
Srinivas Girigowda640728a2013-03-28 12:21:54 -07004175#endif
4176 )
4177 {
4178 wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM;
4179 }
James Zmuda77fb5ae2013-01-29 08:00:17 -08004180#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08004181#ifdef FEATURE_WLAN_TDLS
4182 wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS
4183 | WIPHY_FLAG_TDLS_EXTERNAL_SETUP;
4184#endif
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05304185#ifdef FEATURE_WLAN_SCAN_PNO
Hardik Kantilal Patel3dfd8792013-11-13 20:34:57 +05304186 if (pCfg->configPNOScanSupport)
4187 {
4188 wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN;
4189 wiphy->max_sched_scan_ssids = SIR_PNO_MAX_SUPP_NETWORKS;
4190 wiphy->max_match_sets = SIR_PNO_MAX_SUPP_NETWORKS;
4191 wiphy->max_sched_scan_ie_len = SIR_MAC_MAX_IE_LENGTH;
4192 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05304193#endif/*FEATURE_WLAN_SCAN_PNO*/
Mohit Khanna698ba2a2012-12-04 15:08:18 -08004194
Amar Singhalfddc28c2013-09-05 13:03:40 -07004195#ifdef CONFIG_ENABLE_LINUX_REG
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07004196 /* even with WIPHY_FLAG_CUSTOM_REGULATORY,
4197 driver can still register regulatory callback and
Amar Singhalfddc28c2013-09-05 13:03:40 -07004198 it will get regulatory settings in wiphy->band[], but
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07004199 driver need to determine what to do with both
4200 regulatory settings */
Amar Singhalfddc28c2013-09-05 13:03:40 -07004201
4202 wiphy->reg_notifier = wlan_hdd_linux_reg_notifier;
Amar Singhala49cbc52013-10-08 18:37:44 -07004203#else
4204 wiphy->reg_notifier = wlan_hdd_crda_reg_notifier;
Amar Singhalfddc28c2013-09-05 13:03:40 -07004205#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004206
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304207 wiphy->max_scan_ssids = MAX_SCAN_SSID;
4208
Madan Mohan Koyyalamudi6815b162013-07-19 17:17:46 +05304209 wiphy->max_scan_ie_len = SIR_MAC_MAX_IE_LENGTH;
Jeff Johnson295189b2012-06-20 16:38:30 -07004210
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05304211 wiphy->max_acl_mac_addrs = MAX_ACL_MAC_ADDRESS;
4212
Jeff Johnson295189b2012-06-20 16:38:30 -07004213 /* Supports STATION & AD-HOC modes right now */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304214 wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -07004215 | BIT(NL80211_IFTYPE_ADHOC)
Jeff Johnson295189b2012-06-20 16:38:30 -07004216 | BIT(NL80211_IFTYPE_P2P_CLIENT)
4217 | BIT(NL80211_IFTYPE_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07004218 | BIT(NL80211_IFTYPE_AP);
4219
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05304220 if( pCfg->advertiseConcurrentOperation )
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08004221 {
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05304222#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
4223 if( pCfg->enableMCC )
4224 {
4225 /* Currently, supports up to two channels */
4226 wlan_hdd_iface_combination.num_different_channels = 2;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08004227
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05304228 if( !pCfg->allowMCCGODiffBI )
4229 wlan_hdd_iface_combination.beacon_int_infra_match = true;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08004230
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05304231 }
4232 wiphy->iface_combinations = &wlan_hdd_iface_combination;
4233 wiphy->n_iface_combinations = 1;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08004234#endif
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05304235 }
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08004236
Jeff Johnson295189b2012-06-20 16:38:30 -07004237 /* Before registering we need to update the ht capabilitied based
4238 * on ini values*/
4239 if( !pCfg->ShortGI20MhzEnable )
4240 {
4241 wlan_hdd_band_2_4_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
4242 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
4243 wlan_hdd_band_p2p_2_4_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
4244 }
4245
4246 if( !pCfg->ShortGI40MhzEnable )
4247 {
4248 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_40;
4249 }
4250
4251 if( !pCfg->nChannelBondingMode5GHz )
4252 {
4253 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
4254 }
4255
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05304256 wiphy->bands[IEEE80211_BAND_2GHZ] = &wlan_hdd_band_2_4_GHZ;
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +05304257 if (true == hdd_is_5g_supported(pHddCtx))
4258 {
4259 wiphy->bands[IEEE80211_BAND_5GHZ] = &wlan_hdd_band_5_GHZ;
4260 }
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05304261
4262 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
4263 {
4264
4265 if (NULL == wiphy->bands[i])
4266 {
4267 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[i] is NULL, i = %d",
4268 __func__, i);
4269 continue;
4270 }
4271
4272 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
4273 {
4274 struct ieee80211_supported_band *band = wiphy->bands[i];
4275
4276 if (IEEE80211_BAND_2GHZ == i && eCSR_BAND_5G == pCfg->nBandCapability) // 5G only
4277 {
4278 // Enable social channels for P2P
4279 if (WLAN_HDD_IS_SOCIAL_CHANNEL(band->channels[j].center_freq))
4280 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
4281 else
4282 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
4283 continue;
4284 }
4285 else if (IEEE80211_BAND_5GHZ == i && eCSR_BAND_24 == pCfg->nBandCapability) // 2G only
4286 {
4287 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
4288 continue;
4289 }
4290 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004291 }
4292 /*Initialise the supported cipher suite details*/
4293 wiphy->cipher_suites = hdd_cipher_suites;
4294 wiphy->n_cipher_suites = ARRAY_SIZE(hdd_cipher_suites);
4295
4296 /*signal strength in mBm (100*dBm) */
4297 wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
4298
4299#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Sushant Kaushik4f640e42014-07-08 12:27:09 +05304300 wiphy->max_remain_on_channel_duration = 5000;
Jeff Johnson295189b2012-06-20 16:38:30 -07004301#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07004302
Sunil Duttc69bccb2014-05-26 21:30:20 +05304303 wiphy->n_vendor_commands = ARRAY_SIZE(hdd_wiphy_vendor_commands);
4304 wiphy->vendor_commands = hdd_wiphy_vendor_commands;
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08004305 wiphy->vendor_events = wlan_hdd_cfg80211_vendor_events;
4306 wiphy->n_vendor_events = ARRAY_SIZE(wlan_hdd_cfg80211_vendor_events);
4307
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05304308 EXIT();
4309 return 0;
4310}
4311
4312/* In this function we are registering wiphy. */
4313int wlan_hdd_cfg80211_register(struct wiphy *wiphy)
4314{
4315 ENTER();
4316 /* Register our wiphy dev with cfg80211 */
Jeff Johnson295189b2012-06-20 16:38:30 -07004317 if (0 > wiphy_register(wiphy))
4318 {
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05304319 /* print error */
Jeff Johnson295189b2012-06-20 16:38:30 -07004320 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
4321 return -EIO;
4322 }
4323
4324 EXIT();
4325 return 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304326}
Jeff Johnson295189b2012-06-20 16:38:30 -07004327
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05304328/* In this function we are updating channel list when,
4329 regulatory domain is FCC and country code is US.
4330 Here In FCC standard 5GHz UNII-1 Bands are indoor only.
4331 As per FCC smart phone is not a indoor device.
4332 GO should not opeate on indoor channels */
4333void wlan_hdd_cfg80211_update_reg_info(struct wiphy *wiphy)
4334{
4335 int j;
4336 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4337 tANI_U8 defaultCountryCode[3] = SME_INVALID_COUNTRY_CODE;
4338 //Default counrtycode from NV at the time of wiphy initialization.
4339 if (eHAL_STATUS_SUCCESS != sme_GetDefaultCountryCodeFrmNv(pHddCtx->hHal,
4340 &defaultCountryCode[0]))
4341 {
Jeff Johnson0299d0a2013-10-30 12:37:43 -07004342 hddLog(LOGE, FL("Failed to get default country code from NV"));
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05304343 }
4344 if ((defaultCountryCode[0]== 'U') && (defaultCountryCode[1]=='S'))
4345 {
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05304346 if (NULL == wiphy->bands[IEEE80211_BAND_5GHZ])
4347 {
4348 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[IEEE80211_BAND_5GHZ] is NULL",__func__ );
4349 return;
4350 }
4351 for (j = 0; j < wiphy->bands[IEEE80211_BAND_5GHZ]->n_channels; j++)
4352 {
4353 struct ieee80211_supported_band *band = wiphy->bands[IEEE80211_BAND_5GHZ];
4354 // Mark UNII -1 band channel as passive
4355 if (WLAN_HDD_CHANNEL_IN_UNII_1_BAND(band->channels[j].center_freq))
4356 band->channels[j].flags |= IEEE80211_CHAN_PASSIVE_SCAN;
4357 }
4358 }
4359}
4360
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05304361/* This function registers for all frame which supplicant is interested in */
4362void wlan_hdd_cfg80211_register_frames(hdd_adapter_t* pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07004363{
Jeff Johnson295189b2012-06-20 16:38:30 -07004364 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
4365 /* Register for all P2P action, public action etc frames */
4366 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
4367
Jeff Johnsone7245742012-09-05 17:12:55 -07004368 ENTER();
4369
Jeff Johnson295189b2012-06-20 16:38:30 -07004370 /* Right now we are registering these frame when driver is getting
4371 initialized. Once we will move to 2.6.37 kernel, in which we have
4372 frame register ops, we will move this code as a part of that */
4373 /* GAS Initial Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304374 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Jeff Johnson295189b2012-06-20 16:38:30 -07004375 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
4376
4377 /* GAS Initial Response */
4378 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
4379 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304380
Jeff Johnson295189b2012-06-20 16:38:30 -07004381 /* GAS Comeback Request */
4382 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
4383 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
4384
4385 /* GAS Comeback Response */
4386 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
4387 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
4388
4389 /* P2P Public Action */
4390 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304391 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -07004392 P2P_PUBLIC_ACTION_FRAME_SIZE );
4393
4394 /* P2P Action */
4395 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
4396 (v_U8_t*)P2P_ACTION_FRAME,
4397 P2P_ACTION_FRAME_SIZE );
Chet Lanctot186b5732013-03-18 10:26:30 -07004398
Gopichand Nakkalae3d56e72013-04-21 23:33:32 +05304399 /* WNM BSS Transition Request frame */
4400 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
4401 (v_U8_t*)WNM_BSS_ACTION_FRAME,
4402 WNM_BSS_ACTION_FRAME_SIZE );
Leela Venkata Kiran Kumar Reddy Chiralae8e62c82013-10-29 18:23:26 -07004403
4404 /* WNM-Notification */
4405 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
4406 (v_U8_t*)WNM_NOTIFICATION_FRAME,
4407 WNM_NOTIFICATION_FRAME_SIZE );
Jeff Johnson295189b2012-06-20 16:38:30 -07004408}
4409
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05304410void wlan_hdd_cfg80211_deregister_frames(hdd_adapter_t* pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07004411{
Jeff Johnson295189b2012-06-20 16:38:30 -07004412 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
4413 /* Register for all P2P action, public action etc frames */
4414 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
4415
Jeff Johnsone7245742012-09-05 17:12:55 -07004416 ENTER();
4417
Jeff Johnson295189b2012-06-20 16:38:30 -07004418 /* Right now we are registering these frame when driver is getting
4419 initialized. Once we will move to 2.6.37 kernel, in which we have
4420 frame register ops, we will move this code as a part of that */
4421 /* GAS Initial Request */
4422
4423 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
4424 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
4425
4426 /* GAS Initial Response */
4427 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
4428 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304429
Jeff Johnson295189b2012-06-20 16:38:30 -07004430 /* GAS Comeback Request */
4431 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
4432 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
4433
4434 /* GAS Comeback Response */
4435 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
4436 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
4437
4438 /* P2P Public Action */
4439 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304440 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -07004441 P2P_PUBLIC_ACTION_FRAME_SIZE );
4442
4443 /* P2P Action */
4444 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
4445 (v_U8_t*)P2P_ACTION_FRAME,
4446 P2P_ACTION_FRAME_SIZE );
Leela Venkata Kiran Kumar Reddy Chiralae8e62c82013-10-29 18:23:26 -07004447 /* WNM-Notification */
4448 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
4449 (v_U8_t*)WNM_NOTIFICATION_FRAME,
4450 WNM_NOTIFICATION_FRAME_SIZE );
Jeff Johnson295189b2012-06-20 16:38:30 -07004451}
4452
4453#ifdef FEATURE_WLAN_WAPI
4454void wlan_hdd_cfg80211_set_key_wapi(hdd_adapter_t* pAdapter, u8 key_index,
4455 const u8 *mac_addr, u8 *key , int key_Len)
4456{
4457 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4458 tCsrRoamSetKey setKey;
4459 v_BOOL_t isConnected = TRUE;
4460 int status = 0;
4461 v_U32_t roamId= 0xFF;
4462 tANI_U8 *pKeyPtr = NULL;
4463 int n = 0;
4464
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05304465 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s(%d)",
4466 __func__, hdd_device_modetoString(pAdapter->device_mode),
4467 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07004468
Gopichand Nakkalae7480202013-02-11 15:24:22 +05304469 vos_mem_zero(&setKey, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -07004470 setKey.keyId = key_index; // Store Key ID
4471 setKey.encType = eCSR_ENCRYPT_TYPE_WPI; // SET WAPI Encryption
4472 setKey.keyDirection = eSIR_TX_RX; // Key Directionn both TX and RX
4473 setKey.paeRole = 0 ; // the PAE role
4474 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
4475 {
4476 vos_set_macaddr_broadcast( (v_MACADDR_t *)setKey.peerMac );
4477 }
4478 else
4479 {
4480 isConnected = hdd_connIsConnected(pHddStaCtx);
4481 vos_mem_copy(setKey.peerMac,&pHddStaCtx->conn_info.bssId,WNI_CFG_BSSID_LEN);
4482 }
4483 setKey.keyLength = key_Len;
4484 pKeyPtr = setKey.Key;
4485 memcpy( pKeyPtr, key, key_Len);
4486
Arif Hussain6d2a3322013-11-17 19:50:10 -08004487 hddLog(VOS_TRACE_LEVEL_INFO,"%s: WAPI KEY LENGTH:0x%04x",
Jeff Johnson295189b2012-06-20 16:38:30 -07004488 __func__, key_Len);
4489 for (n = 0 ; n < key_Len; n++)
4490 hddLog(VOS_TRACE_LEVEL_INFO, "%s WAPI KEY Data[%d]:%02x ",
4491 __func__,n,setKey.Key[n]);
4492
4493 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
4494 if ( isConnected )
4495 {
4496 status= sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
4497 pAdapter->sessionId, &setKey, &roamId );
4498 }
4499 if ( status != 0 )
4500 {
4501 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4502 "[%4d] sme_RoamSetKey returned ERROR status= %d",
4503 __LINE__, status );
4504 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
4505 }
4506}
4507#endif /* FEATURE_WLAN_WAPI*/
4508
4509#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304510int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07004511 beacon_data_t **ppBeacon,
4512 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004513#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304514int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004515 beacon_data_t **ppBeacon,
4516 struct cfg80211_beacon_data *params,
4517 int dtim_period)
4518#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304519{
Jeff Johnson295189b2012-06-20 16:38:30 -07004520 int size;
4521 beacon_data_t *beacon = NULL;
4522 beacon_data_t *old = NULL;
4523 int head_len,tail_len;
4524
Jeff Johnsone7245742012-09-05 17:12:55 -07004525 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07004526 if (params->head && !params->head_len)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05304527 {
4528 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4529 FL("head_len is NULL"));
Jeff Johnson295189b2012-06-20 16:38:30 -07004530 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05304531 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004532
4533 old = pAdapter->sessionCtx.ap.beacon;
4534
4535 if (!params->head && !old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05304536 {
4537 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4538 FL("session(%d) old and new heads points to NULL"),
4539 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07004540 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05304541 }
4542
4543 if (params->tail && !params->tail_len)
4544 {
4545 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4546 FL("tail_len is zero but tail is not NULL"));
4547 return -EINVAL;
4548 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004549
Jeff Johnson295189b2012-06-20 16:38:30 -07004550#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,38))
4551 /* Kernel 3.0 is not updating dtim_period for set beacon */
4552 if (!params->dtim_period)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05304553 {
4554 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4555 FL("dtim period is 0"));
Jeff Johnson295189b2012-06-20 16:38:30 -07004556 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05304557 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004558#endif
4559
4560 if(params->head)
4561 head_len = params->head_len;
4562 else
4563 head_len = old->head_len;
4564
4565 if(params->tail || !old)
4566 tail_len = params->tail_len;
4567 else
4568 tail_len = old->tail_len;
4569
4570 size = sizeof(beacon_data_t) + head_len + tail_len;
4571
4572 beacon = kzalloc(size, GFP_KERNEL);
4573
4574 if( beacon == NULL )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05304575 {
4576 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4577 FL("Mem allocation for beacon failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -07004578 return -ENOMEM;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05304579 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004580
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004581#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07004582 if(params->dtim_period || !old )
4583 beacon->dtim_period = params->dtim_period;
4584 else
4585 beacon->dtim_period = old->dtim_period;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004586#else
4587 if(dtim_period || !old )
4588 beacon->dtim_period = dtim_period;
4589 else
4590 beacon->dtim_period = old->dtim_period;
4591#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304592
Jeff Johnson295189b2012-06-20 16:38:30 -07004593 beacon->head = ((u8 *) beacon) + sizeof(beacon_data_t);
4594 beacon->tail = beacon->head + head_len;
4595 beacon->head_len = head_len;
4596 beacon->tail_len = tail_len;
4597
4598 if(params->head) {
4599 memcpy (beacon->head,params->head,beacon->head_len);
4600 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304601 else {
Jeff Johnson295189b2012-06-20 16:38:30 -07004602 if(old)
4603 memcpy (beacon->head,old->head,beacon->head_len);
4604 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304605
Jeff Johnson295189b2012-06-20 16:38:30 -07004606 if(params->tail) {
4607 memcpy (beacon->tail,params->tail,beacon->tail_len);
4608 }
4609 else {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304610 if(old)
Jeff Johnson295189b2012-06-20 16:38:30 -07004611 memcpy (beacon->tail,old->tail,beacon->tail_len);
4612 }
4613
4614 *ppBeacon = beacon;
4615
4616 kfree(old);
4617
4618 return 0;
4619
4620}
Jeff Johnson295189b2012-06-20 16:38:30 -07004621
4622v_U8_t* wlan_hdd_cfg80211_get_ie_ptr(v_U8_t *pIes, int length, v_U8_t eid)
4623{
4624 int left = length;
4625 v_U8_t *ptr = pIes;
4626 v_U8_t elem_id,elem_len;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304627
Jeff Johnson295189b2012-06-20 16:38:30 -07004628 while(left >= 2)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304629 {
Jeff Johnson295189b2012-06-20 16:38:30 -07004630 elem_id = ptr[0];
4631 elem_len = ptr[1];
4632 left -= 2;
4633 if(elem_len > left)
4634 {
4635 hddLog(VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07004636 FL("****Invalid IEs eid = %d elem_len=%d left=%d*****"),
Jeff Johnson295189b2012-06-20 16:38:30 -07004637 eid,elem_len,left);
4638 return NULL;
4639 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304640 if (elem_id == eid)
Jeff Johnson295189b2012-06-20 16:38:30 -07004641 {
4642 return ptr;
4643 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304644
Jeff Johnson295189b2012-06-20 16:38:30 -07004645 left -= elem_len;
4646 ptr += (elem_len + 2);
4647 }
4648 return NULL;
4649}
4650
Jeff Johnson295189b2012-06-20 16:38:30 -07004651/* Check if rate is 11g rate or not */
4652static int wlan_hdd_rate_is_11g(u8 rate)
4653{
Sanjay Devnani28322e22013-06-21 16:13:40 -07004654 static const u8 gRateArray[8] = {12, 18, 24, 36, 48, 72, 96, 108}; /* actual rate * 2 */
Jeff Johnson295189b2012-06-20 16:38:30 -07004655 u8 i;
4656 for (i = 0; i < 8; i++)
4657 {
4658 if(rate == gRateArray[i])
4659 return TRUE;
4660 }
4661 return FALSE;
4662}
4663
4664/* Check for 11g rate and set proper 11g only mode */
4665static void wlan_hdd_check_11gmode(u8 *pIe, u8* require_ht,
4666 u8* pCheckRatesfor11g, eSapPhyMode* pSapHw_mode)
4667{
4668 u8 i, num_rates = pIe[0];
4669
4670 pIe += 1;
4671 for ( i = 0; i < num_rates; i++)
4672 {
4673 if( *pCheckRatesfor11g && (TRUE == wlan_hdd_rate_is_11g(pIe[i] & RATE_MASK)))
4674 {
4675 /* If rate set have 11g rate than change the mode to 11G */
4676 *pSapHw_mode = eSAP_DOT11_MODE_11g;
4677 if (pIe[i] & BASIC_RATE_MASK)
4678 {
4679 /* If we have 11g rate as basic rate, it means mode
4680 is 11g only mode.
4681 */
4682 *pSapHw_mode = eSAP_DOT11_MODE_11g_ONLY;
4683 *pCheckRatesfor11g = FALSE;
4684 }
4685 }
4686 else if((BASIC_RATE_MASK | WLAN_BSS_MEMBERSHIP_SELECTOR_HT_PHY) == pIe[i])
4687 {
4688 *require_ht = TRUE;
4689 }
4690 }
4691 return;
4692}
4693
4694static void wlan_hdd_set_sapHwmode(hdd_adapter_t *pHostapdAdapter)
4695{
4696 tsap_Config_t *pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
4697 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
4698 struct ieee80211_mgmt *pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
4699 u8 checkRatesfor11g = TRUE;
4700 u8 require_ht = FALSE;
4701 u8 *pIe=NULL;
4702
4703 pConfig->SapHw_mode= eSAP_DOT11_MODE_11b;
4704
4705 pIe = wlan_hdd_cfg80211_get_ie_ptr(&pMgmt_frame->u.beacon.variable[0],
4706 pBeacon->head_len, WLAN_EID_SUPP_RATES);
4707 if (pIe != NULL)
4708 {
4709 pIe += 1;
4710 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
4711 &pConfig->SapHw_mode);
4712 }
4713
4714 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
4715 WLAN_EID_EXT_SUPP_RATES);
4716 if (pIe != NULL)
4717 {
4718
4719 pIe += 1;
4720 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
4721 &pConfig->SapHw_mode);
4722 }
4723
4724 if( pConfig->channel > 14 )
4725 {
4726 pConfig->SapHw_mode= eSAP_DOT11_MODE_11a;
4727 }
4728
4729 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
4730 WLAN_EID_HT_CAPABILITY);
4731
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304732 if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07004733 {
4734 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n;
4735 if(require_ht)
4736 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n_ONLY;
4737 }
4738}
4739
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05304740static int wlan_hdd_add_ie(hdd_adapter_t* pHostapdAdapter, v_U8_t *genie,
4741 v_U8_t *total_ielen, v_U8_t *oui, v_U8_t oui_size)
4742{
Arif Hussaine7f3ea52013-09-12 21:56:36 -07004743 v_U16_t ielen = 0;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05304744 v_U8_t *pIe = NULL;
4745 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
4746
4747 pIe = wlan_hdd_get_vendor_oui_ie_ptr(oui, oui_size,
4748 pBeacon->tail, pBeacon->tail_len);
4749
4750 if (pIe)
4751 {
4752 ielen = pIe[1] + 2;
4753 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
4754 {
4755 vos_mem_copy(&genie[*total_ielen], pIe, ielen);
4756 }
4757 else
4758 {
4759 hddLog( VOS_TRACE_LEVEL_ERROR, "**Ie Length is too big***");
4760 return -EINVAL;
4761 }
4762 *total_ielen += ielen;
4763 }
4764 return 0;
4765}
4766
Arif Hussaine7f3ea52013-09-12 21:56:36 -07004767static void wlan_hdd_add_hostapd_conf_vsie(hdd_adapter_t* pHostapdAdapter,
4768 v_U8_t *genie, v_U8_t *total_ielen)
4769{
4770 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
4771 int left = pBeacon->tail_len;
4772 v_U8_t *ptr = pBeacon->tail;
4773 v_U8_t elem_id, elem_len;
4774 v_U16_t ielen = 0;
4775
4776 if ( NULL == ptr || 0 == left )
4777 return;
4778
4779 while (left >= 2)
4780 {
4781 elem_id = ptr[0];
4782 elem_len = ptr[1];
4783 left -= 2;
4784 if (elem_len > left)
4785 {
4786 hddLog( VOS_TRACE_LEVEL_ERROR,
4787 "****Invalid IEs eid = %d elem_len=%d left=%d*****",
4788 elem_id, elem_len, left);
4789 return;
4790 }
4791 if (IE_EID_VENDOR == elem_id)
4792 {
4793 /* skipping the VSIE's which we don't want to include or
4794 * it will be included by existing code
4795 */
4796 if ((memcmp( &ptr[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) != 0 ) &&
4797#ifdef WLAN_FEATURE_WFD
4798 (memcmp( &ptr[2], WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE) != 0) &&
4799#endif
4800 (memcmp( &ptr[2], WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
4801 (memcmp( &ptr[2], BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
4802 (memcmp( &ptr[2], "\x00\x50\xf2\x02", WPA_OUI_TYPE_SIZE) != 0) &&
4803 (memcmp( &ptr[2], WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
4804 (memcmp( &ptr[2], P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE) != 0))
4805 {
4806 ielen = ptr[1] + 2;
4807 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
4808 {
4809 vos_mem_copy(&genie[*total_ielen], ptr, ielen);
4810 *total_ielen += ielen;
4811 }
4812 else
4813 {
4814 hddLog( VOS_TRACE_LEVEL_ERROR,
4815 "IE Length is too big "
4816 "IEs eid=%d elem_len=%d total_ie_lent=%d",
4817 elem_id, elem_len, *total_ielen);
4818 }
4819 }
4820 }
4821
4822 left -= elem_len;
4823 ptr += (elem_len + 2);
4824 }
4825 return;
4826}
4827
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004828#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07004829static int wlan_hdd_cfg80211_update_apies(hdd_adapter_t* pHostapdAdapter,
4830 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004831#else
4832static int wlan_hdd_cfg80211_update_apies(hdd_adapter_t* pHostapdAdapter,
4833 struct cfg80211_beacon_data *params)
4834#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07004835{
4836 v_U8_t *genie;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05304837 v_U8_t total_ielen = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07004838 v_U8_t addIE[1] = {0};
Jeff Johnsone7245742012-09-05 17:12:55 -07004839 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07004840
4841 genie = vos_mem_malloc(MAX_GENIE_LEN);
4842
4843 if(genie == NULL) {
4844
4845 return -ENOMEM;
4846 }
4847
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05304848 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
4849 &total_ielen, WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07004850 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05304851 hddLog(LOGE,
4852 FL("Adding WPS IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05304853 ret = -EINVAL;
4854 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07004855 }
4856
4857#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05304858 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
4859 &total_ielen, WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE))
4860 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05304861 hddLog(LOGE,
4862 FL("Adding WFD IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05304863 ret = -EINVAL;
4864 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07004865 }
4866#endif
4867
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05304868 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
4869 &total_ielen, P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07004870 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05304871 hddLog(LOGE,
4872 FL("Adding P2P IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05304873 ret = -EINVAL;
4874 goto done;
4875 }
4876
4877 if (WLAN_HDD_SOFTAP == pHostapdAdapter->device_mode)
4878 {
Arif Hussaine7f3ea52013-09-12 21:56:36 -07004879 wlan_hdd_add_hostapd_conf_vsie(pHostapdAdapter, genie, &total_ielen);
Jeff Johnson295189b2012-06-20 16:38:30 -07004880 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004881
4882 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
4883 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, genie, total_ielen, NULL,
4884 eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
4885 {
4886 hddLog(LOGE,
4887 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07004888 ret = -EINVAL;
4889 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07004890 }
4891
4892 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
4893 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
4894 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
4895 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
4896 ==eHAL_STATUS_FAILURE)
4897 {
4898 hddLog(LOGE,
4899 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07004900 ret = -EINVAL;
4901 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07004902 }
4903
4904 // Added for ProResp IE
4905 if ( (params->proberesp_ies != NULL) && (params->proberesp_ies_len != 0) )
4906 {
4907 u16 rem_probe_resp_ie_len = params->proberesp_ies_len;
4908 u8 probe_rsp_ie_len[3] = {0};
4909 u8 counter = 0;
4910 /* Check Probe Resp Length if it is greater then 255 then Store
4911 Probe Resp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1 &
4912 WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are not able
4913 Store More then 255 bytes into One Variable.
4914 */
4915 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
4916 {
4917 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
4918 {
4919 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
4920 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
4921 }
4922 else
4923 {
4924 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
4925 rem_probe_resp_ie_len = 0;
4926 }
4927 }
4928
4929 rem_probe_resp_ie_len = 0;
4930
4931 if (probe_rsp_ie_len[0] > 0)
4932 {
4933 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
4934 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
4935 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
4936 probe_rsp_ie_len[0], NULL,
4937 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
4938 {
4939 hddLog(LOGE,
4940 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07004941 ret = -EINVAL;
4942 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07004943 }
4944 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
4945 }
4946
4947 if (probe_rsp_ie_len[1] > 0)
4948 {
4949 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
4950 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
4951 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
4952 probe_rsp_ie_len[1], NULL,
4953 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
4954 {
4955 hddLog(LOGE,
4956 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07004957 ret = -EINVAL;
4958 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07004959 }
4960 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
4961 }
4962
4963 if (probe_rsp_ie_len[2] > 0)
4964 {
4965 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
4966 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
4967 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
4968 probe_rsp_ie_len[2], NULL,
4969 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
4970 {
4971 hddLog(LOGE,
4972 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07004973 ret = -EINVAL;
4974 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07004975 }
4976 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
4977 }
4978
4979 if (probe_rsp_ie_len[1] == 0 )
4980 {
4981 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
4982 WNI_CFG_PROBE_RSP_ADDNIE_DATA2, (tANI_U8*)addIE, 0, NULL,
4983 eANI_BOOLEAN_FALSE) )
4984 {
4985 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08004986 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07004987 }
4988 }
4989
4990 if (probe_rsp_ie_len[2] == 0 )
4991 {
4992 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
4993 WNI_CFG_PROBE_RSP_ADDNIE_DATA3, (tANI_U8*)addIE, 0, NULL,
4994 eANI_BOOLEAN_FALSE) )
4995 {
4996 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08004997 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07004998 }
4999 }
5000
5001 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
5002 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
5003 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
5004 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
5005 == eHAL_STATUS_FAILURE)
5006 {
5007 hddLog(LOGE,
5008 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07005009 ret = -EINVAL;
5010 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07005011 }
5012 }
5013 else
5014 {
5015 // Reset WNI_CFG_PROBE_RSP Flags
5016 wlan_hdd_reset_prob_rspies(pHostapdAdapter);
5017
5018 hddLog(VOS_TRACE_LEVEL_INFO,
5019 "%s: No Probe Response IE received in set beacon",
5020 __func__);
5021 }
5022
5023 // Added for AssocResp IE
5024 if ( (params->assocresp_ies != NULL) && (params->assocresp_ies_len != 0) )
5025 {
5026 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
5027 WNI_CFG_ASSOC_RSP_ADDNIE_DATA, (tANI_U8*)params->assocresp_ies,
5028 params->assocresp_ies_len, NULL,
5029 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
5030 {
5031 hddLog(LOGE,
5032 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07005033 ret = -EINVAL;
5034 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07005035 }
5036
5037 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
5038 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 1, NULL,
5039 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
5040 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
5041 == eHAL_STATUS_FAILURE)
5042 {
5043 hddLog(LOGE,
5044 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07005045 ret = -EINVAL;
5046 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07005047 }
5048 }
5049 else
5050 {
5051 hddLog(VOS_TRACE_LEVEL_INFO,
5052 "%s: No Assoc Response IE received in set beacon",
5053 __func__);
5054
5055 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
5056 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
5057 eANI_BOOLEAN_FALSE) )
5058 {
5059 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08005060 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07005061 }
5062 }
5063
Jeff Johnsone7245742012-09-05 17:12:55 -07005064done:
Jeff Johnson295189b2012-06-20 16:38:30 -07005065 vos_mem_free(genie);
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05305066 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07005067}
Jeff Johnson295189b2012-06-20 16:38:30 -07005068
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305069/*
Jeff Johnson295189b2012-06-20 16:38:30 -07005070 * FUNCTION: wlan_hdd_validate_operation_channel
5071 * called by wlan_hdd_cfg80211_start_bss() and
5072 * wlan_hdd_cfg80211_set_channel()
5073 * This function validates whether given channel is part of valid
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305074 * channel list.
5075 */
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07005076VOS_STATUS wlan_hdd_validate_operation_channel(hdd_adapter_t *pAdapter,int channel)
Jeff Johnson295189b2012-06-20 16:38:30 -07005077{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305078
Jeff Johnson295189b2012-06-20 16:38:30 -07005079 v_U32_t num_ch = 0;
5080 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN];
5081 u32 indx = 0;
5082 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05305083 v_U8_t fValidChannel = FALSE, count = 0;
5084 hdd_config_t *hdd_pConfig_ini= (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305085
Jeff Johnson295189b2012-06-20 16:38:30 -07005086 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
5087
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05305088 if ( hdd_pConfig_ini->sapAllowAllChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -07005089 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05305090 /* Validate the channel */
5091 for (count = RF_CHAN_1 ; count <= RF_CHAN_165 ; count++)
Jeff Johnson295189b2012-06-20 16:38:30 -07005092 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05305093 if ( channel == rfChannels[count].channelNum )
5094 {
5095 fValidChannel = TRUE;
5096 break;
5097 }
5098 }
5099 if (fValidChannel != TRUE)
5100 {
5101 hddLog(VOS_TRACE_LEVEL_ERROR,
5102 "%s: Invalid Channel [%d]", __func__, channel);
5103 return VOS_STATUS_E_FAILURE;
Jeff Johnson295189b2012-06-20 16:38:30 -07005104 }
5105 }
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05305106 else
Jeff Johnson295189b2012-06-20 16:38:30 -07005107 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05305108 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
5109 valid_ch, &num_ch))
5110 {
5111 hddLog(VOS_TRACE_LEVEL_ERROR,
5112 "%s: failed to get valid channel list", __func__);
5113 return VOS_STATUS_E_FAILURE;
5114 }
5115 for (indx = 0; indx < num_ch; indx++)
5116 {
5117 if (channel == valid_ch[indx])
5118 {
5119 break;
5120 }
5121 }
5122
Rashmi Ramanna3b59e122014-04-10 14:45:13 +05305123 if (indx >= num_ch)
5124 {
5125 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
5126 {
5127 eCsrBand band;
5128 unsigned int freq;
5129
5130 sme_GetFreqBand(hHal, &band);
5131
5132 if (eCSR_BAND_5G == band)
5133 {
5134#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
5135 if (channel <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
5136 {
5137 freq = ieee80211_channel_to_frequency(channel,
5138 IEEE80211_BAND_2GHZ);
5139 }
5140 else
5141 {
5142 freq = ieee80211_channel_to_frequency(channel,
5143 IEEE80211_BAND_5GHZ);
5144 }
5145#else
5146 freq = ieee80211_channel_to_frequency(channel);
5147#endif
5148 if(WLAN_HDD_IS_SOCIAL_CHANNEL(freq))
5149 return VOS_STATUS_SUCCESS;
5150 }
5151 }
5152
5153 hddLog(VOS_TRACE_LEVEL_ERROR,
5154 "%s: Invalid Channel [%d]", __func__, channel);
5155 return VOS_STATUS_E_FAILURE;
5156 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005157 }
Rashmi Ramanna3b59e122014-04-10 14:45:13 +05305158
Jeff Johnson295189b2012-06-20 16:38:30 -07005159 return VOS_STATUS_SUCCESS;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305160
Jeff Johnson295189b2012-06-20 16:38:30 -07005161}
5162
Viral Modi3a32cc52013-02-08 11:14:52 -08005163/**
5164 * FUNCTION: wlan_hdd_cfg80211_set_channel
5165 * This function is used to set the channel number
5166 */
5167static int wlan_hdd_cfg80211_set_channel( struct wiphy *wiphy, struct net_device *dev,
5168 struct ieee80211_channel *chan,
5169 enum nl80211_channel_type channel_type
5170 )
5171{
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05305172 hdd_adapter_t *pAdapter = NULL;
Viral Modi3a32cc52013-02-08 11:14:52 -08005173 v_U32_t num_ch = 0;
Jeff Johnson4416a782013-03-25 14:17:50 -07005174 int channel = 0;
Viral Modi3a32cc52013-02-08 11:14:52 -08005175 int freq = chan->center_freq; /* freq is in MHZ */
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305176 hdd_context_t *pHddCtx;
5177 int status;
Viral Modi3a32cc52013-02-08 11:14:52 -08005178
5179 ENTER();
5180
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05305181
Viral Modi3a32cc52013-02-08 11:14:52 -08005182 if( NULL == dev )
5183 {
5184 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08005185 "%s: Called with dev = NULL.", __func__);
Viral Modi3a32cc52013-02-08 11:14:52 -08005186 return -ENODEV;
5187 }
5188 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05305189
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05305190 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
5191 TRACE_CODE_HDD_CFG80211_SET_CHANNEL, pAdapter->sessionId,
5192 channel_type ));
Viral Modi3a32cc52013-02-08 11:14:52 -08005193 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05305194 "%s: device_mode = %s (%d) freq = %d", __func__,
5195 hdd_device_modetoString(pAdapter->device_mode),
5196 pAdapter->device_mode, chan->center_freq);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305197
5198 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
5199 status = wlan_hdd_validate_context(pHddCtx);
5200
5201 if (0 != status)
Viral Modi3a32cc52013-02-08 11:14:52 -08005202 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305203 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5204 "%s: HDD context is not valid", __func__);
5205 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -08005206 }
5207
5208 /*
5209 * Do freq to chan conversion
5210 * TODO: for 11a
5211 */
5212
5213 channel = ieee80211_frequency_to_channel(freq);
5214
5215 /* Check freq range */
5216 if ((WNI_CFG_CURRENT_CHANNEL_STAMIN > channel) ||
5217 (WNI_CFG_CURRENT_CHANNEL_STAMAX < channel))
5218 {
5219 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08005220 "%s: Channel [%d] is outside valid range from %d to %d",
Viral Modi3a32cc52013-02-08 11:14:52 -08005221 __func__, channel, WNI_CFG_CURRENT_CHANNEL_STAMIN,
5222 WNI_CFG_CURRENT_CHANNEL_STAMAX);
5223 return -EINVAL;
5224 }
5225
5226 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
5227
Gopichand Nakkala6ab19562013-03-07 13:59:42 +05305228 if ((WLAN_HDD_SOFTAP != pAdapter->device_mode) &&
5229 (WLAN_HDD_P2P_GO != pAdapter->device_mode))
Viral Modi3a32cc52013-02-08 11:14:52 -08005230 {
5231 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pAdapter,channel))
5232 {
5233 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08005234 "%s: Invalid Channel [%d]", __func__, channel);
Viral Modi3a32cc52013-02-08 11:14:52 -08005235 return -EINVAL;
5236 }
5237 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
5238 "%s: set channel to [%d] for device mode =%d",
5239 __func__, channel,pAdapter->device_mode);
5240 }
5241 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Viral Modi3a32cc52013-02-08 11:14:52 -08005242 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Viral Modi3a32cc52013-02-08 11:14:52 -08005243 )
5244 {
5245 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
5246 tCsrRoamProfile * pRoamProfile = &pWextState->roamProfile;
5247 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
5248
5249 if (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState)
5250 {
5251 /* Link is up then return cant set channel*/
5252 hddLog( VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08005253 "%s: IBSS Associated, can't set the channel", __func__);
Viral Modi3a32cc52013-02-08 11:14:52 -08005254 return -EINVAL;
5255 }
5256
5257 num_ch = pRoamProfile->ChannelInfo.numOfChannels = 1;
5258 pHddStaCtx->conn_info.operationChannel = channel;
5259 pRoamProfile->ChannelInfo.ChannelList =
5260 &pHddStaCtx->conn_info.operationChannel;
5261 }
5262 else if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Viral Modi3a32cc52013-02-08 11:14:52 -08005263 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Viral Modi3a32cc52013-02-08 11:14:52 -08005264 )
5265 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05305266 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
5267 {
5268 if(VOS_STATUS_SUCCESS !=
5269 wlan_hdd_validate_operation_channel(pAdapter,channel))
5270 {
5271 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08005272 "%s: Invalid Channel [%d]", __func__, channel);
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05305273 return -EINVAL;
5274 }
5275 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
5276 }
5277 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
Viral Modi3a32cc52013-02-08 11:14:52 -08005278 {
5279 hdd_config_t *cfg_param = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
5280
5281 /* If auto channel selection is configured as enable/ 1 then ignore
5282 channel set by supplicant
5283 */
5284 if ( cfg_param->apAutoChannelSelection )
5285 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05305286 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel =
5287 AUTO_CHANNEL_SELECT;
Viral Modi3a32cc52013-02-08 11:14:52 -08005288 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05305289 "%s: set channel to auto channel (0) for device mode =%s (%d)",
5290 __func__, hdd_device_modetoString(pAdapter->device_mode),
5291 pAdapter->device_mode);
Viral Modi3a32cc52013-02-08 11:14:52 -08005292 }
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05305293 else
5294 {
5295 if(VOS_STATUS_SUCCESS !=
5296 wlan_hdd_validate_operation_channel(pAdapter,channel))
5297 {
5298 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08005299 "%s: Invalid Channel [%d]", __func__, channel);
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05305300 return -EINVAL;
5301 }
5302 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
5303 }
Viral Modi3a32cc52013-02-08 11:14:52 -08005304 }
5305 }
5306 else
5307 {
5308 hddLog(VOS_TRACE_LEVEL_FATAL,
5309 "%s: Invalid device mode failed to set valid channel", __func__);
5310 return -EINVAL;
5311 }
5312 EXIT();
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305313 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -08005314}
5315
Jeff Johnson295189b2012-06-20 16:38:30 -07005316#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
5317static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
5318 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005319#else
5320static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
5321 struct cfg80211_beacon_data *params,
5322 const u8 *ssid, size_t ssid_len,
5323 enum nl80211_hidden_ssid hidden_ssid)
5324#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005325{
5326 tsap_Config_t *pConfig;
5327 beacon_data_t *pBeacon = NULL;
5328 struct ieee80211_mgmt *pMgmt_frame;
5329 v_U8_t *pIe=NULL;
5330 v_U16_t capab_info;
5331 eCsrAuthType RSNAuthType;
5332 eCsrEncryptionType RSNEncryptType;
5333 eCsrEncryptionType mcRSNEncryptType;
5334 int status = VOS_STATUS_SUCCESS;
5335 tpWLAN_SAPEventCB pSapEventCallback;
5336 hdd_hostapd_state_t *pHostapdState;
5337 v_U8_t wpaRsnIEdata[(SIR_MAC_MAX_IE_LENGTH * 2)+4]; //Max ie length 255 * 2(WPA+RSN) + 2 bytes (vendor specific ID) * 2
5338 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05305339 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07005340 struct qc_mac_acl_entry *acl_entry = NULL;
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05305341 hdd_config_t *iniConfig;
Jeff Johnson295189b2012-06-20 16:38:30 -07005342 v_SINT_t i;
Madan Mohan Koyyalamudi543172b2012-12-05 16:40:18 -08005343 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
Chet Lanctot40142442014-05-20 13:39:25 -07005344 v_BOOL_t MFPCapable = VOS_FALSE;
5345 v_BOOL_t MFPRequired = VOS_FALSE;
Abhishek Singhf0ac1752014-03-05 17:47:09 +05305346 eHddDot11Mode sapDot11Mode =
5347 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->sapDot11Mode;
Jeff Johnson295189b2012-06-20 16:38:30 -07005348
5349 ENTER();
5350
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05305351 iniConfig = pHddCtx->cfg_ini;
5352
Jeff Johnson295189b2012-06-20 16:38:30 -07005353 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter);
5354
5355 pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
5356
5357 pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
5358
5359 pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
5360
5361 pConfig->beacon_int = pMgmt_frame->u.beacon.beacon_int;
5362
5363 //channel is already set in the set_channel Call back
5364 //pConfig->channel = pCommitConfig->channel;
5365
5366 /*Protection parameter to enable or disable*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305367 pConfig->protEnabled =
Jeff Johnson295189b2012-06-20 16:38:30 -07005368 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtEnabled;
5369
5370 pConfig->dtim_period = pBeacon->dtim_period;
5371
Arif Hussain6d2a3322013-11-17 19:50:10 -08005372 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"****pConfig->dtim_period=%d***",
Jeff Johnson295189b2012-06-20 16:38:30 -07005373 pConfig->dtim_period);
5374
5375
Madan Mohan Koyyalamudie0ca11f2012-11-27 15:57:52 -08005376 if (pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson32d95a32012-09-10 13:15:23 -07005377 {
5378 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -07005379 WLAN_EID_COUNTRY);
Kiet Lam083504c2013-11-25 14:17:45 +05305380 if(memcmp(pHddCtx->cfg_ini->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0)
5381 {
5382 tANI_BOOLEAN restartNeeded;
5383 pConfig->ieee80211d = 1;
5384 vos_mem_copy(pConfig->countryCode, pHddCtx->cfg_ini->apCntryCode, 3);
5385 sme_setRegInfo(hHal, pConfig->countryCode);
5386 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
5387 }
5388 else if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07005389 {
Jeff Johnson32d95a32012-09-10 13:15:23 -07005390 tANI_BOOLEAN restartNeeded;
Jeff Johnson32d95a32012-09-10 13:15:23 -07005391 pConfig->ieee80211d = 1;
5392 vos_mem_copy(pConfig->countryCode, &pIe[2], 3);
5393 sme_setRegInfo(hHal, pConfig->countryCode);
5394 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
Jeff Johnson295189b2012-06-20 16:38:30 -07005395 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07005396 else
5397 {
5398 pConfig->ieee80211d = 0;
5399 }
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05305400 /*
5401 * If auto channel is configured i.e. channel is 0,
5402 * so skip channel validation.
5403 */
5404 if( AUTO_CHANNEL_SELECT != pConfig->channel )
5405 {
5406 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pHostapdAdapter,pConfig->channel))
5407 {
5408 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08005409 "%s: Invalid Channel [%d]", __func__, pConfig->channel);
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05305410 return -EINVAL;
5411 }
5412 }
5413 else
5414 {
5415 if(1 != pHddCtx->is_dynamic_channel_range_set)
5416 {
5417 hdd_config_t *hdd_pConfig= (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini;
5418 WLANSAP_SetChannelRange(hHal, hdd_pConfig->apStartChannelNum,
5419 hdd_pConfig->apEndChannelNum,hdd_pConfig->apOperatingBand);
5420 }
5421 pHddCtx->is_dynamic_channel_range_set = 0;
5422 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005423 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07005424 else
Jeff Johnson295189b2012-06-20 16:38:30 -07005425 {
5426 pConfig->ieee80211d = 0;
5427 }
5428 pConfig->authType = eSAP_AUTO_SWITCH;
5429
5430 capab_info = pMgmt_frame->u.beacon.capab_info;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305431
5432 pConfig->privacy = (pMgmt_frame->u.beacon.capab_info &
Jeff Johnson295189b2012-06-20 16:38:30 -07005433 WLAN_CAPABILITY_PRIVACY) ? VOS_TRUE : VOS_FALSE;
5434
5435 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uPrivacy = pConfig->privacy;
5436
5437 /*Set wps station to configured*/
5438 pIe = wlan_hdd_get_wps_ie_ptr(pBeacon->tail, pBeacon->tail_len);
5439
5440 if(pIe)
5441 {
5442 if(pIe[1] < (2 + WPS_OUI_TYPE_SIZE))
5443 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08005444 hddLog( VOS_TRACE_LEVEL_ERROR, "**Wps Ie Length is too small***");
Jeff Johnson295189b2012-06-20 16:38:30 -07005445 return -EINVAL;
5446 }
5447 else if(memcmp(&pIe[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) == 0)
5448 {
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07005449 hddLog( VOS_TRACE_LEVEL_INFO, "** WPS IE(len %d) ***", (pIe[1]+2));
Jeff Johnson295189b2012-06-20 16:38:30 -07005450 /* Check 15 bit of WPS IE as it contain information for wps state
5451 * WPS state
5452 */
5453 if(SAP_WPS_ENABLED_UNCONFIGURED == pIe[15])
5454 {
5455 pConfig->wps_state = SAP_WPS_ENABLED_UNCONFIGURED;
5456 } else if(SAP_WPS_ENABLED_CONFIGURED == pIe[15])
5457 {
5458 pConfig->wps_state = SAP_WPS_ENABLED_CONFIGURED;
5459 }
5460 }
5461 }
5462 else
5463 {
5464 pConfig->wps_state = SAP_WPS_DISABLED;
5465 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305466 pConfig->fwdWPSPBCProbeReq = 1; // Forward WPS PBC probe request frame up
Jeff Johnson295189b2012-06-20 16:38:30 -07005467
c_hpothufe599e92014-06-16 11:38:55 +05305468 pConfig->RSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
5469 pConfig->mcRSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
5470 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType =
5471 eCSR_ENCRYPT_TYPE_NONE;
5472
Jeff Johnson295189b2012-06-20 16:38:30 -07005473 pConfig->RSNWPAReqIELength = 0;
5474 pConfig->pRSNWPAReqIE = NULL;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305475 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -07005476 WLAN_EID_RSN);
5477 if(pIe && pIe[1])
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305478 {
Jeff Johnson295189b2012-06-20 16:38:30 -07005479 pConfig->RSNWPAReqIELength = pIe[1] + 2;
5480 memcpy(&wpaRsnIEdata[0], pIe, pConfig->RSNWPAReqIELength);
5481 pConfig->pRSNWPAReqIE = &wpaRsnIEdata[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305482 /* The actual processing may eventually be more extensive than
5483 * this. Right now, just consume any PMKIDs that are sent in
Jeff Johnson295189b2012-06-20 16:38:30 -07005484 * by the app.
5485 * */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305486 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -07005487 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
5488 &RSNEncryptType,
5489 &mcRSNEncryptType,
5490 &RSNAuthType,
Chet Lanctot8cecea22014-02-11 19:09:36 -08005491 &MFPCapable,
5492 &MFPRequired,
Jeff Johnson295189b2012-06-20 16:38:30 -07005493 pConfig->pRSNWPAReqIE[1]+2,
5494 pConfig->pRSNWPAReqIE );
5495
5496 if( VOS_STATUS_SUCCESS == status )
5497 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305498 /* Now copy over all the security attributes you have
5499 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -07005500 * */
5501 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
5502 pConfig->mcRSNEncryptType = mcRSNEncryptType;
5503 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
5504 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05305505 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -08005506 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -07005507 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
5508 }
5509 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305510
Jeff Johnson295189b2012-06-20 16:38:30 -07005511 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE,
5512 pBeacon->tail, pBeacon->tail_len);
5513
5514 if(pIe && pIe[1] && (pIe[0] == DOT11F_EID_WPA))
5515 {
5516 if (pConfig->pRSNWPAReqIE)
5517 {
5518 /*Mixed mode WPA/WPA2*/
5519 memcpy((&wpaRsnIEdata[0] + pConfig->RSNWPAReqIELength), pIe, pIe[1] + 2);
5520 pConfig->RSNWPAReqIELength += pIe[1] + 2;
5521 }
5522 else
5523 {
5524 pConfig->RSNWPAReqIELength = pIe[1] + 2;
5525 memcpy(&wpaRsnIEdata[0], pIe, pConfig->RSNWPAReqIELength);
5526 pConfig->pRSNWPAReqIE = &wpaRsnIEdata[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305527 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -07005528 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
5529 &RSNEncryptType,
5530 &mcRSNEncryptType,
5531 &RSNAuthType,
Chet Lanctot8cecea22014-02-11 19:09:36 -08005532 &MFPCapable,
5533 &MFPRequired,
Jeff Johnson295189b2012-06-20 16:38:30 -07005534 pConfig->pRSNWPAReqIE[1]+2,
5535 pConfig->pRSNWPAReqIE );
5536
5537 if( VOS_STATUS_SUCCESS == status )
5538 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305539 /* Now copy over all the security attributes you have
5540 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -07005541 * */
5542 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
5543 pConfig->mcRSNEncryptType = mcRSNEncryptType;
5544 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
5545 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05305546 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -08005547 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -07005548 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
5549 }
5550 }
5551 }
5552
Jeff Johnson4416a782013-03-25 14:17:50 -07005553 if (pConfig->RSNWPAReqIELength > sizeof wpaRsnIEdata) {
5554 hddLog( VOS_TRACE_LEVEL_ERROR, "**RSNWPAReqIELength is too large***");
5555 return -EINVAL;
5556 }
5557
Jeff Johnson295189b2012-06-20 16:38:30 -07005558 pConfig->SSIDinfo.ssidHidden = VOS_FALSE;
5559
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005560#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07005561 if (params->ssid != NULL)
5562 {
5563 memcpy(pConfig->SSIDinfo.ssid.ssId, params->ssid, params->ssid_len);
5564 pConfig->SSIDinfo.ssid.length = params->ssid_len;
5565 if (params->hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
5566 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
5567 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005568#else
5569 if (ssid != NULL)
5570 {
5571 memcpy(pConfig->SSIDinfo.ssid.ssId, ssid, ssid_len);
5572 pConfig->SSIDinfo.ssid.length = ssid_len;
5573 if (hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
5574 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
5575 }
5576#endif
5577
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305578 vos_mem_copy(pConfig->self_macaddr.bytes,
Jeff Johnson295189b2012-06-20 16:38:30 -07005579 pHostapdAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305580
Jeff Johnson295189b2012-06-20 16:38:30 -07005581 /* default value */
5582 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
5583 pConfig->num_accept_mac = 0;
5584 pConfig->num_deny_mac = 0;
5585
5586 pIe = wlan_hdd_get_vendor_oui_ie_ptr(BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
5587 pBeacon->tail, pBeacon->tail_len);
5588
5589 /* pIe for black list is following form:
5590 type : 1 byte
5591 length : 1 byte
5592 OUI : 4 bytes
5593 acl type : 1 byte
5594 no of mac addr in black list: 1 byte
5595 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305596 */
5597 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07005598 {
5599 pConfig->SapMacaddr_acl = pIe[6];
5600 pConfig->num_deny_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -08005601 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no deny mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07005602 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05305603 if (pConfig->num_deny_mac > MAX_ACL_MAC_ADDRESS)
5604 pConfig->num_deny_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07005605 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
5606 for (i = 0; i < pConfig->num_deny_mac; i++)
5607 {
5608 vos_mem_copy(&pConfig->deny_mac[i], acl_entry->addr, sizeof(qcmacaddr));
5609 acl_entry++;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305610 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005611 }
5612 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
5613 pBeacon->tail, pBeacon->tail_len);
5614
5615 /* pIe for white list is following form:
5616 type : 1 byte
5617 length : 1 byte
5618 OUI : 4 bytes
5619 acl type : 1 byte
5620 no of mac addr in white list: 1 byte
5621 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305622 */
5623 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07005624 {
5625 pConfig->SapMacaddr_acl = pIe[6];
5626 pConfig->num_accept_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -08005627 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no accept mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07005628 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05305629 if (pConfig->num_accept_mac > MAX_ACL_MAC_ADDRESS)
5630 pConfig->num_accept_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07005631 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
5632 for (i = 0; i < pConfig->num_accept_mac; i++)
5633 {
5634 vos_mem_copy(&pConfig->accept_mac[i], acl_entry->addr, sizeof(qcmacaddr));
5635 acl_entry++;
5636 }
5637 }
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05305638
Jeff Johnson295189b2012-06-20 16:38:30 -07005639 wlan_hdd_set_sapHwmode(pHostapdAdapter);
5640
Jeff Johnsone7245742012-09-05 17:12:55 -07005641#ifdef WLAN_FEATURE_11AC
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -08005642 /* Overwrite the hostapd setting for HW mode only for 11ac.
Kiet Lam0f320422013-11-21 19:29:17 +05305643 * This is valid only if mode is set to 11n in hostapd, either AUTO or
5644 * 11ac in .ini and 11ac is supported by both host and firmware.
5645 * Otherwise, leave whatever is set in hostapd (a OR b OR g OR n mode)
5646 */
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -08005647 if( ((pConfig->SapHw_mode == eSAP_DOT11_MODE_11n) ||
5648 (pConfig->SapHw_mode == eSAP_DOT11_MODE_11n_ONLY)) &&
Abhishek Singhf0ac1752014-03-05 17:47:09 +05305649 (( sapDot11Mode == eHDD_DOT11_MODE_AUTO ) ||
5650 ( sapDot11Mode == eHDD_DOT11_MODE_11ac ) ||
5651 ( sapDot11Mode == eHDD_DOT11_MODE_11ac_ONLY ) ) &&
5652 (sme_IsFeatureSupportedByDriver(DOT11AC)) &&
5653 (sme_IsFeatureSupportedByFW(DOT11AC)) )
Jeff Johnsone7245742012-09-05 17:12:55 -07005654 {
Siddharth Bhalf42f8592014-05-15 13:39:07 +05305655 v_U32_t operatingBand = 0;
Jeff Johnsone7245742012-09-05 17:12:55 -07005656 pConfig->SapHw_mode = eSAP_DOT11_MODE_11ac;
Siddharth Bhalf42f8592014-05-15 13:39:07 +05305657 ccmCfgGetInt(hHal, WNI_CFG_SAP_CHANNEL_SELECT_OPERATING_BAND, &operatingBand);
Ravi Joshi83bfaa12013-05-28 22:12:08 -07005658
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05305659 /* If ACS disable and selected channel <= 14
5660 * OR
5661 * ACS enabled and ACS operating band is choosen as 2.4
5662 * AND
5663 * VHT in 2.4G Disabled
5664 * THEN
5665 * Fallback to 11N mode
5666 */
5667 if (((AUTO_CHANNEL_SELECT != pConfig->channel && pConfig->channel <= SIR_11B_CHANNEL_END)
5668 || (AUTO_CHANNEL_SELECT == pConfig->channel &&
Siddharth Bhalf42f8592014-05-15 13:39:07 +05305669 operatingBand == RF_SUBBAND_2_4_GHZ)) &&
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05305670 iniConfig->enableVhtFor24GHzBand == FALSE)
Ravi Joshi83bfaa12013-05-28 22:12:08 -07005671 {
Siddharth Bhalf42f8592014-05-15 13:39:07 +05305672 hddLog(LOGW, FL("Setting hwmode to 11n, operatingBand = %d, Channel = %d"),
5673 operatingBand, pConfig->channel);
Ravi Joshi83bfaa12013-05-28 22:12:08 -07005674 pConfig->SapHw_mode = eSAP_DOT11_MODE_11n;
5675 }
Jeff Johnsone7245742012-09-05 17:12:55 -07005676 }
5677#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305678
Ravi Joshiaeb7d9e2013-05-02 12:28:14 -07005679 if ( AUTO_CHANNEL_SELECT != pConfig->channel )
5680 {
5681 sme_SelectCBMode(hHal,
5682 sapConvertSapPhyModeToCsrPhyMode(pConfig->SapHw_mode),
5683 pConfig->channel);
5684 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005685 // ht_capab is not what the name conveys,this is used for protection bitmap
5686 pConfig->ht_capab =
5687 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtection;
5688
5689 if ( 0 != wlan_hdd_cfg80211_update_apies(pHostapdAdapter, params) )
5690 {
5691 hddLog(LOGE, FL("SAP Not able to set AP IEs"));
5692 return -EINVAL;
5693 }
5694
5695 //Uapsd Enabled Bit
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305696 pConfig->UapsdEnable =
Jeff Johnson295189b2012-06-20 16:38:30 -07005697 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apUapsdEnabled;
5698 //Enable OBSS protection
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305699 pConfig->obssProtEnabled =
5700 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apOBSSProtEnabled;
Jeff Johnson295189b2012-06-20 16:38:30 -07005701
Chet Lanctot8cecea22014-02-11 19:09:36 -08005702#ifdef WLAN_FEATURE_11W
5703 pConfig->mfpCapable = MFPCapable;
5704 pConfig->mfpRequired = MFPRequired;
5705 hddLog(LOGW, FL("Soft AP MFP capable %d, MFP required %d\n"),
5706 pConfig->mfpCapable, pConfig->mfpRequired);
5707#endif
5708
Arif Hussain6d2a3322013-11-17 19:50:10 -08005709 hddLog(LOGW, FL("SOftAP macaddress : "MAC_ADDRESS_STR),
Jeff Johnson295189b2012-06-20 16:38:30 -07005710 MAC_ADDR_ARRAY(pHostapdAdapter->macAddressCurrent.bytes));
Arif Hussain6d2a3322013-11-17 19:50:10 -08005711 hddLog(LOGW,FL("ssid =%s, beaconint=%d, channel=%d"),
5712 pConfig->SSIDinfo.ssid.ssId, (int)pConfig->beacon_int,
5713 (int)pConfig->channel);
5714 hddLog(LOGW,FL("hw_mode=%x, privacy=%d, authType=%d"),
5715 pConfig->SapHw_mode, pConfig->privacy,
5716 pConfig->authType);
5717 hddLog(LOGW,FL("RSN/WPALen=%d, Uapsd = %d"),
5718 (int)pConfig->RSNWPAReqIELength, pConfig->UapsdEnable);
5719 hddLog(LOGW,FL("ProtEnabled = %d, OBSSProtEnabled = %d"),
5720 pConfig->protEnabled, pConfig->obssProtEnabled);
Jeff Johnson295189b2012-06-20 16:38:30 -07005721
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305722 if(test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -07005723 {
5724 //Bss already started. just return.
5725 //TODO Probably it should update some beacon params.
5726 hddLog( LOGE, "Bss Already started...Ignore the request");
5727 EXIT();
5728 return 0;
5729 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305730
Agarwal Ashish51325b52014-06-16 16:50:49 +05305731 if (vos_max_concurrent_connections_reached()) {
5732 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
5733 return -EINVAL;
5734 }
5735
Jeff Johnson295189b2012-06-20 16:38:30 -07005736 pConfig->persona = pHostapdAdapter->device_mode;
5737
5738 pSapEventCallback = hdd_hostapd_SAPEventCB;
5739 if(WLANSAP_StartBss(pVosContext, pSapEventCallback, pConfig,
5740 (v_PVOID_t)pHostapdAdapter->dev) != VOS_STATUS_SUCCESS)
5741 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08005742 hddLog(LOGE,FL("SAP Start Bss fail"));
Jeff Johnson295189b2012-06-20 16:38:30 -07005743 return -EINVAL;
5744 }
5745
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305746 hddLog(LOG1,
Jeff Johnson295189b2012-06-20 16:38:30 -07005747 FL("Waiting for Scan to complete(auto mode) and BSS to start"));
5748
5749 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305750
Jeff Johnson295189b2012-06-20 16:38:30 -07005751 if (!VOS_IS_STATUS_SUCCESS(status))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305752 {
5753 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08005754 ("ERROR: HDD vos wait for single_event failed!!"));
Tushnim Bhattacharyyaad37df12013-10-02 12:01:33 -07005755 smeGetCommandQStatus(hHal);
Jeff Johnson295189b2012-06-20 16:38:30 -07005756 VOS_ASSERT(0);
5757 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305758
Jeff Johnson295189b2012-06-20 16:38:30 -07005759 set_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags);
Agarwal Ashish51325b52014-06-16 16:50:49 +05305760 wlan_hdd_incr_active_session(pHddCtx, pHostapdAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07005761
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07005762#ifdef WLAN_FEATURE_P2P_DEBUG
5763 if (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO)
5764 {
5765 if(globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED)
5766 {
5767 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
5768 hddLog(LOGE,"[P2P State] From Go nego completed to "
Jeff Johnson1250df42012-12-10 14:31:52 -08005769 "Non-autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07005770 }
5771 else if(globalP2PConnectionStatus == P2P_NOT_ACTIVE)
5772 {
5773 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
5774 hddLog(LOGE,"[P2P State] From Inactive to "
Jeff Johnson1250df42012-12-10 14:31:52 -08005775 "Autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07005776 }
5777 }
5778#endif
5779
Jeff Johnson295189b2012-06-20 16:38:30 -07005780 pHostapdState->bCommit = TRUE;
5781 EXIT();
5782
5783 return 0;
5784}
5785
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005786#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305787static int wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy,
5788 struct net_device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -07005789 struct beacon_parameters *params)
5790{
5791 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05305792 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305793 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07005794
5795 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05305796
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05305797 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
5798 TRACE_CODE_HDD_CFG80211_ADD_BEACON,
5799 pAdapter->sessionId, params->interval));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05305800 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "device mode=%s (%d)",
5801 hdd_device_modetoString(pAdapter->device_mode),
5802 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07005803
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305804 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
5805 status = wlan_hdd_validate_context(pHddCtx);
5806
5807 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005808 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305809 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5810 "%s: HDD context is not valid", __func__);
5811 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005812 }
5813
Agarwal Ashish51325b52014-06-16 16:50:49 +05305814 if (vos_max_concurrent_connections_reached()) {
5815 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
5816 return -EINVAL;
5817 }
5818
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305819 if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07005820 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07005821 )
5822 {
5823 beacon_data_t *old,*new;
5824
5825 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305826
Jeff Johnson295189b2012-06-20 16:38:30 -07005827 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305828 {
5829 hddLog(VOS_TRACE_LEVEL_WARN,
5830 FL("already beacon info added to session(%d)"),
5831 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07005832 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305833 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005834
5835 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
5836
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305837 if(status != VOS_STATUS_SUCCESS)
Jeff Johnson295189b2012-06-20 16:38:30 -07005838 {
5839 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08005840 "%s:Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005841 return -EINVAL;
5842 }
5843
5844 pAdapter->sessionCtx.ap.beacon = new;
5845
5846 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
5847 }
5848
5849 EXIT();
5850 return status;
5851}
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305852
5853static int wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07005854 struct net_device *dev,
5855 struct beacon_parameters *params)
5856{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305857 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05305858 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
5859 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305860 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07005861
5862 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05305863 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
5864 TRACE_CODE_HDD_CFG80211_SET_BEACON,
5865 pAdapter->sessionId, pHddStaCtx->conn_info.authType));
5866 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
5867 __func__, hdd_device_modetoString(pAdapter->device_mode),
5868 pAdapter->device_mode);
5869
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305870 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
5871 status = wlan_hdd_validate_context(pHddCtx);
5872
5873 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005874 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305875 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5876 "%s: HDD context is not valid", __func__);
5877 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005878 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05305879
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305880 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07005881 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305882 )
Jeff Johnson295189b2012-06-20 16:38:30 -07005883 {
5884 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305885
Jeff Johnson295189b2012-06-20 16:38:30 -07005886 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305887
Jeff Johnson295189b2012-06-20 16:38:30 -07005888 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305889 {
5890 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5891 FL("session(%d) old and new heads points to NULL"),
5892 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07005893 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305894 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005895
5896 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
5897
5898 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305899 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08005900 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005901 return -EINVAL;
5902 }
5903
5904 pAdapter->sessionCtx.ap.beacon = new;
5905
5906 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
5907 }
5908
5909 EXIT();
5910 return status;
5911}
5912
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005913#endif //(LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
5914
5915#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07005916static int wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy,
5917 struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005918#else
5919static int wlan_hdd_cfg80211_stop_ap (struct wiphy *wiphy,
5920 struct net_device *dev)
5921#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005922{
5923 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnsone7245742012-09-05 17:12:55 -07005924 hdd_context_t *pHddCtx = NULL;
5925 hdd_scaninfo_t *pScanInfo = NULL;
5926 hdd_adapter_t *staAdapter = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305927 VOS_STATUS status;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05305928 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07005929
5930 ENTER();
5931
5932 if (NULL == pAdapter)
5933 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05305934 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005935 "%s: HDD adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005936 return -ENODEV;
5937 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07005938
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05305939 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
5940 TRACE_CODE_HDD_CFG80211_STOP_AP,
5941 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305942 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
5943 status = wlan_hdd_validate_context(pHddCtx);
5944
5945 if (0 != status)
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07005946 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305947 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5948 "%s: HDD context is not valid", __func__);
5949 return status;
Jeff Johnson4416a782013-03-25 14:17:50 -07005950 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07005951
5952 staAdapter = hdd_get_adapter(pAdapter->pHddCtx, WLAN_HDD_INFRA_STATION);
5953 if (NULL == staAdapter)
5954 {
5955 staAdapter = hdd_get_adapter(pAdapter->pHddCtx, WLAN_HDD_P2P_CLIENT);
5956 if (NULL == staAdapter)
5957 {
Rajesh Chauhan52d885b2013-11-01 10:54:25 -07005958 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
5959 "%s: HDD adapter context for STA/P2P-CLI is Null",
5960 __func__);
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07005961 }
5962 }
5963
5964 pScanInfo = &pHddCtx->scan_info;
5965
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05305966 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
5967 __func__, hdd_device_modetoString(pAdapter->device_mode),
5968 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07005969
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05305970 ret = wlan_hdd_scan_abort(pAdapter);
5971
Girish Gowli4bf7a632014-06-12 13:42:11 +05305972 if (ret < 0)
Jeff Johnsone7245742012-09-05 17:12:55 -07005973 {
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05305974 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5975 FL("Timeout occurred while waiting for abortscan %ld"), ret);
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305976
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05305977 if (pHddCtx->isLogpInProgress)
Jeff Johnsone7245742012-09-05 17:12:55 -07005978 {
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05305979 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5980 "%s: LOGP in Progress. Ignore!!!", __func__);
Yue Ma4f55ef32014-01-23 16:45:33 -08005981
Jeff Johnsone7245742012-09-05 17:12:55 -07005982 VOS_ASSERT(pScanInfo->mScanPending);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05305983 return -EAGAIN;
Jeff Johnsone7245742012-09-05 17:12:55 -07005984 }
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05305985 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -07005986 }
5987
Arun Kumar Khandavallia3bd8002014-01-17 16:21:19 +05305988 hdd_hostapd_stop(dev);
5989
Jeff Johnson295189b2012-06-20 16:38:30 -07005990 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07005991 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07005992 )
5993 {
5994 beacon_data_t *old;
5995
5996 old = pAdapter->sessionCtx.ap.beacon;
5997
5998 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305999 {
6000 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6001 FL("session(%d) beacon data points to NULL"),
6002 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07006003 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306004 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006005
Jeff Johnson295189b2012-06-20 16:38:30 -07006006 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07006007
6008 mutex_lock(&pHddCtx->sap_lock);
6009 if(test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
6010 {
Jeff Johnson4416a782013-03-25 14:17:50 -07006011 if ( VOS_STATUS_SUCCESS == (status = WLANSAP_StopBss(pHddCtx->pvosContext) ) )
Jeff Johnson295189b2012-06-20 16:38:30 -07006012 {
6013 hdd_hostapd_state_t *pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
6014
6015 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
6016
6017 if (!VOS_IS_STATUS_SUCCESS(status))
6018 {
6019 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006020 ("ERROR: HDD vos wait for single_event failed!!"));
Jeff Johnson295189b2012-06-20 16:38:30 -07006021 VOS_ASSERT(0);
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05306022 }
6023 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006024 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
Agarwal Ashish51325b52014-06-16 16:50:49 +05306025 /* BSS stopped, clear the active sessions for this device mode */
6026 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07006027 }
6028 mutex_unlock(&pHddCtx->sap_lock);
6029
6030 if(status != VOS_STATUS_SUCCESS)
6031 {
6032 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006033 "%s:Error!!! Stopping the BSS",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006034 return -EINVAL;
6035 }
6036
Jeff Johnson4416a782013-03-25 14:17:50 -07006037 if (ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -07006038 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 0,NULL, eANI_BOOLEAN_FALSE)
6039 ==eHAL_STATUS_FAILURE)
6040 {
6041 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006042 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07006043 }
6044
Jeff Johnson4416a782013-03-25 14:17:50 -07006045 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -07006046 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
6047 eANI_BOOLEAN_FALSE) )
6048 {
6049 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006050 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07006051 }
6052
6053 // Reset WNI_CFG_PROBE_RSP Flags
6054 wlan_hdd_reset_prob_rspies(pAdapter);
6055
6056 pAdapter->sessionCtx.ap.beacon = NULL;
6057 kfree(old);
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07006058#ifdef WLAN_FEATURE_P2P_DEBUG
6059 if((pAdapter->device_mode == WLAN_HDD_P2P_GO) &&
6060 (globalP2PConnectionStatus == P2P_GO_COMPLETED_STATE))
6061 {
6062 hddLog(LOGE,"[P2P State] From GO completed to Inactive state "
6063 "GO got removed");
6064 globalP2PConnectionStatus = P2P_NOT_ACTIVE;
6065 }
6066#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006067 }
6068 EXIT();
6069 return status;
6070}
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006071
6072#if (LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
6073
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306074static int wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
6075 struct net_device *dev,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006076 struct cfg80211_ap_settings *params)
6077{
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306078 hdd_adapter_t *pAdapter;
6079 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306080 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006081
6082 ENTER();
6083
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306084 if (NULL == dev)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07006085 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306086 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306087 "%s: Device is Null", __func__);
6088 return -ENODEV;
6089 }
6090
6091 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6092 if (NULL == pAdapter)
6093 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306094 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306095 "%s: HDD adapter is Null", __func__);
6096 return -ENODEV;
6097 }
6098
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05306099 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
6100 TRACE_CODE_HDD_CFG80211_START_AP, pAdapter->sessionId,
6101 params-> beacon_interval));
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306102 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
6103 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306104 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306105 "%s: HDD adapter magic is invalid", __func__);
6106 return -ENODEV;
6107 }
6108
6109 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306110 status = wlan_hdd_validate_context(pHddCtx);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306111
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306112 if (0 != status)
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306113 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306114 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6115 "%s: HDD context is not valid", __func__);
6116 return status;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306117 }
6118
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05306119 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device mode = %s (%d)",
6120 __func__, hdd_device_modetoString(pAdapter->device_mode),
6121 pAdapter->device_mode);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306122
6123 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006124 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006125 )
6126 {
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306127 beacon_data_t *old, *new;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006128
6129 old = pAdapter->sessionCtx.ap.beacon;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306130
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006131 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306132 {
6133 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
6134 FL("already beacon info added to session(%d)"),
6135 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006136 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306137 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006138
6139 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter, &new, &params->beacon, params->dtim_period);
6140
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306141 if (status != 0)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006142 {
6143 hddLog(VOS_TRACE_LEVEL_FATAL,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05306144 "%s:Error!!! Allocating the new beacon", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006145 return -EINVAL;
6146 }
6147 pAdapter->sessionCtx.ap.beacon = new;
Viral Modi3a32cc52013-02-08 11:14:52 -08006148#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
Yue Maf49ba872013-08-19 12:04:25 -07006149 wlan_hdd_cfg80211_set_channel(wiphy, dev,
6150#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
6151 params->channel, params->channel_type);
6152#else
6153 params->chandef.chan, cfg80211_get_chandef_type(&(params->chandef)));
6154#endif
Viral Modi3a32cc52013-02-08 11:14:52 -08006155#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006156 status = wlan_hdd_cfg80211_start_bss(pAdapter, &params->beacon, params->ssid,
6157 params->ssid_len, params->hidden_ssid);
6158 }
6159
6160 EXIT();
6161 return status;
6162}
6163
6164
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306165static int wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006166 struct net_device *dev,
6167 struct cfg80211_beacon_data *params)
6168{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306169 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05306170 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306171 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006172
6173 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05306174
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05306175 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
6176 TRACE_CODE_HDD_CFG80211_CHANGE_BEACON,
6177 pAdapter->sessionId, pAdapter->device_mode));
Arif Hussain6d2a3322013-11-17 19:50:10 -08006178 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006179 __func__, pAdapter->device_mode);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306180
6181 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
6182 status = wlan_hdd_validate_context(pHddCtx);
6183
6184 if (0 != status)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07006185 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306186 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6187 "%s: HDD context is not valid", __func__);
6188 return status;
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07006189 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006190
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306191 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006192 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306193 )
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006194 {
6195 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306196
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006197 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306198
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006199 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306200 {
6201 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6202 FL("session(%d) beacon data points to NULL"),
6203 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006204 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306205 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006206
6207 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter, &new, params, 0);
6208
6209 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306210 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006211 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006212 return -EINVAL;
6213 }
6214
6215 pAdapter->sessionCtx.ap.beacon = new;
6216
6217 status = wlan_hdd_cfg80211_start_bss(pAdapter, params, NULL, 0, 0);
6218 }
6219
6220 EXIT();
6221 return status;
6222}
6223
6224#endif //(LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
6225
Jeff Johnson295189b2012-06-20 16:38:30 -07006226
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +05306227static int __wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07006228 struct net_device *dev,
6229 struct bss_parameters *params)
6230{
6231 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6232
6233 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05306234
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05306235 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
6236 TRACE_CODE_HDD_CFG80211_CHANGE_BSS,
6237 pAdapter->sessionId, params->ap_isolate));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05306238 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
6239 __func__, hdd_device_modetoString(pAdapter->device_mode),
6240 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07006241
6242 if((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07006243 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306244 )
Jeff Johnson295189b2012-06-20 16:38:30 -07006245 {
6246 /* ap_isolate == -1 means that in change bss, upper layer doesn't
6247 * want to update this parameter */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306248 if (-1 != params->ap_isolate)
Jeff Johnson295189b2012-06-20 16:38:30 -07006249 {
6250 pAdapter->sessionCtx.ap.apDisableIntraBssFwd = !!params->ap_isolate;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306251 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006252 }
6253
6254 EXIT();
6255 return 0;
6256}
6257
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +05306258static int wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
6259 struct net_device *dev,
6260 struct bss_parameters *params)
6261{
6262 int ret;
6263
6264 vos_ssr_protect(__func__);
6265 ret = __wlan_hdd_cfg80211_change_bss(wiphy, dev, params);
6266 vos_ssr_unprotect(__func__);
6267
6268 return ret;
6269}
Kiet Lam10841362013-11-01 11:36:50 +05306270/* FUNCTION: wlan_hdd_change_country_code_cd
6271* to wait for contry code completion
6272*/
6273void* wlan_hdd_change_country_code_cb(void *pAdapter)
6274{
6275 hdd_adapter_t *call_back_pAdapter = pAdapter;
6276 complete(&call_back_pAdapter->change_country_code);
6277 return NULL;
6278}
6279
Jeff Johnson295189b2012-06-20 16:38:30 -07006280/*
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +05306281 * FUNCTION: __wlan_hdd_cfg80211_change_iface
Jeff Johnson295189b2012-06-20 16:38:30 -07006282 * This function is used to set the interface type (INFRASTRUCTURE/ADHOC)
6283 */
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +05306284int __wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07006285 struct net_device *ndev,
6286 enum nl80211_iftype type,
6287 u32 *flags,
6288 struct vif_params *params
6289 )
6290{
6291 struct wireless_dev *wdev;
6292 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Rajesh Chauhana0516c62014-01-30 16:11:18 -08006293 hdd_context_t *pHddCtx;
Mohit Khanna0f232092012-09-11 14:46:08 -07006294 hdd_adapter_t *pP2pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07006295 tCsrRoamProfile *pRoamProfile = NULL;
6296 eCsrRoamBssType LastBSSType;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306297 hdd_config_t *pConfig = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07006298 eMib_dot11DesiredBssType connectedBssType;
6299 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306300 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07006301
6302 ENTER();
6303
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05306304 if (!pAdapter)
Rajesh Chauhana0516c62014-01-30 16:11:18 -08006305 {
6306 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6307 "%s: Adapter context is null", __func__);
6308 return VOS_STATUS_E_FAILURE;
6309 }
6310
6311 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
6312 if (!pHddCtx)
6313 {
6314 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6315 "%s: HDD context is null", __func__);
6316 return VOS_STATUS_E_FAILURE;
6317 }
6318
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05306319 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
6320 TRACE_CODE_HDD_CFG80211_CHANGE_IFACE,
6321 pAdapter->sessionId, type));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306322 status = wlan_hdd_validate_context(pHddCtx);
6323
6324 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -07006325 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306326 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6327 "%s: HDD context is not valid", __func__);
6328 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -07006329 }
6330
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05306331 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
6332 __func__, hdd_device_modetoString(pAdapter->device_mode),
6333 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07006334
Agarwal Ashish51325b52014-06-16 16:50:49 +05306335 if (vos_max_concurrent_connections_reached()) {
6336 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
6337 return -EINVAL;
6338 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306339 pConfig = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -07006340 wdev = ndev->ieee80211_ptr;
6341
6342#ifdef WLAN_BTAMP_FEATURE
6343 if((NL80211_IFTYPE_P2P_CLIENT == type)||
6344 (NL80211_IFTYPE_ADHOC == type)||
6345 (NL80211_IFTYPE_AP == type)||
6346 (NL80211_IFTYPE_P2P_GO == type))
6347 {
6348 pHddCtx->isAmpAllowed = VOS_FALSE;
6349 // stop AMP traffic
6350 status = WLANBAP_StopAmp();
6351 if(VOS_STATUS_SUCCESS != status )
6352 {
6353 pHddCtx->isAmpAllowed = VOS_TRUE;
6354 hddLog(VOS_TRACE_LEVEL_FATAL,
6355 "%s: Failed to stop AMP", __func__);
6356 return -EINVAL;
6357 }
6358 }
6359#endif //WLAN_BTAMP_FEATURE
6360 /* Reset the current device mode bit mask*/
6361 wlan_hdd_clear_concurrency_mode(pHddCtx, pAdapter->device_mode);
6362
6363 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -07006364 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnsone7245742012-09-05 17:12:55 -07006365 || (pAdapter->device_mode == WLAN_HDD_P2P_DEVICE)
Jeff Johnson295189b2012-06-20 16:38:30 -07006366 )
6367 {
6368 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -08006369 if (!pWextState)
6370 {
6371 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6372 "%s: pWextState is null", __func__);
6373 return VOS_STATUS_E_FAILURE;
6374 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006375 pRoamProfile = &pWextState->roamProfile;
6376 LastBSSType = pRoamProfile->BSSType;
6377
6378 switch (type)
6379 {
6380 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -07006381 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -07006382 hddLog(VOS_TRACE_LEVEL_INFO,
6383 "%s: setting interface Type to INFRASTRUCTURE", __func__);
6384 pRoamProfile->BSSType = eCSR_BSS_TYPE_INFRASTRUCTURE;
Jeff Johnsone7245742012-09-05 17:12:55 -07006385#ifdef WLAN_FEATURE_11AC
6386 if(pConfig->dot11Mode == eHDD_DOT11_MODE_AUTO)
6387 {
6388 pConfig->dot11Mode = eHDD_DOT11_MODE_11ac;
6389 }
6390#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306391 pRoamProfile->phyMode =
Jeff Johnsone7245742012-09-05 17:12:55 -07006392 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07006393 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08006394 //Check for sub-string p2p to confirm its a p2p interface
6395 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306396 {
Gopichand Nakkala864d3552012-12-31 16:08:51 -08006397 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
6398 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
6399 }
6400 else
6401 {
6402 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -07006403 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -08006404 }
Madan Mohan Koyyalamudi81746922013-07-17 14:38:51 +05306405#ifdef FEATURE_WLAN_TDLS
6406 /* The open adapter for the p2p shall skip initializations in
6407 * tdls_init if the device mode is WLAN_HDD_P2P_DEVICE, for
6408 * TDLS is supported only on WLAN_HDD_P2P_CLIENT. Hence invoke
6409 * tdls_init when the change_iface sets the device mode to
6410 * WLAN_HDD_P2P_CLIENT.
6411 */
6412
6413 if ( pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
6414 {
Agarwal Ashish4b87f922014-06-18 03:03:21 +05306415 if (0 != wlan_hdd_sta_tdls_init (pAdapter))
Madan Mohan Koyyalamudi81746922013-07-17 14:38:51 +05306416 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306417 hddLog(VOS_TRACE_LEVEL_ERROR,
6418 "%s: tdls initialization failed", __func__);
Madan Mohan Koyyalamudi81746922013-07-17 14:38:51 +05306419 return -EINVAL;
6420 }
6421 }
6422#endif
6423
Jeff Johnson295189b2012-06-20 16:38:30 -07006424 break;
6425 case NL80211_IFTYPE_ADHOC:
6426 hddLog(VOS_TRACE_LEVEL_INFO,
6427 "%s: setting interface Type to ADHOC", __func__);
6428 pRoamProfile->BSSType = eCSR_BSS_TYPE_START_IBSS;
6429 pRoamProfile->phyMode =
6430 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Shailender Karmuchia734f332013-04-19 14:02:48 -07006431 pAdapter->device_mode = WLAN_HDD_IBSS;
Jeff Johnson295189b2012-06-20 16:38:30 -07006432 wdev->iftype = type;
6433 break;
6434
6435 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -07006436 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07006437 {
6438 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
6439 "%s: setting interface Type to %s", __func__,
6440 (type == NL80211_IFTYPE_AP) ? "SoftAP" : "P2pGo");
6441
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08006442 //Cancel any remain on channel for GO mode
6443 if (NL80211_IFTYPE_P2P_GO == type)
6444 {
6445 wlan_hdd_cancel_existing_remain_on_channel(pAdapter);
6446 }
Mohit Khanna0f232092012-09-11 14:46:08 -07006447 if (NL80211_IFTYPE_AP == type)
6448 {
6449 /* As Loading WLAN Driver one interface being created for p2p device
6450 * address. This will take one HW STA and the max number of clients
6451 * that can connect to softAP will be reduced by one. so while changing
6452 * the interface type to NL80211_IFTYPE_AP (SoftAP) remove p2p0
6453 * interface as it is not required in SoftAP mode.
6454 */
6455
6456 // Get P2P Adapter
6457 pP2pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_DEVICE);
6458
6459 if (pP2pAdapter)
6460 {
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05306461 hdd_stop_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
Mohit Khanna0f232092012-09-11 14:46:08 -07006462 hdd_deinit_adapter(pHddCtx, pP2pAdapter);
6463 hdd_close_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
6464 }
6465 }
Swaroop Goltia2e32212014-04-09 23:37:33 +05306466 //Disable IMPS & BMPS for SAP/GO
6467 if(VOS_STATUS_E_FAILURE ==
6468 hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_P2P_GO))
6469 {
6470 //Fail to Exit BMPS
6471 VOS_ASSERT(0);
6472 }
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306473#ifdef FEATURE_WLAN_TDLS
Mohit Khanna0f232092012-09-11 14:46:08 -07006474
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306475 /* A Mutex Lock is introduced while changing the mode to
6476 * protect the concurrent access for the Adapters by TDLS
6477 * module.
6478 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05306479 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306480#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006481 //De-init the adapter.
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05306482 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
Jeff Johnson295189b2012-06-20 16:38:30 -07006483 hdd_deinit_adapter( pHddCtx, pAdapter );
6484 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
Jeff Johnson295189b2012-06-20 16:38:30 -07006485 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
6486 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306487#ifdef FEATURE_WLAN_TDLS
6488 mutex_unlock(&pHddCtx->tdls_lock);
6489#endif
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -07006490 if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) &&
6491 (pConfig->apRandomBssidEnabled))
6492 {
6493 /* To meet Android requirements create a randomized
6494 MAC address of the form 02:1A:11:Fx:xx:xx */
6495 get_random_bytes(&ndev->dev_addr[3], 3);
6496 ndev->dev_addr[0] = 0x02;
6497 ndev->dev_addr[1] = 0x1A;
6498 ndev->dev_addr[2] = 0x11;
6499 ndev->dev_addr[3] |= 0xF0;
6500 memcpy(pAdapter->macAddressCurrent.bytes, ndev->dev_addr,
6501 VOS_MAC_ADDR_SIZE);
Arif Hussain24bafea2013-11-15 15:10:03 -08006502 pr_info("wlan: Generated HotSpot BSSID " MAC_ADDRESS_STR"\n",
6503 MAC_ADDR_ARRAY(ndev->dev_addr));
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -07006504 }
6505
Jeff Johnson295189b2012-06-20 16:38:30 -07006506 hdd_set_ap_ops( pAdapter->dev );
6507
Kiet Lam10841362013-11-01 11:36:50 +05306508 /* This is for only SAP mode where users can
6509 * control country through ini.
6510 * P2P GO follows station country code
6511 * acquired during the STA scanning. */
6512 if((NL80211_IFTYPE_AP == type) &&
6513 (memcmp(pConfig->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0))
6514 {
6515 int status = 0;
6516 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_INFO,
6517 "%s: setting country code from INI ", __func__);
6518 init_completion(&pAdapter->change_country_code);
6519 status = (int)sme_ChangeCountryCode(pHddCtx->hHal,
6520 (void *)(tSmeChangeCountryCallback)
6521 wlan_hdd_change_country_code_cb,
6522 pConfig->apCntryCode, pAdapter,
6523 pHddCtx->pvosContext,
Abhishek Singha306a442013-11-07 18:39:01 +05306524 eSIR_FALSE,
6525 eSIR_TRUE);
Kiet Lam10841362013-11-01 11:36:50 +05306526 if (eHAL_STATUS_SUCCESS == status)
6527 {
6528 /* Wait for completion */
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306529 ret = wait_for_completion_interruptible_timeout(
Kiet Lam10841362013-11-01 11:36:50 +05306530 &pAdapter->change_country_code,
6531 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306532 if (ret <= 0)
Kiet Lam10841362013-11-01 11:36:50 +05306533 {
6534 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306535 FL("SME Timed out while setting country code %ld"),
6536 ret);
Yue Ma4f55ef32014-01-23 16:45:33 -08006537
6538 if (pHddCtx->isLogpInProgress)
6539 {
6540 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6541 "%s: LOGP in Progress. Ignore!!!", __func__);
6542 return -EAGAIN;
6543 }
Kiet Lam10841362013-11-01 11:36:50 +05306544 }
6545 }
6546 else
6547 {
6548 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006549 "%s: SME Change Country code failed",__func__);
Kiet Lam10841362013-11-01 11:36:50 +05306550 return -EINVAL;
6551 }
6552 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006553 status = hdd_init_ap_mode(pAdapter);
6554 if(status != VOS_STATUS_SUCCESS)
6555 {
6556 hddLog(VOS_TRACE_LEVEL_FATAL,
6557 "%s: Error initializing the ap mode", __func__);
6558 return -EINVAL;
6559 }
6560 hdd_set_conparam(1);
6561
Jeff Johnson295189b2012-06-20 16:38:30 -07006562 /*interface type changed update in wiphy structure*/
6563 if(wdev)
6564 {
6565 wdev->iftype = type;
6566 pHddCtx->change_iface = type;
6567 }
6568 else
6569 {
6570 hddLog(VOS_TRACE_LEVEL_ERROR,
6571 "%s: ERROR !!!! Wireless dev is NULL", __func__);
6572 return -EINVAL;
6573 }
6574 goto done;
6575 }
6576
6577 default:
6578 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
6579 __func__);
6580 return -EOPNOTSUPP;
6581 }
6582 }
6583 else if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07006584 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07006585 )
6586 {
6587 switch(type)
6588 {
6589 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -07006590 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -07006591 case NL80211_IFTYPE_ADHOC:
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306592#ifdef FEATURE_WLAN_TDLS
6593
6594 /* A Mutex Lock is introduced while changing the mode to
6595 * protect the concurrent access for the Adapters by TDLS
6596 * module.
6597 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05306598 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306599#endif
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05306600 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
Jeff Johnson32d95a32012-09-10 13:15:23 -07006601 hdd_deinit_adapter( pHddCtx, pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07006602 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08006603 //Check for sub-string p2p to confirm its a p2p interface
6604 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala864d3552012-12-31 16:08:51 -08006605 {
6606 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
6607 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
6608 }
6609 else
6610 {
6611 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -07006612 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -08006613 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006614 hdd_set_conparam(0);
6615 pHddCtx->change_iface = type;
Jeff Johnson295189b2012-06-20 16:38:30 -07006616 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
6617 hdd_set_station_ops( pAdapter->dev );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306618#ifdef FEATURE_WLAN_TDLS
6619 mutex_unlock(&pHddCtx->tdls_lock);
6620#endif
Sunil Dutt66485cb2013-12-19 19:05:03 +05306621 status = hdd_init_station_mode( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07006622 if( VOS_STATUS_SUCCESS != status )
6623 return -EOPNOTSUPP;
Jeff Johnsone7245742012-09-05 17:12:55 -07006624 /* In case of JB, for P2P-GO, only change interface will be called,
6625 * This is the right place to enable back bmps_imps()
6626 */
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306627 if (pHddCtx->hdd_wlan_suspended)
6628 {
6629 hdd_set_pwrparams(pHddCtx);
6630 }
Jeff Johnsone7245742012-09-05 17:12:55 -07006631 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07006632 goto done;
6633 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -07006634 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07006635 wdev->iftype = type;
Jeff Johnson295189b2012-06-20 16:38:30 -07006636 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
6637 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Jeff Johnson295189b2012-06-20 16:38:30 -07006638 goto done;
6639 default:
6640 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
6641 __func__);
6642 return -EOPNOTSUPP;
6643
6644 }
6645
6646 }
6647 else
6648 {
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05306649 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: unsupported device mode(%s (%d))",
6650 __func__, hdd_device_modetoString(pAdapter->device_mode),
6651 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07006652 return -EOPNOTSUPP;
6653 }
6654
6655
6656 if(pRoamProfile)
6657 {
6658 if ( LastBSSType != pRoamProfile->BSSType )
6659 {
6660 /*interface type changed update in wiphy structure*/
6661 wdev->iftype = type;
6662
6663 /*the BSS mode changed, We need to issue disconnect
6664 if connected or in IBSS disconnect state*/
6665 if ( hdd_connGetConnectedBssType(
6666 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), &connectedBssType ) ||
6667 ( eCSR_BSS_TYPE_START_IBSS == LastBSSType ) )
6668 {
6669 /*need to issue a disconnect to CSR.*/
6670 INIT_COMPLETION(pAdapter->disconnect_comp_var);
6671 if( eHAL_STATUS_SUCCESS ==
6672 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
6673 pAdapter->sessionId,
6674 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
6675 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306676 ret = wait_for_completion_interruptible_timeout(
6677 &pAdapter->disconnect_comp_var,
6678 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
6679 if (ret <= 0)
6680 {
6681 hddLog(VOS_TRACE_LEVEL_ERROR,
6682 FL("wait on disconnect_comp_var failed %ld"), ret);
6683 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006684 }
6685 }
6686 }
6687 }
6688
6689done:
6690 /*set bitmask based on updated value*/
6691 wlan_hdd_set_concurrency_mode(pHddCtx, pAdapter->device_mode);
Leo Chang6fe1f922013-06-07 19:21:24 -07006692
6693 /* Only STA mode support TM now
6694 * all other mode, TM feature should be disabled */
6695 if ( (pHddCtx->cfg_ini->thermalMitigationEnable) &&
6696 (~VOS_STA & pHddCtx->concurrency_mode) )
6697 {
6698 hddDevTmLevelChangedHandler(pHddCtx->parent_dev, 0);
6699 }
6700
Jeff Johnson295189b2012-06-20 16:38:30 -07006701#ifdef WLAN_BTAMP_FEATURE
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306702 if((NL80211_IFTYPE_STATION == type) && (pHddCtx->concurrency_mode <= 1) &&
Agarwal Ashish51325b52014-06-16 16:50:49 +05306703 (pHddCtx->no_of_open_sessions[WLAN_HDD_INFRA_STATION] <=1))
Jeff Johnson295189b2012-06-20 16:38:30 -07006704 {
6705 //we are ok to do AMP
6706 pHddCtx->isAmpAllowed = VOS_TRUE;
6707 }
6708#endif //WLAN_BTAMP_FEATURE
6709 EXIT();
6710 return 0;
6711}
6712
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +05306713/*
6714 * FUNCTION: wlan_hdd_cfg80211_change_iface
6715 * wrapper function to protect the actual implementation from SSR.
6716 */
6717int wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
6718 struct net_device *ndev,
6719 enum nl80211_iftype type,
6720 u32 *flags,
6721 struct vif_params *params
6722 )
6723{
6724 int ret;
6725
6726 vos_ssr_protect(__func__);
6727 ret = __wlan_hdd_cfg80211_change_iface(wiphy, ndev, type, flags, params);
6728 vos_ssr_unprotect(__func__);
6729
6730 return ret;
6731}
6732
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006733#ifdef FEATURE_WLAN_TDLS
6734static int wlan_hdd_tdls_add_station(struct wiphy *wiphy,
6735 struct net_device *dev, u8 *mac, bool update, tCsrStaParams *StaParams)
6736{
6737 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6738 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
6739 VOS_STATUS status;
Hoonki Lee5305c3a2013-04-29 23:28:59 -07006740 hddTdlsPeer_t *pTdlsPeer;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306741 long ret;
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05306742 tANI_U16 numCurrTdlsPeers;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006743
6744 ENTER();
6745
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05306746 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006747 {
6748 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6749 "Invalid arguments");
6750 return -EINVAL;
6751 }
Hoonki Lee27511902013-03-14 18:19:06 -07006752
6753 if ((eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode) ||
6754 (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode))
6755 {
6756 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
6757 "%s: TDLS mode is disabled OR not enabled in FW."
6758 MAC_ADDRESS_STR " Request declined.",
6759 __func__, MAC_ADDR_ARRAY(mac));
6760 return -ENOTSUPP;
6761 }
6762
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006763 if (pHddCtx->isLogpInProgress)
6764 {
6765 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6766 "%s:LOGP in Progress. Ignore!!!", __func__);
Gopichand Nakkala05922802013-03-14 12:23:19 -07006767 wlan_hdd_tdls_set_link_status(pAdapter, mac, eTDLS_LINK_IDLE);
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006768 return -EBUSY;
6769 }
6770
Naresh Jayaram9c6f4462014-02-13 12:20:31 +05306771 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, mac);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07006772
6773 if ( NULL == pTdlsPeer ) {
6774 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
6775 "%s: " MAC_ADDRESS_STR " (update %d) not exist. return invalid",
6776 __func__, MAC_ADDR_ARRAY(mac), update);
6777 return -EINVAL;
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07006778 }
Hoonki Lee5305c3a2013-04-29 23:28:59 -07006779
6780 /* in add station, we accept existing valid staId if there is */
6781 if ((0 == update) &&
6782 ((pTdlsPeer->link_status >= eTDLS_LINK_CONNECTING) ||
6783 (TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07006784 {
Hoonki Lee5305c3a2013-04-29 23:28:59 -07006785 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07006786 "%s: " MAC_ADDRESS_STR
Hoonki Lee5305c3a2013-04-29 23:28:59 -07006787 " link_status %d. staId %d. add station ignored.",
6788 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, pTdlsPeer->staId);
6789 return 0;
6790 }
6791 /* in change station, we accept only when staId is valid */
6792 if ((1 == update) &&
6793 ((pTdlsPeer->link_status > eTDLS_LINK_CONNECTING) ||
6794 (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
6795 {
6796 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
6797 "%s: " MAC_ADDRESS_STR
6798 " link status %d. staId %d. change station %s.",
6799 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, pTdlsPeer->staId,
6800 (TDLS_STA_INDEX_VALID(pTdlsPeer->staId)) ? "ignored" : "declined");
6801 return (TDLS_STA_INDEX_VALID(pTdlsPeer->staId)) ? 0 : -EPERM;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07006802 }
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07006803
6804 /* when others are on-going, we want to change link_status to idle */
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306805 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, mac, TRUE))
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006806 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07006807 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6808 "%s: " MAC_ADDRESS_STR
6809 " TDLS setup is ongoing. Request declined.",
6810 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala05922802013-03-14 12:23:19 -07006811 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006812 }
6813
6814 /* first to check if we reached to maximum supported TDLS peer.
6815 TODO: for now, return -EPERM looks working fine,
6816 but need to check if any other errno fit into this category.*/
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05306817 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
6818 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006819 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07006820 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6821 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05306822 " TDLS Max peer already connected. Request declined."
6823 " Num of peers (%d), Max allowed (%d).",
6824 __func__, MAC_ADDR_ARRAY(mac), numCurrTdlsPeers,
6825 HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -07006826 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006827 }
6828 else
6829 {
6830 hddTdlsPeer_t *pTdlsPeer;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05306831 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, mac, TRUE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07006832 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006833 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07006834 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6835 "%s: " MAC_ADDRESS_STR " already connected. Request declined.",
6836 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006837 return -EPERM;
6838 }
6839 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07006840 if (0 == update)
6841 wlan_hdd_tdls_set_link_status(pAdapter, mac, eTDLS_LINK_CONNECTING);
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006842
Jeff Johnsond75fe012013-04-06 10:53:06 -07006843 /* debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05306844 if (NULL != StaParams)
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07006845 {
6846 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
6847 "%s: TDLS Peer Parameters.", __func__);
Hoonki Lee66b75f32013-04-16 18:30:07 -07006848 if(StaParams->htcap_present)
6849 {
6850 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
6851 "ht_capa->cap_info: %0x", StaParams->HTCap.capInfo);
6852 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
6853 "ht_capa->extended_capabilities: %0x",
6854 StaParams->HTCap.extendedHtCapInfo);
6855 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07006856 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
6857 "params->capability: %0x",StaParams->capability);
6858 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07006859 "params->ext_capab_len: %0x",StaParams->extn_capability[0]);
Hoonki Lee66b75f32013-04-16 18:30:07 -07006860 if(StaParams->vhtcap_present)
6861 {
6862 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
6863 "rxMcsMap %x rxHighest %x txMcsMap %x txHighest %x",
6864 StaParams->VHTCap.suppMcs.rxMcsMap, StaParams->VHTCap.suppMcs.rxHighest,
6865 StaParams->VHTCap.suppMcs.txMcsMap, StaParams->VHTCap.suppMcs.txHighest);
6866 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07006867 {
6868 int i = 0;
Hoonki Lee5305c3a2013-04-29 23:28:59 -07006869 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "Supported rates:");
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07006870 for (i = 0; i < sizeof(StaParams->supported_rates); i++)
6871 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
6872 "[%d]: %x ", i, StaParams->supported_rates[i]);
6873 }
Jeff Johnsond75fe012013-04-06 10:53:06 -07006874 } /* end debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05306875 else if ((1 == update) && (NULL == StaParams))
6876 {
6877 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6878 "%s : update is true, but staParams is NULL. Error!", __func__);
6879 return -EPERM;
6880 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006881
6882 INIT_COMPLETION(pAdapter->tdls_add_station_comp);
6883
6884 if (!update)
6885 {
6886 status = sme_AddTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
6887 pAdapter->sessionId, mac);
6888 }
6889 else
6890 {
6891 status = sme_ChangeTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
6892 pAdapter->sessionId, mac, StaParams);
6893 }
6894
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306895 ret = wait_for_completion_interruptible_timeout(&pAdapter->tdls_add_station_comp,
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006896 msecs_to_jiffies(WAIT_TIME_TDLS_ADD_STA));
6897
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306898 if (ret <= 0)
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006899 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07006900 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306901 "%s: timeout waiting for tdls add station indication %ld",
6902 __func__, ret);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07006903 return -EPERM;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006904 }
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306905
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006906 if ( eHAL_STATUS_SUCCESS != pAdapter->tdlsAddStaStatus)
6907 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07006908 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006909 "%s: Add Station is unsucessful", __func__);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07006910 return -EPERM;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006911 }
6912
6913 return 0;
Gopichand Nakkala05922802013-03-14 12:23:19 -07006914
6915error:
6916 wlan_hdd_tdls_set_link_status(pAdapter, mac, eTDLS_LINK_IDLE);
6917 return -EPERM;
6918
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006919}
6920#endif
6921
Jeff Johnson295189b2012-06-20 16:38:30 -07006922static int wlan_hdd_change_station(struct wiphy *wiphy,
6923 struct net_device *dev,
6924 u8 *mac,
6925 struct station_parameters *params)
6926{
6927 VOS_STATUS status = VOS_STATUS_SUCCESS;
6928 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Gopichand Nakkala29149562013-05-10 21:43:41 +05306929 hdd_context_t *pHddCtx;
6930 hdd_station_ctx_t *pHddStaCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07006931 v_MACADDR_t STAMacAddress;
Gopichand Nakkalab0856222013-03-12 22:39:05 -07006932#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006933 tCsrStaParams StaParams = {0};
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006934 tANI_U8 isBufSta = 0;
Naresh Jayaram3180aa42014-02-12 21:47:26 +05306935 tANI_U8 isOffChannelSupported = 0;
Gopichand Nakkalab0856222013-03-12 22:39:05 -07006936#endif
Jeff Johnsone7245742012-09-05 17:12:55 -07006937 ENTER();
6938
Gopichand Nakkala29149562013-05-10 21:43:41 +05306939 if ((NULL == pAdapter))
6940 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05306941 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala29149562013-05-10 21:43:41 +05306942 "invalid adapter ");
6943 return -EINVAL;
6944 }
6945
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05306946 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
6947 TRACE_CODE_HDD_CHANGE_STATION,
6948 pAdapter->sessionId, params->listen_interval));
Gopichand Nakkala29149562013-05-10 21:43:41 +05306949 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
6950 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6951
6952 if ((NULL == pHddCtx) || (NULL == pHddStaCtx))
6953 {
6954 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
6955 "invalid HDD state or HDD station context");
6956 return -EINVAL;
6957 }
6958
6959 if (pHddCtx->isLogpInProgress)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006960 {
6961 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6962 "%s:LOGP in Progress. Ignore!!!", __func__);
6963 return -EAGAIN;
6964 }
6965
Jeff Johnson295189b2012-06-20 16:38:30 -07006966 vos_mem_copy(STAMacAddress.bytes, mac, sizeof(v_MACADDR_t));
6967
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006968 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
6969 || (pAdapter->device_mode == WLAN_HDD_P2P_GO))
Jeff Johnson295189b2012-06-20 16:38:30 -07006970 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006971 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED))
Jeff Johnson295189b2012-06-20 16:38:30 -07006972 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306973 status = hdd_softap_change_STA_state( pAdapter, &STAMacAddress,
Jeff Johnson295189b2012-06-20 16:38:30 -07006974 WLANTL_STA_AUTHENTICATED);
6975
Gopichand Nakkala29149562013-05-10 21:43:41 +05306976 if (status != VOS_STATUS_SUCCESS)
6977 {
6978 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6979 "%s: Not able to change TL state to AUTHENTICATED", __func__);
6980 return -EINVAL;
6981 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006982 }
6983 }
Hoonki Leea6d49be2013-04-05 09:43:25 -07006984 else if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
6985 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)) {
Gopichand Nakkala29149562013-05-10 21:43:41 +05306986#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07006987 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
6988 StaParams.capability = params->capability;
6989 StaParams.uapsd_queues = params->uapsd_queues;
6990 StaParams.max_sp = params->max_sp;
6991
Naresh Jayaram3180aa42014-02-12 21:47:26 +05306992 /* Convert (first channel , number of channels) tuple to
6993 * the total list of channels. This goes with the assumption
6994 * that if the first channel is < 14, then the next channels
6995 * are an incremental of 1 else an incremental of 4 till the number
6996 * of channels.
6997 */
6998 if (0 != params->supported_channels_len) {
6999 int i = 0,j = 0,k = 0, no_of_channels = 0 ;
7000 for ( i = 0 ; i < params->supported_channels_len ; i+=2)
7001 {
7002 int wifi_chan_index;
7003 StaParams.supported_channels[j] = params->supported_channels[i];
7004 wifi_chan_index =
7005 ((StaParams.supported_channels[j] <= HDD_CHANNEL_14 ) ? 1 : 4 );
7006 no_of_channels = params->supported_channels[i+1];
7007 for(k=1; k <= no_of_channels; k++)
7008 {
7009 StaParams.supported_channels[j+1] =
7010 StaParams.supported_channels[j] + wifi_chan_index;
7011 j+=1;
7012 }
7013 }
7014 StaParams.supported_channels_len = j;
7015 }
7016 vos_mem_copy(StaParams.supported_oper_classes,
7017 params->supported_oper_classes,
7018 params->supported_oper_classes_len);
7019 StaParams.supported_oper_classes_len =
7020 params->supported_oper_classes_len;
7021
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007022 if (0 != params->ext_capab_len)
7023 vos_mem_copy(StaParams.extn_capability, params->ext_capab,
7024 sizeof(StaParams.extn_capability));
7025
7026 if (NULL != params->ht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -07007027 {
7028 StaParams.htcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007029 vos_mem_copy(&StaParams.HTCap, params->ht_capa, sizeof(tSirHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -07007030 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007031
7032 StaParams.supported_rates_len = params->supported_rates_len;
7033
7034 /* Note : The Maximum sizeof supported_rates sent by the Supplicant is 32.
7035 * The supported_rates array , for all the structures propogating till Add Sta
7036 * to the firmware has to be modified , if the supplicant (ieee80211) is
7037 * modified to send more rates.
7038 */
7039
7040 /* To avoid Data Currption , set to max length to SIR_MAC_MAX_SUPP_RATES
7041 */
7042 if (StaParams.supported_rates_len > SIR_MAC_MAX_SUPP_RATES)
7043 StaParams.supported_rates_len = SIR_MAC_MAX_SUPP_RATES;
7044
7045 if (0 != StaParams.supported_rates_len) {
7046 int i = 0;
7047 vos_mem_copy(StaParams.supported_rates, params->supported_rates,
7048 StaParams.supported_rates_len);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007049 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007050 "Supported Rates with Length %d", StaParams.supported_rates_len);
7051 for (i=0; i < StaParams.supported_rates_len; i++)
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007052 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007053 "[%d]: %0x", i, StaParams.supported_rates[i]);
7054 }
7055
7056 if (NULL != params->vht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -07007057 {
7058 StaParams.vhtcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007059 vos_mem_copy(&StaParams.VHTCap, params->vht_capa, sizeof(tSirVHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -07007060 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007061
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007062 if (0 != params->ext_capab_len ) {
7063 /*Define A Macro : TODO Sunil*/
7064 if ((1<<4) & StaParams.extn_capability[3]) {
7065 isBufSta = 1;
7066 }
Naresh Jayaram3180aa42014-02-12 21:47:26 +05307067 /* TDLS Channel Switching Support */
7068 if ((1<<6) & StaParams.extn_capability[3]) {
7069 isOffChannelSupported = 1;
7070 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007071 }
Naresh Jayaram3180aa42014-02-12 21:47:26 +05307072 status = wlan_hdd_tdls_set_peer_caps( pAdapter, mac,
7073 &StaParams, isBufSta,
7074 isOffChannelSupported);
7075
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05307076 if (VOS_STATUS_SUCCESS != status) {
7077 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7078 "%s: wlan_hdd_tdls_set_peer_caps failed!", __func__);
7079 return -EINVAL;
7080 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007081 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 1, &StaParams);
7082
7083 if (VOS_STATUS_SUCCESS != status) {
7084 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7085 "%s: sme_ChangeTdlsPeerSta failed!", __func__);
7086 return -EINVAL;
7087 }
7088 }
Gopichand Nakkalab0856222013-03-12 22:39:05 -07007089#endif
Gopichand Nakkala6239acd2013-06-14 14:48:00 +05307090 }
Jeff Johnsone7245742012-09-05 17:12:55 -07007091 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07007092 return status;
7093}
7094
7095/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05307096 * FUNCTION: __wlan_hdd_cfg80211_add_key
Jeff Johnson295189b2012-06-20 16:38:30 -07007097 * This function is used to initialize the key information
7098 */
7099#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05307100static int __wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07007101 struct net_device *ndev,
7102 u8 key_index, bool pairwise,
7103 const u8 *mac_addr,
7104 struct key_params *params
7105 )
7106#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05307107static int __wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07007108 struct net_device *ndev,
7109 u8 key_index, const u8 *mac_addr,
7110 struct key_params *params
7111 )
7112#endif
7113{
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007114 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -07007115 tCsrRoamSetKey setKey;
7116 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307117 int status;
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007118 v_U32_t roamId= 0xFF;
7119 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07007120 hdd_hostapd_state_t *pHostapdState;
7121 VOS_STATUS vos_status;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07007122 eHalStatus halStatus;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307123 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07007124
7125 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307126
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307127 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7128 TRACE_CODE_HDD_CFG80211_ADD_KEY,
7129 pAdapter->sessionId, params->key_len));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307130 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7131 status = wlan_hdd_validate_context(pHddCtx);
7132
7133 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007134 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307135 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7136 "%s: HDD context is not valid", __func__);
7137 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007138 }
7139
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05307140 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
7141 __func__, hdd_device_modetoString(pAdapter->device_mode),
7142 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07007143
7144 if (CSR_MAX_NUM_KEY <= key_index)
7145 {
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007146 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07007147 key_index);
7148
7149 return -EINVAL;
7150 }
7151
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007152 if (CSR_MAX_KEY_LEN < params->key_len)
7153 {
7154 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key length %d", __func__,
7155 params->key_len);
7156
7157 return -EINVAL;
7158 }
7159
7160 hddLog(VOS_TRACE_LEVEL_INFO,
7161 "%s: called with key index = %d & key length %d",
7162 __func__, key_index, params->key_len);
Jeff Johnson295189b2012-06-20 16:38:30 -07007163
7164 /*extract key idx, key len and key*/
7165 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
7166 setKey.keyId = key_index;
7167 setKey.keyLength = params->key_len;
7168 vos_mem_copy(&setKey.Key[0],params->key, params->key_len);
7169
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007170 switch (params->cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -07007171 {
7172 case WLAN_CIPHER_SUITE_WEP40:
7173 setKey.encType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
7174 break;
7175
7176 case WLAN_CIPHER_SUITE_WEP104:
7177 setKey.encType = eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
7178 break;
7179
7180 case WLAN_CIPHER_SUITE_TKIP:
7181 {
7182 u8 *pKey = &setKey.Key[0];
7183 setKey.encType = eCSR_ENCRYPT_TYPE_TKIP;
7184
7185 vos_mem_zero(pKey, CSR_MAX_KEY_LEN);
7186
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007187 /*Supplicant sends the 32bytes key in this order
Jeff Johnson295189b2012-06-20 16:38:30 -07007188
7189 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007190 | Tk1 |TX-MIC | RX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -07007191 |--------------|----------|----------|
7192 <---16bytes---><--8bytes--><--8bytes-->
7193
7194 */
7195 /*Sme expects the 32 bytes key to be in the below order
7196
7197 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007198 | Tk1 |RX-MIC | TX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -07007199 |--------------|----------|----------|
7200 <---16bytes---><--8bytes--><--8bytes-->
7201 */
7202 /* Copy the Temporal Key 1 (TK1) */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007203 vos_mem_copy(pKey, params->key, 16);
Jeff Johnson295189b2012-06-20 16:38:30 -07007204
7205 /*Copy the rx mic first*/
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007206 vos_mem_copy(&pKey[16], &params->key[24], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -07007207
7208 /*Copy the tx mic */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007209 vos_mem_copy(&pKey[24], &params->key[16], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -07007210
7211
7212 break;
7213 }
7214
7215 case WLAN_CIPHER_SUITE_CCMP:
7216 setKey.encType = eCSR_ENCRYPT_TYPE_AES;
7217 break;
7218
7219#ifdef FEATURE_WLAN_WAPI
7220 case WLAN_CIPHER_SUITE_SMS4:
7221 {
7222 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
7223 wlan_hdd_cfg80211_set_key_wapi(pAdapter, key_index, mac_addr,
7224 params->key, params->key_len);
7225 return 0;
7226 }
7227#endif
Chet Lanctot186b5732013-03-18 10:26:30 -07007228
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08007229#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -07007230 case WLAN_CIPHER_SUITE_KRK:
7231 setKey.encType = eCSR_ENCRYPT_TYPE_KRK;
7232 break;
7233#endif
Chet Lanctot186b5732013-03-18 10:26:30 -07007234
7235#ifdef WLAN_FEATURE_11W
7236 case WLAN_CIPHER_SUITE_AES_CMAC:
7237 setKey.encType = eCSR_ENCRYPT_TYPE_AES_CMAC;
Chet Lanctot3b5158a2013-03-31 16:45:21 -07007238 break;
Chet Lanctot186b5732013-03-18 10:26:30 -07007239#endif
7240
Jeff Johnson295189b2012-06-20 16:38:30 -07007241 default:
Jeff Johnson0299d0a2013-10-30 12:37:43 -07007242 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unsupported cipher type %u",
Jeff Johnson295189b2012-06-20 16:38:30 -07007243 __func__, params->cipher);
7244 return -EOPNOTSUPP;
7245 }
7246
7247 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: encryption type %d",
7248 __func__, setKey.encType);
7249
Shailender Karmuchi642e9812013-05-30 14:34:49 -07007250 if (
Jeff Johnson295189b2012-06-20 16:38:30 -07007251#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
7252 (!pairwise)
7253#else
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007254 (!mac_addr || is_broadcast_ether_addr(mac_addr))
Jeff Johnson295189b2012-06-20 16:38:30 -07007255#endif
Shailender Karmuchi642e9812013-05-30 14:34:49 -07007256 )
7257 {
7258 /* set group key*/
7259 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
7260 "%s- %d: setting Broadcast key",
7261 __func__, __LINE__);
7262 setKey.keyDirection = eSIR_RX_ONLY;
7263 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
7264 }
7265 else
7266 {
7267 /* set pairwise key*/
7268 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
7269 "%s- %d: setting pairwise key",
7270 __func__, __LINE__);
7271 setKey.keyDirection = eSIR_TX_RX;
7272 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
7273 }
7274 if ((WLAN_HDD_IBSS == pAdapter->device_mode) && !pairwise)
7275 {
7276 setKey.keyDirection = eSIR_TX_RX;
7277 /*Set the group key*/
7278 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
7279 pAdapter->sessionId, &setKey, &roamId );
Jeff Johnson295189b2012-06-20 16:38:30 -07007280
Shailender Karmuchi642e9812013-05-30 14:34:49 -07007281 if ( 0 != status )
7282 {
7283 hddLog(VOS_TRACE_LEVEL_ERROR,
7284 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
7285 return -EINVAL;
7286 }
7287 /*Save the keys here and call sme_RoamSetKey for setting
7288 the PTK after peer joins the IBSS network*/
7289 vos_mem_copy(&pAdapter->sessionCtx.station.ibss_enc_key,
7290 &setKey, sizeof(tCsrRoamSetKey));
7291 return status;
7292 }
Gopichand Nakkala29149562013-05-10 21:43:41 +05307293 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP) ||
7294 (pAdapter->device_mode == WLAN_HDD_P2P_GO))
7295 {
Jeff Johnson295189b2012-06-20 16:38:30 -07007296 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007297 if( pHostapdState->bssState == BSS_START )
7298 {
c_hpothu7c55da62014-01-23 18:34:02 +05307299 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7300 vos_status = wlan_hdd_check_ula_done(pAdapter);
7301
7302 if ( vos_status != VOS_STATUS_SUCCESS )
7303 {
7304 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7305 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
7306 __LINE__, vos_status );
7307
7308 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
7309
7310 return -EINVAL;
7311 }
7312
Jeff Johnson295189b2012-06-20 16:38:30 -07007313 status = WLANSAP_SetKeySta( pVosContext, &setKey);
7314
7315 if ( status != eHAL_STATUS_SUCCESS )
7316 {
7317 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7318 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
7319 __LINE__, status );
7320 }
7321 }
7322
7323 /* Saving WEP keys */
7324 else if( eCSR_ENCRYPT_TYPE_WEP40_STATICKEY == setKey.encType ||
7325 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY == setKey.encType )
7326 {
7327 //Save the wep key in ap context. Issue setkey after the BSS is started.
7328 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
7329 vos_mem_copy(&pAPCtx->wepKey[key_index], &setKey, sizeof(tCsrRoamSetKey));
7330 }
7331 else
7332 {
7333 //Save the key in ap context. Issue setkey after the BSS is started.
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007334 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07007335 vos_mem_copy(&pAPCtx->groupKey, &setKey, sizeof(tCsrRoamSetKey));
7336 }
7337 }
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007338 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION) ||
7339 (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT) )
Jeff Johnson295189b2012-06-20 16:38:30 -07007340 {
7341 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
7342 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7343
Gopichand Nakkala3d295922013-05-07 16:19:14 +05307344#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
7345 if (!pairwise)
7346#else
7347 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
7348#endif
7349 {
7350 /* set group key*/
7351 if (pHddStaCtx->roam_info.deferKeyComplete)
7352 {
7353 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
7354 "%s- %d: Perform Set key Complete",
7355 __func__, __LINE__);
7356 hdd_PerformRoamSetKeyComplete(pAdapter);
7357 }
7358 }
7359
Jeff Johnson295189b2012-06-20 16:38:30 -07007360 pWextState->roamProfile.Keys.KeyLength[key_index] = (u8)params->key_len;
7361
Venkata Prathyusha Kuntupalliee2ce712013-01-17 14:09:24 -08007362 pWextState->roamProfile.Keys.defaultIndex = key_index;
7363
7364
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07007365 vos_mem_copy(&pWextState->roamProfile.Keys.KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -07007366 params->key, params->key_len);
7367
Gopichand Nakkala3d295922013-05-07 16:19:14 +05307368
Jeff Johnson295189b2012-06-20 16:38:30 -07007369 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
7370
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307371 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -07007372 "%s: set key for peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307373 __func__, setKey.peerMac[0], setKey.peerMac[1],
7374 setKey.peerMac[2], setKey.peerMac[3],
7375 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -07007376 setKey.keyDirection);
7377
7378 vos_status = wlan_hdd_check_ula_done(pAdapter);
7379
7380 if ( vos_status != VOS_STATUS_SUCCESS )
7381 {
7382 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7383 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
7384 __LINE__, vos_status );
7385
7386 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
7387
7388 return -EINVAL;
7389
7390 }
7391
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07007392#ifdef WLAN_FEATURE_VOWIFI_11R
Gopichand Nakkala3d295922013-05-07 16:19:14 +05307393 /* The supplicant may attempt to set the PTK once pre-authentication
7394 is done. Save the key in the UMAC and include it in the ADD BSS
7395 request */
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07007396 halStatus = sme_FTUpdateKey( WLAN_HDD_GET_HAL_CTX(pAdapter), &setKey);
Gopichand Nakkala3d295922013-05-07 16:19:14 +05307397 if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_SUCCESS )
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07007398 {
Gopichand Nakkala3d295922013-05-07 16:19:14 +05307399 hddLog(VOS_TRACE_LEVEL_INFO_MED,
7400 "%s: Update PreAuth Key success", __func__);
7401 return 0;
7402 }
7403 else if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_FAILED )
7404 {
7405 hddLog(VOS_TRACE_LEVEL_ERROR,
7406 "%s: Update PreAuth Key failed", __func__);
Gopichand Nakkalad7d13652013-02-15 01:48:00 +05307407 return -EINVAL;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07007408 }
7409#endif /* WLAN_FEATURE_VOWIFI_11R */
Jeff Johnson295189b2012-06-20 16:38:30 -07007410
7411 /* issue set key request to SME*/
7412 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
7413 pAdapter->sessionId, &setKey, &roamId );
7414
7415 if ( 0 != status )
7416 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307417 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07007418 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
7419 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
7420 return -EINVAL;
7421 }
7422
7423
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307424 /* in case of IBSS as there was no information available about WEP keys during
7425 * IBSS join, group key intialized with NULL key, so re-initialize group key
Jeff Johnson295189b2012-06-20 16:38:30 -07007426 * with correct value*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307427 if ( (eCSR_BSS_TYPE_START_IBSS == pWextState->roamProfile.BSSType) &&
7428 !( ( IW_AUTH_KEY_MGMT_802_1X
7429 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X))
Jeff Johnson295189b2012-06-20 16:38:30 -07007430 && (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType)
7431 )
7432 &&
7433 ( (WLAN_CIPHER_SUITE_WEP40 == params->cipher)
7434 || (WLAN_CIPHER_SUITE_WEP104 == params->cipher)
7435 )
7436 )
7437 {
7438 setKey.keyDirection = eSIR_RX_ONLY;
7439 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
7440
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307441 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -07007442 "%s: set key peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307443 __func__, setKey.peerMac[0], setKey.peerMac[1],
7444 setKey.peerMac[2], setKey.peerMac[3],
7445 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -07007446 setKey.keyDirection);
7447
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307448 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07007449 pAdapter->sessionId, &setKey, &roamId );
7450
7451 if ( 0 != status )
7452 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307453 hddLog(VOS_TRACE_LEVEL_ERROR,
7454 "%s: sme_RoamSetKey failed for group key (IBSS), returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07007455 __func__, status);
7456 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
7457 return -EINVAL;
7458 }
7459 }
7460 }
7461
7462 return 0;
7463}
7464
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05307465#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
7466static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
7467 struct net_device *ndev,
7468 u8 key_index, bool pairwise,
7469 const u8 *mac_addr,
7470 struct key_params *params
7471 )
7472#else
7473static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
7474 struct net_device *ndev,
7475 u8 key_index, const u8 *mac_addr,
7476 struct key_params *params
7477 )
7478#endif
7479{
7480 int ret;
7481 vos_ssr_protect(__func__);
7482#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
7483 ret = __wlan_hdd_cfg80211_add_key(wiphy, ndev, key_index, pairwise,
7484 mac_addr, params);
7485#else
7486 ret = __wlan_hdd_cfg80211_add_key(wiphy, ndev, key_index, mac_addr,
7487 params);
7488#endif
7489 vos_ssr_unprotect(__func__);
7490
7491 return ret;
7492}
7493
Jeff Johnson295189b2012-06-20 16:38:30 -07007494/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05307495 * FUNCTION: __wlan_hdd_cfg80211_get_key
Jeff Johnson295189b2012-06-20 16:38:30 -07007496 * This function is used to get the key information
7497 */
7498#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05307499static int __wlan_hdd_cfg80211_get_key(
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307500 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07007501 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307502 u8 key_index, bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -07007503 const u8 *mac_addr, void *cookie,
7504 void (*callback)(void *cookie, struct key_params*)
7505 )
7506#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05307507static int __wlan_hdd_cfg80211_get_key(
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307508 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07007509 struct net_device *ndev,
7510 u8 key_index, const u8 *mac_addr, void *cookie,
7511 void (*callback)(void *cookie, struct key_params*)
7512 )
7513#endif
7514{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307515 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307516 hdd_wext_state_t *pWextState= WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
7517 tCsrRoamProfile *pRoamProfile = &(pWextState->roamProfile);
Jeff Johnson295189b2012-06-20 16:38:30 -07007518 struct key_params params;
7519
7520 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307521
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05307522 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
7523 __func__, hdd_device_modetoString(pAdapter->device_mode),
7524 pAdapter->device_mode);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307525
Jeff Johnson295189b2012-06-20 16:38:30 -07007526 memset(&params, 0, sizeof(params));
7527
7528 if (CSR_MAX_NUM_KEY <= key_index)
7529 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307530 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid key index %d"), key_index);
Jeff Johnson295189b2012-06-20 16:38:30 -07007531 return -EINVAL;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307532 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007533
7534 switch(pRoamProfile->EncryptionType.encryptionType[0])
7535 {
7536 case eCSR_ENCRYPT_TYPE_NONE:
7537 params.cipher = IW_AUTH_CIPHER_NONE;
7538 break;
7539
7540 case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY:
7541 case eCSR_ENCRYPT_TYPE_WEP40:
7542 params.cipher = WLAN_CIPHER_SUITE_WEP40;
7543 break;
7544
7545 case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY:
7546 case eCSR_ENCRYPT_TYPE_WEP104:
7547 params.cipher = WLAN_CIPHER_SUITE_WEP104;
7548 break;
7549
7550 case eCSR_ENCRYPT_TYPE_TKIP:
7551 params.cipher = WLAN_CIPHER_SUITE_TKIP;
7552 break;
7553
7554 case eCSR_ENCRYPT_TYPE_AES:
7555 params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
7556 break;
7557
7558 default:
7559 params.cipher = IW_AUTH_CIPHER_NONE;
7560 break;
7561 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307562
c_hpothuaaf19692014-05-17 17:01:48 +05307563 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7564 TRACE_CODE_HDD_CFG80211_GET_KEY,
7565 pAdapter->sessionId, params.cipher));
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307566
Jeff Johnson295189b2012-06-20 16:38:30 -07007567 params.key_len = pRoamProfile->Keys.KeyLength[key_index];
7568 params.seq_len = 0;
7569 params.seq = NULL;
7570 params.key = &pRoamProfile->Keys.KeyMaterial[key_index][0];
7571 callback(cookie, &params);
7572 return 0;
7573}
7574
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05307575#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
7576static int wlan_hdd_cfg80211_get_key(
7577 struct wiphy *wiphy,
7578 struct net_device *ndev,
7579 u8 key_index, bool pairwise,
7580 const u8 *mac_addr, void *cookie,
7581 void (*callback)(void *cookie, struct key_params*)
7582 )
7583#else
7584static int wlan_hdd_cfg80211_get_key(
7585 struct wiphy *wiphy,
7586 struct net_device *ndev,
7587 u8 key_index, const u8 *mac_addr, void *cookie,
7588 void (*callback)(void *cookie, struct key_params*)
7589 )
7590#endif
7591{
7592 int ret;
7593
7594 vos_ssr_protect(__func__);
7595#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
7596 ret = __wlan_hdd_cfg80211_get_key(wiphy, ndev, key_index, pairwise,
7597 mac_addr, cookie, callback);
7598#else
7599 ret = __wlan_hdd_cfg80211_get_key(wiphy, ndev, key_index, mac_addr,
7600 callback);
7601#endif
7602 vos_ssr_unprotect(__func__);
7603
7604 return ret;
7605}
7606
Jeff Johnson295189b2012-06-20 16:38:30 -07007607/*
7608 * FUNCTION: wlan_hdd_cfg80211_del_key
7609 * This function is used to delete the key information
7610 */
7611#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307612static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07007613 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307614 u8 key_index,
7615 bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -07007616 const u8 *mac_addr
7617 )
7618#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307619static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07007620 struct net_device *ndev,
7621 u8 key_index,
7622 const u8 *mac_addr
7623 )
7624#endif
7625{
7626 int status = 0;
7627
7628 //This code needs to be revisited. There is sme_removeKey API, we should
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307629 //plan to use that. After the change to use correct index in setkey,
Jeff Johnson295189b2012-06-20 16:38:30 -07007630 //it is observed that this is invalidating peer
7631 //key index whenever re-key is done. This is affecting data link.
7632 //It should be ok to ignore del_key.
7633#if 0
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307634 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
7635 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07007636 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
7637 tCsrRoamSetKey setKey;
7638 v_U32_t roamId= 0xFF;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307639
Jeff Johnson295189b2012-06-20 16:38:30 -07007640 ENTER();
7641
7642 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device_mode = %d\n",
7643 __func__,pAdapter->device_mode);
7644
7645 if (CSR_MAX_NUM_KEY <= key_index)
7646 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307647 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07007648 key_index);
7649
7650 return -EINVAL;
7651 }
7652
7653 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
7654 setKey.keyId = key_index;
7655
7656 if (mac_addr)
7657 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
7658 else
7659 vos_mem_copy(setKey.peerMac, groupmacaddr, WNI_CFG_BSSID_LEN);
7660
7661 setKey.encType = eCSR_ENCRYPT_TYPE_NONE;
7662
7663 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07007664 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307665 )
7666 {
7667
7668 hdd_hostapd_state_t *pHostapdState =
Jeff Johnson295189b2012-06-20 16:38:30 -07007669 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
7670 if( pHostapdState->bssState == BSS_START)
7671 {
7672 status = WLANSAP_SetKeySta( pVosContext, &setKey);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307673
Jeff Johnson295189b2012-06-20 16:38:30 -07007674 if ( status != eHAL_STATUS_SUCCESS )
7675 {
7676 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7677 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
7678 __LINE__, status );
7679 }
7680 }
7681 }
7682 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307683 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnson295189b2012-06-20 16:38:30 -07007684 )
7685 {
7686 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7687
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307688 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
7689
7690 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -07007691 "%s: delete key for peerMac %2x:%2x:%2x:%2x:%2x:%2x",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307692 __func__, setKey.peerMac[0], setKey.peerMac[1],
7693 setKey.peerMac[2], setKey.peerMac[3],
Jeff Johnson295189b2012-06-20 16:38:30 -07007694 setKey.peerMac[4], setKey.peerMac[5]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307695 if(pAdapter->sessionCtx.station.conn_info.connState ==
7696 eConnectionState_Associated)
Jeff Johnson295189b2012-06-20 16:38:30 -07007697 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307698 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07007699 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307700
Jeff Johnson295189b2012-06-20 16:38:30 -07007701 if ( 0 != status )
7702 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307703 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07007704 "%s: sme_RoamSetKey failure, returned %d",
7705 __func__, status);
7706 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
7707 return -EINVAL;
7708 }
7709 }
7710 }
7711#endif
Jeff Johnsone7245742012-09-05 17:12:55 -07007712 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07007713 return status;
7714}
7715
7716/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05307717 * FUNCTION: __wlan_hdd_cfg80211_set_default_key
Jeff Johnson295189b2012-06-20 16:38:30 -07007718 * This function is used to set the default tx key index
7719 */
7720#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05307721static int __wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07007722 struct net_device *ndev,
7723 u8 key_index,
7724 bool unicast, bool multicast)
7725#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05307726static int __wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07007727 struct net_device *ndev,
7728 u8 key_index)
7729#endif
7730{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307731 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307732 int status;
Gopichand Nakkala29149562013-05-10 21:43:41 +05307733 hdd_wext_state_t *pWextState;
7734 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307735 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07007736
7737 ENTER();
7738
Gopichand Nakkala29149562013-05-10 21:43:41 +05307739 if ((NULL == pAdapter))
7740 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307741 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala29149562013-05-10 21:43:41 +05307742 "invalid adapter");
7743 return -EINVAL;
7744 }
7745
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307746 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7747 TRACE_CODE_HDD_CFG80211_SET_DEFAULT_KEY,
7748 pAdapter->sessionId, key_index));
7749
Gopichand Nakkala29149562013-05-10 21:43:41 +05307750 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
7751 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7752
7753 if ((NULL == pWextState) || (NULL == pHddStaCtx))
7754 {
7755 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
7756 "invalid Wext state or HDD context");
7757 return -EINVAL;
7758 }
7759
Arif Hussain6d2a3322013-11-17 19:50:10 -08007760 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d key_index = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07007761 __func__,pAdapter->device_mode, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307762
Jeff Johnson295189b2012-06-20 16:38:30 -07007763 if (CSR_MAX_NUM_KEY <= key_index)
7764 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307765 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07007766 key_index);
7767
7768 return -EINVAL;
7769 }
7770
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307771 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7772 status = wlan_hdd_validate_context(pHddCtx);
7773
7774 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007775 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307776 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7777 "%s: HDD context is not valid", __func__);
7778 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007779 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307780
Jeff Johnson295189b2012-06-20 16:38:30 -07007781 if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -07007782 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307783 )
Jeff Johnson295189b2012-06-20 16:38:30 -07007784 {
Gopichand Nakkala29149562013-05-10 21:43:41 +05307785 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
Arif Hussain6943f522013-11-04 20:10:10 -08007786 pHddStaCtx->conn_info.ucEncryptionType) &&
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307787 (eCSR_ENCRYPT_TYPE_AES !=
Arif Hussain6943f522013-11-04 20:10:10 -08007788 pHddStaCtx->conn_info.ucEncryptionType)
Jeff Johnson295189b2012-06-20 16:38:30 -07007789 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307790 {
7791 /* if default key index is not same as previous one,
Jeff Johnson295189b2012-06-20 16:38:30 -07007792 * then update the default key index */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307793
Jeff Johnson295189b2012-06-20 16:38:30 -07007794 tCsrRoamSetKey setKey;
7795 v_U32_t roamId= 0xFF;
7796 tCsrKeys *Keys = &pWextState->roamProfile.Keys;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307797
7798 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: default tx key index %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07007799 __func__, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307800
Jeff Johnson295189b2012-06-20 16:38:30 -07007801 Keys->defaultIndex = (u8)key_index;
7802 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
7803 setKey.keyId = key_index;
7804 setKey.keyLength = Keys->KeyLength[key_index];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307805
7806 vos_mem_copy(&setKey.Key[0],
7807 &Keys->KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -07007808 Keys->KeyLength[key_index]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307809
Gopichand Nakkala29149562013-05-10 21:43:41 +05307810 setKey.keyDirection = eSIR_TX_RX;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307811
7812 vos_mem_copy(setKey.peerMac,
Jeff Johnson295189b2012-06-20 16:38:30 -07007813 &pHddStaCtx->conn_info.bssId[0],
7814 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307815
Gopichand Nakkala29149562013-05-10 21:43:41 +05307816 if (Keys->KeyLength[key_index] == CSR_WEP40_KEY_LEN &&
7817 pWextState->roamProfile.EncryptionType.encryptionType[0] ==
7818 eCSR_ENCRYPT_TYPE_WEP104)
7819 {
7820 /*In the case of dynamic wep supplicant hardcodes DWEP type to eCSR_ENCRYPT_TYPE_WEP104
7821 even though ap is configured for WEP-40 encryption. In this canse the key length
7822 is 5 but the encryption type is 104 hence checking the key langht(5) and encryption
7823 type(104) and switching encryption type to 40*/
7824 pWextState->roamProfile.EncryptionType.encryptionType[0] =
7825 eCSR_ENCRYPT_TYPE_WEP40;
7826 pWextState->roamProfile.mcEncryptionType.encryptionType[0] =
7827 eCSR_ENCRYPT_TYPE_WEP40;
7828 }
7829
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307830 setKey.encType =
Jeff Johnson295189b2012-06-20 16:38:30 -07007831 pWextState->roamProfile.EncryptionType.encryptionType[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307832
Jeff Johnson295189b2012-06-20 16:38:30 -07007833 /* issue set key request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307834 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07007835 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307836
Jeff Johnson295189b2012-06-20 16:38:30 -07007837 if ( 0 != status )
7838 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307839 hddLog(VOS_TRACE_LEVEL_ERROR,
7840 "%s: sme_RoamSetKey failed, returned %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07007841 status);
7842 return -EINVAL;
7843 }
7844 }
7845 }
7846
7847 /* In SoftAp mode setting key direction for default mode */
7848 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
7849 {
7850 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
7851 pWextState->roamProfile.EncryptionType.encryptionType[0]) &&
7852 (eCSR_ENCRYPT_TYPE_AES !=
7853 pWextState->roamProfile.EncryptionType.encryptionType[0])
7854 )
7855 {
7856 /* Saving key direction for default key index to TX default */
7857 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
7858 pAPCtx->wepKey[key_index].keyDirection = eSIR_TX_DEFAULT;
7859 }
7860 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307861
Jeff Johnson295189b2012-06-20 16:38:30 -07007862 return status;
7863}
7864
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05307865#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
7866static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
7867 struct net_device *ndev,
7868 u8 key_index,
7869 bool unicast, bool multicast)
7870#else
7871static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
7872 struct net_device *ndev,
7873 u8 key_index)
7874#endif
7875{
7876 int ret;
7877 vos_ssr_protect(__func__);
7878#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
7879 ret = __wlan_hdd_cfg80211_set_default_key(wiphy, ndev, key_index, unicast,
7880 multicast);
7881#else
7882 ret = __wlan_hdd_cfg80211_set_default_key(wiphy, ndev, key_index);
7883#endif
7884 vos_ssr_unprotect(__func__);
7885
7886 return ret;
7887}
7888
Jeff Johnson295189b2012-06-20 16:38:30 -07007889/*
7890 * FUNCTION: wlan_hdd_cfg80211_inform_bss
7891 * This function is used to inform the BSS details to nl80211 interface.
7892 */
7893static struct cfg80211_bss* wlan_hdd_cfg80211_inform_bss(
7894 hdd_adapter_t *pAdapter, tCsrRoamConnectedProfile *roamProfile)
7895{
7896 struct net_device *dev = pAdapter->dev;
7897 struct wireless_dev *wdev = dev->ieee80211_ptr;
7898 struct wiphy *wiphy = wdev->wiphy;
7899 tSirBssDescription *pBssDesc = roamProfile->pBssDesc;
7900 int chan_no;
7901 int ie_length;
7902 const char *ie;
7903 unsigned int freq;
7904 struct ieee80211_channel *chan;
7905 int rssi = 0;
7906 struct cfg80211_bss *bss = NULL;
7907
7908 ENTER();
7909
7910 if( NULL == pBssDesc )
7911 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08007912 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pBssDesc is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007913 return bss;
7914 }
7915
7916 chan_no = pBssDesc->channelId;
7917 ie_length = GET_IE_LEN_IN_BSS_DESC( pBssDesc->length );
7918 ie = ((ie_length != 0) ? (const char *)&pBssDesc->ieFields: NULL);
7919
7920 if( NULL == ie )
7921 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08007922 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: IE of BSS descriptor is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007923 return bss;
7924 }
7925
7926#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
7927 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
7928 {
7929 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
7930 }
7931 else
7932 {
7933 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
7934 }
7935#else
7936 freq = ieee80211_channel_to_frequency(chan_no);
7937#endif
7938
7939 chan = __ieee80211_get_channel(wiphy, freq);
7940
Santhosh Kumar Padmaa45fdb12014-04-15 15:54:38 +05307941 if (!chan) {
7942 hddLog(VOS_TRACE_LEVEL_ERROR, "%s chan pointer is NULL", __func__);
7943 return NULL;
7944 }
7945
Abhishek Singhaee43942014-06-16 18:55:47 +05307946 rssi = (VOS_MIN ((pBssDesc->rssi + pBssDesc->sinr), 0))*100;
Jeff Johnson295189b2012-06-20 16:38:30 -07007947
Abhishek Singhaee43942014-06-16 18:55:47 +05307948 return cfg80211_inform_bss(wiphy, chan, pBssDesc->bssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307949 le64_to_cpu(*(__le64 *)pBssDesc->timeStamp),
Jeff Johnson295189b2012-06-20 16:38:30 -07007950 pBssDesc->capabilityInfo,
7951 pBssDesc->beaconInterval, ie, ie_length,
Abhishek Singhaee43942014-06-16 18:55:47 +05307952 rssi, GFP_KERNEL );
Jeff Johnson295189b2012-06-20 16:38:30 -07007953}
7954
7955
7956
7957/*
7958 * FUNCTION: wlan_hdd_cfg80211_inform_bss_frame
7959 * This function is used to inform the BSS details to nl80211 interface.
7960 */
7961struct cfg80211_bss*
7962wlan_hdd_cfg80211_inform_bss_frame( hdd_adapter_t *pAdapter,
7963 tSirBssDescription *bss_desc
7964 )
7965{
7966 /*
7967 cfg80211_inform_bss() is not updating ie field of bss entry, if entry
7968 already exists in bss data base of cfg80211 for that particular BSS ID.
7969 Using cfg80211_inform_bss_frame to update the bss entry instead of
7970 cfg80211_inform_bss, But this call expects mgmt packet as input. As of
7971 now there is no possibility to get the mgmt(probe response) frame from PE,
7972 converting bss_desc to ieee80211_mgmt(probe response) and passing to
7973 cfg80211_inform_bss_frame.
7974 */
7975 struct net_device *dev = pAdapter->dev;
7976 struct wireless_dev *wdev = dev->ieee80211_ptr;
7977 struct wiphy *wiphy = wdev->wiphy;
7978 int chan_no = bss_desc->channelId;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08007979#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
7980 qcom_ie_age *qie_age = NULL;
7981 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length ) + sizeof(qcom_ie_age);
7982#else
Jeff Johnson295189b2012-06-20 16:38:30 -07007983 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length );
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08007984#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007985 const char *ie =
7986 ((ie_length != 0) ? (const char *)&bss_desc->ieFields: NULL);
7987 unsigned int freq;
7988 struct ieee80211_channel *chan;
Abhishek Singh1e2bfa32014-01-02 15:44:15 +05307989 struct ieee80211_mgmt *mgmt = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07007990 struct cfg80211_bss *bss_status = NULL;
7991 size_t frame_len = sizeof (struct ieee80211_mgmt) + ie_length;
7992 int rssi = 0;
Wilson Yangf80a0542013-10-07 13:02:37 -07007993 hdd_context_t *pHddCtx;
7994 int status;
Jeff Johnsone7245742012-09-05 17:12:55 -07007995#ifdef WLAN_OPEN_SOURCE
7996 struct timespec ts;
7997#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007998
Wilson Yangf80a0542013-10-07 13:02:37 -07007999 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8000 status = wlan_hdd_validate_context(pHddCtx);
8001
8002 /*bss_update is not allowed during wlan driver loading or unloading*/
Mihir Shete18156292014-03-11 15:38:30 +05308003 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Wilson Yangf80a0542013-10-07 13:02:37 -07008004 {
8005 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8006 "%s:Loading_unloading in Progress. Ignore!!!",__func__);
8007 return NULL;
8008 }
8009
8010
8011 if (0 != status)
8012 {
8013 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8014 "%s: HDD context is not valid", __func__);
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -07008015 return NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -07008016 }
8017
Abhishek Singh1e2bfa32014-01-02 15:44:15 +05308018 mgmt = kzalloc((sizeof (struct ieee80211_mgmt) + ie_length), GFP_KERNEL);
Wilson Yangf80a0542013-10-07 13:02:37 -07008019 if (!mgmt)
8020 {
8021 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8022 "%s: memory allocation failed ", __func__);
8023 return NULL;
8024 }
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -07008025
Jeff Johnson295189b2012-06-20 16:38:30 -07008026 memcpy(mgmt->bssid, bss_desc->bssId, ETH_ALEN);
Jeff Johnsone7245742012-09-05 17:12:55 -07008027
8028#ifdef WLAN_OPEN_SOURCE
8029 /* Android does not want the timestamp from the frame.
8030 Instead it wants a monotonic increasing value */
8031 get_monotonic_boottime(&ts);
8032 mgmt->u.probe_resp.timestamp =
8033 ((u64)ts.tv_sec * 1000000) + (ts.tv_nsec / 1000);
8034#else
8035 /* keep old behavior for non-open source (for now) */
Jeff Johnson295189b2012-06-20 16:38:30 -07008036 memcpy(&mgmt->u.probe_resp.timestamp, bss_desc->timeStamp,
8037 sizeof (bss_desc->timeStamp));
Jeff Johnsone7245742012-09-05 17:12:55 -07008038
8039#endif
8040
Jeff Johnson295189b2012-06-20 16:38:30 -07008041 mgmt->u.probe_resp.beacon_int = bss_desc->beaconInterval;
8042 mgmt->u.probe_resp.capab_info = bss_desc->capabilityInfo;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08008043
8044#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
8045 /* GPS Requirement: need age ie per entry. Using vendor specific. */
8046 /* Assuming this is the last IE, copy at the end */
8047 ie_length -=sizeof(qcom_ie_age);
8048 qie_age = (qcom_ie_age *)(mgmt->u.probe_resp.variable + ie_length);
8049 qie_age->element_id = QCOM_VENDOR_IE_ID;
8050 qie_age->len = QCOM_VENDOR_IE_AGE_LEN;
8051 qie_age->oui_1 = QCOM_OUI1;
8052 qie_age->oui_2 = QCOM_OUI2;
8053 qie_age->oui_3 = QCOM_OUI3;
8054 qie_age->type = QCOM_VENDOR_IE_AGE_TYPE;
8055 qie_age->age = vos_timer_get_system_ticks() - bss_desc->nReceivedTime;
8056#endif
8057
Jeff Johnson295189b2012-06-20 16:38:30 -07008058 memcpy(mgmt->u.probe_resp.variable, ie, ie_length);
Gopichand Nakkalad908ec82013-05-16 19:32:19 +05308059 if (bss_desc->fProbeRsp)
8060 {
8061 mgmt->frame_control |=
8062 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_RESP);
8063 }
8064 else
8065 {
8066 mgmt->frame_control |=
8067 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_BEACON);
8068 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008069
8070#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308071 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ) &&
Jeff Johnson295189b2012-06-20 16:38:30 -07008072 (wiphy->bands[IEEE80211_BAND_2GHZ] != NULL))
8073 {
8074 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
8075 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308076 else if ((chan_no > ARRAY_SIZE(hdd_channels_2_4_GHZ)) &&
Jeff Johnson295189b2012-06-20 16:38:30 -07008077 (wiphy->bands[IEEE80211_BAND_5GHZ] != NULL))
8078
8079 {
8080 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
8081 }
8082 else
8083 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05308084 hddLog(VOS_TRACE_LEVEL_ERROR, "%s Invalid chan_no:%d",
8085 __func__, chan_no);
Jeff Johnson295189b2012-06-20 16:38:30 -07008086 kfree(mgmt);
8087 return NULL;
8088 }
8089#else
8090 freq = ieee80211_channel_to_frequency(chan_no);
8091#endif
8092 chan = __ieee80211_get_channel(wiphy, freq);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -08008093 /*when the band is changed on the fly using the GUI, three things are done
8094 * 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)
8095 * as part of the scan abort, message willbe queued to PE and we proceed with flushing and changinh the band.
8096 * pe will stop the scanning further and report back the results what ever it had till now by calling the call back function.
8097 * if the time between update band and scandone call back is sufficent enough the band change reflects in SME, SME validates the channels
8098 * and discards the channels correponding to previous band and calls back with zero bss results.
8099 * 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
8100 * all the channels correponding to previous band.this is due to race condition.but those channels are invalid to the new band and so
8101 * this function __ieee80211_get_channel will return NULL.Each time we report scan result with this pointer null warning kernel trace is printed.
8102 * if the scan results contain large number of APs continuosly kernel warning trace is printed and it will lead to apps watch dog bark.
8103 * So drop the bss and continue to next bss.
8104 */
8105 if(chan == NULL)
8106 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05308107 hddLog(VOS_TRACE_LEVEL_ERROR, "%s chan pointer is NULL", __func__);
Chilam Ngc4244af2013-04-01 15:37:32 -07008108 kfree(mgmt);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -08008109 return NULL;
8110 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008111 /*To keep the rssi icon of the connected AP in the scan window
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308112 *and the rssi icon of the wireless networks in sync
Jeff Johnson295189b2012-06-20 16:38:30 -07008113 * */
8114 if (( eConnectionState_Associated ==
8115 pAdapter->sessionCtx.station.conn_info.connState ) &&
8116 ( VOS_TRUE == vos_mem_compare(bss_desc->bssId,
8117 pAdapter->sessionCtx.station.conn_info.bssId,
8118 WNI_CFG_BSSID_LEN)))
8119 {
8120 /* supplicant takes the signal strength in terms of mBm(100*dBm) */
8121 rssi = (pAdapter->rssi * 100);
8122 }
8123 else
8124 {
8125 rssi = (VOS_MIN ((bss_desc->rssi + bss_desc->sinr), 0))*100;
8126 }
8127
Nirav Shah20ac06f2013-12-12 18:14:06 +05308128 hddLog(VOS_TRACE_LEVEL_INFO, "%s: BSSID:" MAC_ADDRESS_STR " Channel:%d"
8129 "RSSI:%d", __func__, MAC_ADDR_ARRAY(mgmt->bssid),
8130 chan->center_freq, (int)(rssi/100));
8131
Jeff Johnson295189b2012-06-20 16:38:30 -07008132 bss_status = cfg80211_inform_bss_frame(wiphy, chan, mgmt,
8133 frame_len, rssi, GFP_KERNEL);
8134 kfree(mgmt);
8135 return bss_status;
8136}
8137
8138/*
8139 * FUNCTION: wlan_hdd_cfg80211_update_bss_db
8140 * This function is used to update the BSS data base of CFG8011
8141 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308142struct cfg80211_bss* wlan_hdd_cfg80211_update_bss_db( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07008143 tCsrRoamInfo *pRoamInfo
8144 )
8145{
8146 tCsrRoamConnectedProfile roamProfile;
8147 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
8148 struct cfg80211_bss *bss = NULL;
8149
8150 ENTER();
8151
8152 memset(&roamProfile, 0, sizeof(tCsrRoamConnectedProfile));
8153 sme_RoamGetConnectProfile(hHal, pAdapter->sessionId, &roamProfile);
8154
8155 if (NULL != roamProfile.pBssDesc)
8156 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308157 bss = wlan_hdd_cfg80211_inform_bss(pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07008158 &roamProfile);
8159
8160 if (NULL == bss)
8161 {
8162 hddLog(VOS_TRACE_LEVEL_INFO, "%s: cfg80211_inform_bss return NULL",
8163 __func__);
8164 }
8165
8166 sme_RoamFreeConnectProfile(hHal, &roamProfile);
8167 }
8168 else
8169 {
8170 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: roamProfile.pBssDesc is NULL",
8171 __func__);
8172 }
8173 return bss;
8174}
8175
8176/*
8177 * FUNCTION: wlan_hdd_cfg80211_update_bss
8178 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308179static int wlan_hdd_cfg80211_update_bss( struct wiphy *wiphy,
8180 hdd_adapter_t *pAdapter
Jeff Johnson295189b2012-06-20 16:38:30 -07008181 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308182{
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308183 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07008184 tCsrScanResultInfo *pScanResult;
8185 eHalStatus status = 0;
8186 tScanResultHandle pResult;
8187 struct cfg80211_bss *bss_status = NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -07008188 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07008189
8190 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308191
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308192 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
8193 TRACE_CODE_HDD_CFG80211_UPDATE_BSS,
8194 NO_SESSION, pAdapter->sessionId));
8195
Wilson Yangf80a0542013-10-07 13:02:37 -07008196 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8197
8198 if (pHddCtx->isLogpInProgress)
Jeff Johnson295189b2012-06-20 16:38:30 -07008199 {
Wilson Yangf80a0542013-10-07 13:02:37 -07008200 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
8201 "%s:LOGP in Progress. Ignore!!!",__func__);
8202 return -EAGAIN;
Jeff Johnson295189b2012-06-20 16:38:30 -07008203 }
8204
Wilson Yangf80a0542013-10-07 13:02:37 -07008205
8206 /*bss_update is not allowed during wlan driver loading or unloading*/
Mihir Shete18156292014-03-11 15:38:30 +05308207 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Wilson Yangf80a0542013-10-07 13:02:37 -07008208 {
8209 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8210 "%s:Loading_unloading in Progress. Ignore!!!",__func__);
8211 return VOS_STATUS_E_PERM;
8212 }
8213
8214
Jeff Johnson295189b2012-06-20 16:38:30 -07008215 /*
8216 * start getting scan results and populate cgf80211 BSS database
8217 */
8218 status = sme_ScanGetResult(hHal, pAdapter->sessionId, NULL, &pResult);
8219
8220 /* no scan results */
8221 if (NULL == pResult)
8222 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05308223 hddLog(VOS_TRACE_LEVEL_INFO, "%s: No scan result Status %d",
8224 __func__, status);
Jeff Johnson295189b2012-06-20 16:38:30 -07008225 return status;
8226 }
8227
8228 pScanResult = sme_ScanResultGetFirst(hHal, pResult);
8229
8230 while (pScanResult)
8231 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308232 /*
8233 * cfg80211_inform_bss() is not updating ie field of bss entry, if
8234 * entry already exists in bss data base of cfg80211 for that
8235 * particular BSS ID. Using cfg80211_inform_bss_frame to update the
8236 * bss entry instead of cfg80211_inform_bss, But this call expects
8237 * mgmt packet as input. As of now there is no possibility to get
8238 * the mgmt(probe response) frame from PE, converting bss_desc to
Jeff Johnson295189b2012-06-20 16:38:30 -07008239 * ieee80211_mgmt(probe response) and passing to c
8240 * fg80211_inform_bss_frame.
8241 * */
8242
8243 bss_status = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
8244 &pScanResult->BssDescriptor);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308245
Jeff Johnson295189b2012-06-20 16:38:30 -07008246
8247 if (NULL == bss_status)
8248 {
8249 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008250 "%s: NULL returned by cfg80211_inform_bss", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008251 }
8252 else
8253 {
Yue Maf49ba872013-08-19 12:04:25 -07008254 cfg80211_put_bss(
8255#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0))
8256 wiphy,
8257#endif
8258 bss_status);
Jeff Johnson295189b2012-06-20 16:38:30 -07008259 }
8260
8261 pScanResult = sme_ScanResultGetNext(hHal, pResult);
8262 }
8263
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308264 sme_ScanResultPurge(hHal, pResult);
Jeff Johnson295189b2012-06-20 16:38:30 -07008265
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308266 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07008267}
8268
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008269void
8270hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel)
8271{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308272 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussaina7c8e412013-11-20 11:06:42 -08008273 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(macAddr));
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008274} /****** end hddPrintMacAddr() ******/
8275
8276void
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07008277hddPrintPmkId(tANI_U8 *pmkId, tANI_U8 logLevel)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008278{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308279 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008280 "%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X",
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07008281 pmkId[0], pmkId[1], pmkId[2], pmkId[3], pmkId[4],
8282 pmkId[5], pmkId[6], pmkId[7], pmkId[8], pmkId[9], pmkId[10],
8283 pmkId[11], pmkId[12], pmkId[13], pmkId[14], pmkId[15]);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008284} /****** end hddPrintPmkId() ******/
8285
8286//hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel);
8287//hddPrintMacAddr(macAddr, VOS_TRACE_LEVEL_FATAL);
8288
8289//void sirDumpBuf(tpAniSirGlobal pMac, tANI_U8 modId, tANI_U32 level, tANI_U8 *buf, tANI_U32 size);
8290//sirDumpBuf(pMac, VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, pmkid, 16);
8291
8292#define dump_bssid(bssid) \
8293 { \
Jeff Johnsone7245742012-09-05 17:12:55 -07008294 hddLog(VOS_TRACE_LEVEL_INFO, "BSSID (MAC) address:\t"); \
8295 hddPrintMacAddr(bssid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008296 }
8297
8298#define dump_pmkid(pMac, pmkid) \
8299 { \
Jeff Johnsone7245742012-09-05 17:12:55 -07008300 hddLog(VOS_TRACE_LEVEL_INFO, "PMKSA-ID:\t"); \
8301 hddPrintPmkId(pmkid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008302 }
8303
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -07008304#if defined(FEATURE_WLAN_LFR) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008305/*
8306 * FUNCTION: wlan_hdd_cfg80211_pmksa_candidate_notify
8307 * This function is used to notify the supplicant of a new PMKSA candidate.
8308 */
8309int wlan_hdd_cfg80211_pmksa_candidate_notify(
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308310 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008311 int index, bool preauth )
8312{
Jeff Johnsone7245742012-09-05 17:12:55 -07008313#ifdef FEATURE_WLAN_OKC
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008314 struct net_device *dev = pAdapter->dev;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07008315 hdd_context_t *pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008316
8317 ENTER();
Jeff Johnsone7245742012-09-05 17:12:55 -07008318 hddLog(VOS_TRACE_LEVEL_INFO, "%s is going to notify supplicant of:", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008319
8320 if( NULL == pRoamInfo )
8321 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08008322 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pRoamInfo is NULL", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008323 return -EINVAL;
8324 }
8325
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07008326 if (eANI_BOOLEAN_TRUE == hdd_is_okc_mode_enabled(pHddCtx))
8327 {
8328 dump_bssid(pRoamInfo->bssid);
8329 cfg80211_pmksa_candidate_notify(dev, index,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008330 pRoamInfo->bssid, preauth, GFP_KERNEL);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07008331 }
Jeff Johnsone7245742012-09-05 17:12:55 -07008332#endif /* FEATURE_WLAN_OKC */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308333 return 0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008334}
8335#endif //FEATURE_WLAN_LFR
8336
Yue Maef608272013-04-08 23:09:17 -07008337#ifdef FEATURE_WLAN_LFR_METRICS
8338/*
8339 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth
8340 * 802.11r/LFR metrics reporting function to report preauth initiation
8341 *
8342 */
8343#define MAX_LFR_METRICS_EVENT_LENGTH 100
8344VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth(hdd_adapter_t *pAdapter,
8345 tCsrRoamInfo *pRoamInfo)
8346{
8347 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
8348 union iwreq_data wrqu;
8349
8350 ENTER();
8351
8352 if (NULL == pAdapter)
8353 {
8354 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
8355 return VOS_STATUS_E_FAILURE;
8356 }
8357
8358 /* create the event */
8359 memset(&wrqu, 0, sizeof(wrqu));
8360 memset(metrics_notification, 0, sizeof(metrics_notification));
8361
8362 wrqu.data.pointer = metrics_notification;
8363 wrqu.data.length = scnprintf(metrics_notification,
8364 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_INIT "
8365 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
8366
8367 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
8368
8369 EXIT();
8370
8371 return VOS_STATUS_SUCCESS;
8372}
8373
8374/*
8375 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth_status
8376 * 802.11r/LFR metrics reporting function to report preauth completion
8377 * or failure
8378 */
8379VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth_status(
8380 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo, bool preauth_status)
8381{
8382 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
8383 union iwreq_data wrqu;
8384
8385 ENTER();
8386
8387 if (NULL == pAdapter)
8388 {
8389 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
8390 return VOS_STATUS_E_FAILURE;
8391 }
8392
8393 /* create the event */
8394 memset(&wrqu, 0, sizeof(wrqu));
8395 memset(metrics_notification, 0, sizeof(metrics_notification));
8396
8397 scnprintf(metrics_notification, sizeof(metrics_notification),
8398 "QCOM: LFR_PREAUTH_STATUS "MAC_ADDRESS_STR,
8399 MAC_ADDR_ARRAY(pRoamInfo->bssid));
8400
8401 if (1 == preauth_status)
8402 strncat(metrics_notification, " TRUE", 5);
8403 else
8404 strncat(metrics_notification, " FALSE", 6);
8405
8406 wrqu.data.pointer = metrics_notification;
8407 wrqu.data.length = strlen(metrics_notification);
8408
8409 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
8410
8411 EXIT();
8412
8413 return VOS_STATUS_SUCCESS;
8414}
8415
8416/*
8417 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_handover
8418 * 802.11r/LFR metrics reporting function to report handover initiation
8419 *
8420 */
8421VOS_STATUS wlan_hdd_cfg80211_roam_metrics_handover(hdd_adapter_t * pAdapter,
8422 tCsrRoamInfo *pRoamInfo)
8423{
8424 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
8425 union iwreq_data wrqu;
8426
8427 ENTER();
8428
8429 if (NULL == pAdapter)
8430 {
8431 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
8432 return VOS_STATUS_E_FAILURE;
8433 }
8434
8435 /* create the event */
8436 memset(&wrqu, 0, sizeof(wrqu));
8437 memset(metrics_notification, 0, sizeof(metrics_notification));
8438
8439 wrqu.data.pointer = metrics_notification;
8440 wrqu.data.length = scnprintf(metrics_notification,
8441 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_HANDOVER "
8442 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
8443
8444 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
8445
8446 EXIT();
8447
8448 return VOS_STATUS_SUCCESS;
8449}
8450#endif
8451
Jeff Johnson295189b2012-06-20 16:38:30 -07008452/*
8453 * FUNCTION: hdd_cfg80211_scan_done_callback
8454 * scanning callback function, called after finishing scan
8455 *
8456 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308457static eHalStatus hdd_cfg80211_scan_done_callback(tHalHandle halHandle,
Jeff Johnson295189b2012-06-20 16:38:30 -07008458 void *pContext, tANI_U32 scanId, eCsrScanStatus status)
8459{
8460 struct net_device *dev = (struct net_device *) pContext;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308461 //struct wireless_dev *wdev = dev->ieee80211_ptr;
Jeff Johnson295189b2012-06-20 16:38:30 -07008462 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07008463 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8464 hdd_scaninfo_t *pScanInfo = &pHddCtx->scan_info;
Jeff Johnson295189b2012-06-20 16:38:30 -07008465 struct cfg80211_scan_request *req = NULL;
8466 int ret = 0;
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +05308467 bool aborted = false;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308468 long waitRet = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07008469
8470 ENTER();
8471
8472 hddLog(VOS_TRACE_LEVEL_INFO,
8473 "%s called with halHandle = %p, pContext = %p,"
Arif Hussain6d2a3322013-11-17 19:50:10 -08008474 "scanID = %d, returned status = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07008475 __func__, halHandle, pContext, (int) scanId, (int) status);
8476
Kiet Lamac06e2c2013-10-23 16:25:07 +05308477 pScanInfo->mScanPendingCounter = 0;
8478
Jeff Johnson295189b2012-06-20 16:38:30 -07008479 //Block on scan req completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308480 waitRet = wait_for_completion_interruptible_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07008481 &pScanInfo->scan_req_completion_event,
8482 msecs_to_jiffies(WLAN_WAIT_TIME_SCAN_REQ));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308483 if (waitRet <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -07008484 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308485 hddLog(VOS_TRACE_LEVEL_ERROR,
8486 "%s wait on scan_req_completion_event failed %ld",__func__, waitRet);
Jeff Johnson295189b2012-06-20 16:38:30 -07008487 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -07008488 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -07008489 }
8490
Yue Maef608272013-04-08 23:09:17 -07008491 if (pScanInfo->mScanPending != VOS_TRUE)
Jeff Johnson295189b2012-06-20 16:38:30 -07008492 {
8493 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -07008494 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -07008495 }
8496
8497 /* Check the scanId */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308498 if (pScanInfo->scanId != scanId)
Jeff Johnson295189b2012-06-20 16:38:30 -07008499 {
8500 hddLog(VOS_TRACE_LEVEL_INFO,
8501 "%s called with mismatched scanId pScanInfo->scanId = %d "
Arif Hussain6d2a3322013-11-17 19:50:10 -08008502 "scanId = %d", __func__, (int) pScanInfo->scanId,
Jeff Johnson295189b2012-06-20 16:38:30 -07008503 (int) scanId);
8504 }
8505
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308506 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07008507 pAdapter);
8508
8509 if (0 > ret)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308510 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008511
8512
8513 /* If any client wait scan result through WEXT
8514 * send scan done event to client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07008515 if (pHddCtx->scan_info.waitScanResult)
Jeff Johnson295189b2012-06-20 16:38:30 -07008516 {
8517 /* The other scan request waiting for current scan finish
8518 * Send event to notify current scan finished */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07008519 if(WEXT_SCAN_PENDING_DELAY == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -07008520 {
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07008521 vos_event_set(&pHddCtx->scan_info.scan_finished_event);
Jeff Johnson295189b2012-06-20 16:38:30 -07008522 }
8523 /* Send notify to WEXT client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07008524 else if(WEXT_SCAN_PENDING_PIGGYBACK == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -07008525 {
8526 struct net_device *dev = pAdapter->dev;
8527 union iwreq_data wrqu;
8528 int we_event;
8529 char *msg;
8530
8531 memset(&wrqu, '\0', sizeof(wrqu));
8532 we_event = SIOCGIWSCAN;
8533 msg = NULL;
8534 wireless_send_event(dev, we_event, &wrqu, msg);
8535 }
8536 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07008537 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07008538
8539 /* Get the Scan Req */
8540 req = pAdapter->request;
8541
8542 if (!req)
8543 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08008544 hddLog(VOS_TRACE_LEVEL_ERROR, "request is became NULL");
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07008545 pScanInfo->mScanPending = VOS_FALSE;
Jeff Johnsone7245742012-09-05 17:12:55 -07008546 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -07008547 }
8548
8549 /*
8550 * setting up 0, just in case.
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308551 */
Jeff Johnson295189b2012-06-20 16:38:30 -07008552 req->n_ssids = 0;
8553 req->n_channels = 0;
8554 req->ie = 0;
8555
Jeff Johnson295189b2012-06-20 16:38:30 -07008556 pAdapter->request = NULL;
Jeff Johnsone7245742012-09-05 17:12:55 -07008557 /* Scan is no longer pending */
8558 pScanInfo->mScanPending = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07008559
Madan Mohan Koyyalamudib764bf82012-10-11 16:38:51 -07008560 /*
8561 * cfg80211_scan_done informing NL80211 about completion
8562 * of scanning
8563 */
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +05308564 if (status == eCSR_SCAN_ABORT || status == eCSR_SCAN_FAILURE)
8565 {
8566 aborted = true;
8567 }
8568 cfg80211_scan_done(req, aborted);
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -08008569 complete(&pScanInfo->abortscan_event_var);
Jeff Johnson295189b2012-06-20 16:38:30 -07008570
Jeff Johnsone7245742012-09-05 17:12:55 -07008571allow_suspend:
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07008572 /* release the wake lock at the end of the scan*/
8573 hdd_allow_suspend();
Jeff Johnsone7245742012-09-05 17:12:55 -07008574
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -07008575 /* Acquire wakelock to handle the case where APP's tries to suspend
8576 * immediatly after the driver gets connect request(i.e after scan)
8577 * from supplicant, this result in app's is suspending and not able
8578 * to process the connect request to AP */
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +05308579 hdd_prevent_suspend_timeout(1000);
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -07008580
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07008581#ifdef FEATURE_WLAN_TDLS
c_hpothu3c8f8e82014-06-02 18:01:50 +05308582 if (!(eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode))
8583 {
8584 wlan_hdd_tdls_scan_done_callback(pAdapter);
8585 }
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07008586#endif
8587
Jeff Johnson295189b2012-06-20 16:38:30 -07008588 EXIT();
8589 return 0;
8590}
8591
8592/*
Rashmi Ramannab1429032014-04-26 14:59:09 +05308593 * FUNCTION: hdd_isConnectionInProgress
8594 * Go through each adapter and check if Connection is in progress
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08008595 *
8596 */
Rashmi Ramannab1429032014-04-26 14:59:09 +05308597v_BOOL_t hdd_isConnectionInProgress( hdd_context_t *pHddCtx )
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08008598{
8599 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
8600 hdd_station_ctx_t *pHddStaCtx = NULL;
8601 hdd_adapter_t *pAdapter = NULL;
8602 VOS_STATUS status = 0;
8603 v_U8_t staId = 0;
8604 v_U8_t *staMac = NULL;
8605
c_hpothu9b781ba2013-12-30 20:57:45 +05308606 if (TRUE == pHddCtx->btCoexModeSet)
8607 {
8608 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Rashmi Ramannab1429032014-04-26 14:59:09 +05308609 FL("BTCoex Mode operation in progress"));
8610 return VOS_TRUE;
c_hpothu9b781ba2013-12-30 20:57:45 +05308611 }
8612
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08008613 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
8614
8615 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
8616 {
8617 pAdapter = pAdapterNode->pAdapter;
8618
8619 if( pAdapter )
8620 {
8621 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05308622 "%s: Adapter with device mode %s (%d) exists",
8623 __func__, hdd_device_modetoString(pAdapter->device_mode),
8624 pAdapter->device_mode);
Rashmi Ramannab1429032014-04-26 14:59:09 +05308625 if (((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
8626 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
8627 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode)) &&
8628 (eConnectionState_Connecting ==
8629 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
8630 {
8631 hddLog(VOS_TRACE_LEVEL_ERROR,
8632 "%s: %p(%d) Connection is in progress", __func__,
8633 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
8634 return VOS_TRUE;
8635 }
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08008636 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05308637 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
8638 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08008639 {
8640 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
8641 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05308642 (VOS_FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08008643 {
8644 staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]);
8645 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain24bafea2013-11-15 15:10:03 -08008646 "%s: client " MAC_ADDRESS_STR
8647 " is in the middle of WPS/EAPOL exchange.", __func__,
8648 MAC_ADDR_ARRAY(staMac));
Rashmi Ramannab1429032014-04-26 14:59:09 +05308649 return VOS_TRUE;
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08008650 }
8651 }
8652 else if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) ||
8653 (WLAN_HDD_P2P_GO == pAdapter->device_mode))
8654 {
8655 for (staId = 0; staId < WLAN_MAX_STA_COUNT; staId++)
8656 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308657 if ((pAdapter->aStaInfo[staId].isUsed) &&
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08008658 (WLANTL_STA_CONNECTED == pAdapter->aStaInfo[staId].tlSTAState))
8659 {
8660 staMac = (v_U8_t *) &(pAdapter->aStaInfo[staId].macAddrSTA.bytes[0]);
8661
8662 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain24bafea2013-11-15 15:10:03 -08008663 "%s: client " MAC_ADDRESS_STR " of SoftAP/P2P-GO is in the "
8664 "middle of WPS/EAPOL exchange.", __func__,
8665 MAC_ADDR_ARRAY(staMac));
Rashmi Ramannab1429032014-04-26 14:59:09 +05308666 return VOS_TRUE;
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08008667 }
8668 }
8669 }
8670 }
8671 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
8672 pAdapterNode = pNext;
8673 }
Rashmi Ramannab1429032014-04-26 14:59:09 +05308674 return VOS_FALSE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308675}
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08008676
8677/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +05308678 * FUNCTION: __wlan_hdd_cfg80211_scan
Jeff Johnson295189b2012-06-20 16:38:30 -07008679 * this scan respond to scan trigger and update cfg80211 scan database
8680 * later, scan dump command can be used to recieve scan results
8681 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +05308682int __wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -08008683#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
8684 struct net_device *dev,
8685#endif
8686 struct cfg80211_scan_request *request)
8687{
Siddharth Bhal0c162d02014-05-06 19:50:42 +05308688 hdd_adapter_t *pAdapter = NULL;
8689 hdd_context_t *pHddCtx = NULL;
8690 hdd_wext_state_t *pwextBuf = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308691 hdd_config_t *cfg_param = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008692 tCsrScanRequest scanRequest;
8693 tANI_U8 *channelList = NULL, i;
8694 v_U32_t scanId = 0;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308695 int status;
8696 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008697 v_U8_t* pP2pIe = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008698
Siddharth Bhal0c162d02014-05-06 19:50:42 +05308699#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
8700 struct net_device *dev = NULL;
8701 if (NULL == request)
8702 {
8703 hddLog(VOS_TRACE_LEVEL_ERROR,
8704 "%s: scan req param null", __func__);
8705 return -EINVAL;
8706 }
8707 dev = request->wdev->netdev;
8708#endif
8709
8710 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
8711 pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
8712 pwextBuf = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
8713
Jeff Johnson295189b2012-06-20 16:38:30 -07008714 ENTER();
8715
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308716
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05308717 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
8718 __func__, hdd_device_modetoString(pAdapter->device_mode),
8719 pAdapter->device_mode);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308720
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308721 status = wlan_hdd_validate_context(pHddCtx);
8722
8723 if (0 != status)
8724 {
8725 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8726 "%s: HDD context is not valid", __func__);
8727 return status;
8728 }
8729
Siddharth Bhal0c162d02014-05-06 19:50:42 +05308730 if (NULL == pwextBuf)
8731 {
8732 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: invalid WEXT state\n",
8733 __func__);
8734 return -EIO;
8735 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308736 cfg_param = pHddCtx->cfg_ini;
8737 pScanInfo = &pHddCtx->scan_info;
8738
Jeff Johnson295189b2012-06-20 16:38:30 -07008739#ifdef WLAN_BTAMP_FEATURE
8740 //Scan not supported when AMP traffic is on.
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008741 if (VOS_TRUE == WLANBAP_AmpSessionOn())
Jeff Johnson295189b2012-06-20 16:38:30 -07008742 {
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08008743 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07008744 "%s: No scanning when AMP is on", __func__);
8745 return -EOPNOTSUPP;
8746 }
8747#endif
8748 //Scan on any other interface is not supported.
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008749 if (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07008750 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008751 hddLog(VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05308752 "%s: Not scanning on device_mode = %s (%d)",
8753 __func__, hdd_device_modetoString(pAdapter->device_mode),
8754 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07008755 return -EOPNOTSUPP;
8756 }
8757
8758 if (TRUE == pScanInfo->mScanPending)
8759 {
Kiet Lamac06e2c2013-10-23 16:25:07 +05308760 if ( MAX_PENDING_LOG > pScanInfo->mScanPendingCounter++ )
8761 {
8762 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: mScanPending is TRUE", __func__);
8763 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008764 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -07008765 }
8766
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308767 //Don't Allow Scan and return busy if Remain On
Jeff Johnson32d95a32012-09-10 13:15:23 -07008768 //Channel and action frame is pending
8769 //Otherwise Cancel Remain On Channel and allow Scan
8770 //If no action frame pending
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008771 if (0 != wlan_hdd_check_remain_on_channel(pAdapter))
Jeff Johnson32d95a32012-09-10 13:15:23 -07008772 {
Kiet Lamac06e2c2013-10-23 16:25:07 +05308773 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Remain On Channel Pending", __func__);
Jeff Johnson32d95a32012-09-10 13:15:23 -07008774 return -EBUSY;
8775 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008776#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07008777 /* if tdls disagree scan right now, return immediately.
8778 tdls will schedule the scan when scan is allowed. (return SUCCESS)
8779 or will reject the scan if any TDLS is in progress. (return -EBUSY)
8780 */
8781 status = wlan_hdd_tdls_scan_callback (pAdapter,
8782 wiphy,
8783#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
8784 dev,
Gopichand Nakkalac3c42b92013-03-20 19:42:34 -07008785#endif
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07008786 request);
8787 if(status <= 0)
8788 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05308789 if(!status)
8790 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS in progress."
8791 "scan rejected %d", __func__, status);
8792 else
8793 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS teardown is ongoing %d",
8794 __func__, status);
8795
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07008796 return status;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008797 }
8798#endif
Jeff Johnson32d95a32012-09-10 13:15:23 -07008799
Jeff Johnson295189b2012-06-20 16:38:30 -07008800 if (mutex_lock_interruptible(&pHddCtx->tmInfo.tmOperationLock))
8801 {
8802 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_ERROR,
Jeff Johnson1250df42012-12-10 14:31:52 -08008803 "%s: Acquire lock fail", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008804 return -EAGAIN;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308805 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008806 if (TRUE == pHddCtx->tmInfo.tmAction.enterImps)
8807 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05308808 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07008809 "%s: MAX TM Level Scan not allowed", __func__);
8810 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308811 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -07008812 }
8813 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
8814
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08008815 /* Check if scan is allowed at this point of time.
8816 */
Rashmi Ramannab1429032014-04-26 14:59:09 +05308817 if (hdd_isConnectionInProgress(pHddCtx))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08008818 {
8819 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Scan not allowed", __func__);
8820 return -EBUSY;
8821 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308822
Jeff Johnson295189b2012-06-20 16:38:30 -07008823 vos_mem_zero( &scanRequest, sizeof(scanRequest));
8824
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05308825 hddLog(VOS_TRACE_LEVEL_INFO, "scan request for ssid = %d",
8826 (int)request->n_ssids);
8827
8828 /* Even though supplicant doesn't provide any SSIDs, n_ssids is set to 1.
8829 * Becasue of this, driver is assuming that this is not wildcard scan and so
8830 * is not aging out the scan results.
8831 */
8832 if (request->ssids && '\0' == request->ssids->ssid[0])
Jeff Johnson295189b2012-06-20 16:38:30 -07008833 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05308834 request->n_ssids = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07008835 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05308836
8837 if ((request->ssids) && (0 < request->n_ssids))
8838 {
8839 tCsrSSIDInfo *SsidInfo;
8840 int j;
8841 scanRequest.SSIDs.numOfSSIDs = request->n_ssids;
8842 /* Allocate num_ssid tCsrSSIDInfo structure */
8843 SsidInfo = scanRequest.SSIDs.SSIDList =
8844 ( tCsrSSIDInfo *)vos_mem_malloc(
8845 request->n_ssids*sizeof(tCsrSSIDInfo));
8846
8847 if(NULL == scanRequest.SSIDs.SSIDList)
8848 {
8849 hddLog(VOS_TRACE_LEVEL_ERROR,
8850 "%s: memory alloc failed SSIDInfo buffer", __func__);
8851 return -ENOMEM;
8852 }
8853
8854 /* copy all the ssid's and their length */
8855 for(j = 0; j < request->n_ssids; j++, SsidInfo++)
8856 {
8857 /* get the ssid length */
8858 SsidInfo->SSID.length = request->ssids[j].ssid_len;
8859 vos_mem_copy(SsidInfo->SSID.ssId, &request->ssids[j].ssid[0],
8860 SsidInfo->SSID.length);
8861 SsidInfo->SSID.ssId[SsidInfo->SSID.length] = '\0';
8862 hddLog(VOS_TRACE_LEVEL_INFO, "SSID number %d: %s",
8863 j, SsidInfo->SSID.ssId);
8864 }
8865 /* set the scan type to active */
8866 scanRequest.scanType = eSIR_ACTIVE_SCAN;
8867 }
8868 else if(WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -07008869 {
Siddharth Bhal0c162d02014-05-06 19:50:42 +05308870 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
8871 TRACE_CODE_HDD_CFG80211_SCAN,
8872 pAdapter->sessionId, 0));
Jeff Johnson295189b2012-06-20 16:38:30 -07008873 /* set the scan type to active */
8874 scanRequest.scanType = eSIR_ACTIVE_SCAN;
Jeff Johnson295189b2012-06-20 16:38:30 -07008875 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05308876 else
8877 {
8878 /*Set the scan type to default type, in this case it is ACTIVE*/
8879 scanRequest.scanType = pScanInfo->scan_mode;
8880 }
8881 scanRequest.minChnTime = cfg_param->nActiveMinChnTime;
8882 scanRequest.maxChnTime = cfg_param->nActiveMaxChnTime;
Jeff Johnson295189b2012-06-20 16:38:30 -07008883
8884 /* set BSSType to default type */
8885 scanRequest.BSSType = eCSR_BSS_TYPE_ANY;
8886
8887 /*TODO: scan the requested channels only*/
8888
8889 /*Right now scanning all the channels */
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05308890 if (MAX_CHANNEL < request->n_channels)
Jeff Johnson295189b2012-06-20 16:38:30 -07008891 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05308892 hddLog(VOS_TRACE_LEVEL_WARN,
8893 "No of Scan Channels exceeded limit: %d", request->n_channels);
8894 request->n_channels = MAX_CHANNEL;
8895 }
8896
8897 hddLog(VOS_TRACE_LEVEL_INFO,
8898 "No of Scan Channels: %d", request->n_channels);
8899
8900
8901 if( request->n_channels )
8902 {
8903 char chList [(request->n_channels*5)+1];
8904 int len;
8905 channelList = vos_mem_malloc( request->n_channels );
8906 if( NULL == channelList )
c_hpothu53512302014-04-15 18:49:53 +05308907 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05308908 hddLog(VOS_TRACE_LEVEL_ERROR,
8909 "%s: memory alloc failed channelList", __func__);
8910 status = -ENOMEM;
8911 goto free_mem;
c_hpothu53512302014-04-15 18:49:53 +05308912 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05308913
8914 for( i = 0, len = 0; i < request->n_channels ; i++ )
8915 {
8916 channelList[i] = request->channels[i]->hw_value;
8917 len += snprintf(chList+len, 5, "%d ", channelList[i]);
8918 }
8919
Nirav Shah20ac06f2013-12-12 18:14:06 +05308920 hddLog(VOS_TRACE_LEVEL_INFO,
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05308921 "Channel-List: %s ", chList);
8922 }
c_hpothu53512302014-04-15 18:49:53 +05308923
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05308924 scanRequest.ChannelInfo.numOfChannels = request->n_channels;
8925 scanRequest.ChannelInfo.ChannelList = channelList;
8926
8927 /* set requestType to full scan */
8928 scanRequest.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
8929
8930 /* Flush the scan results(only p2p beacons) for STA scan and P2P
8931 * search (Flush on both full scan and social scan but not on single
8932 * channel scan).P2P search happens on 3 social channels (1, 6, 11)
8933 */
8934
8935 /* Supplicant does single channel scan after 8-way handshake
8936 * and in that case driver shoudnt flush scan results. If
8937 * driver flushes the scan results here and unfortunately if
8938 * the AP doesnt respond to our probe req then association
8939 * fails which is not desired
8940 */
8941
8942 if( request->n_channels != WLAN_HDD_P2P_SINGLE_CHANNEL_SCAN )
8943 {
8944 hddLog(VOS_TRACE_LEVEL_DEBUG, "Flushing P2P Results");
8945 sme_ScanFlushP2PResult( WLAN_HDD_GET_HAL_CTX(pAdapter),
8946 pAdapter->sessionId );
8947 }
8948
8949 if( request->ie_len )
8950 {
8951 /* save this for future association (join requires this) */
8952 /*TODO: Array needs to be converted to dynamic allocation,
8953 * as multiple ie.s can be sent in cfg80211_scan_request structure
8954 * CR 597966
8955 */
8956 memset( &pScanInfo->scanAddIE, 0, sizeof(pScanInfo->scanAddIE) );
8957 memcpy( pScanInfo->scanAddIE.addIEdata, request->ie, request->ie_len);
8958 pScanInfo->scanAddIE.length = request->ie_len;
8959
8960 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
8961 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
8962 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -07008963 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05308964 if ( request->ie_len <= SIR_MAC_MAX_IE_LENGTH)
Jeff Johnson295189b2012-06-20 16:38:30 -07008965 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05308966 pwextBuf->roamProfile.nAddIEScanLength = request->ie_len;
8967 memcpy( pwextBuf->roamProfile.addIEScan,
8968 request->ie, request->ie_len);
8969 }
8970 else
8971 {
8972 hddLog(VOS_TRACE_LEVEL_ERROR, "Scan Ie length is invalid:"
8973 "%zu", request->ie_len);
Jeff Johnson295189b2012-06-20 16:38:30 -07008974 }
8975
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05308976 }
8977 scanRequest.uIEFieldLen = pScanInfo->scanAddIE.length;
8978 scanRequest.pIEField = pScanInfo->scanAddIE.addIEdata;
8979
8980 pP2pIe = wlan_hdd_get_p2p_ie_ptr((v_U8_t*)request->ie,
8981 request->ie_len);
8982 if (pP2pIe != NULL)
8983 {
8984#ifdef WLAN_FEATURE_P2P_DEBUG
8985 if (((globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED) ||
8986 (globalP2PConnectionStatus == P2P_GO_NEG_PROCESS)) &&
8987 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Nirav Shah20ac06f2013-12-12 18:14:06 +05308988 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05308989 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_1;
8990 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
8991 "Go nego completed to Connection is started");
8992 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
8993 "for 8way Handshake");
Nirav Shah20ac06f2013-12-12 18:14:06 +05308994 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05308995 else if((globalP2PConnectionStatus == P2P_CLIENT_DISCONNECTED_STATE) &&
8996 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -07008997 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05308998 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_2;
8999 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
9000 "Disconnected state to Connection is started");
9001 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
9002 "for 4way Handshake");
9003 }
9004#endif
9005
9006 /* no_cck will be set during p2p find to disable 11b rates */
9007 if(TRUE == request->no_cck)
9008 {
9009 hddLog(VOS_TRACE_LEVEL_INFO,
9010 "%s: This is a P2P Search", __func__);
9011 scanRequest.p2pSearch = 1;
9012
9013 if( request->n_channels == WLAN_HDD_P2P_SOCIAL_CHANNELS )
Agarwal Ashish4f616132013-12-30 23:32:50 +05309014 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05309015 /* set requestType to P2P Discovery */
9016 scanRequest.requestType = eCSR_SCAN_P2P_DISCOVERY;
9017 }
9018
9019 /*
9020 Skip Dfs Channel in case of P2P Search
9021 if it is set in ini file
9022 */
9023 if(cfg_param->skipDfsChnlInP2pSearch)
9024 {
9025 scanRequest.skipDfsChnlInP2pSearch = 1;
Agarwal Ashish4f616132013-12-30 23:32:50 +05309026 }
9027 else
9028 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05309029 scanRequest.skipDfsChnlInP2pSearch = 0;
Agarwal Ashish4f616132013-12-30 23:32:50 +05309030 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009031
Agarwal Ashish4f616132013-12-30 23:32:50 +05309032 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009033 }
9034 }
9035
9036 INIT_COMPLETION(pScanInfo->scan_req_completion_event);
9037
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07009038 /* acquire the wakelock to avoid the apps suspend during the scan. To
9039 * address the following issues.
9040 * 1) Disconnected scenario: we are not allowing the suspend as WLAN is not in
9041 * BMPS/IMPS this result in android trying to suspend aggressively and backing off
9042 * for long time, this result in apps running at full power for long time.
9043 * 2) Connected scenario: If we allow the suspend during the scan, RIVA will
9044 * be stuck in full power because of resume BMPS
9045 */
9046 hdd_prevent_suspend();
Jeff Johnsone7245742012-09-05 17:12:55 -07009047
Nirav Shah20ac06f2013-12-12 18:14:06 +05309048 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
9049 "requestType %d, scanType %d, minChnTime %d, maxChnTime %d,"
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309050 "p2pSearch %d, skipDfsChnlInP2pSearch %d",
9051 scanRequest.requestType, scanRequest.scanType,
9052 scanRequest.minChnTime, scanRequest.maxChnTime,
Nirav Shah20ac06f2013-12-12 18:14:06 +05309053 scanRequest.p2pSearch, scanRequest.skipDfsChnlInP2pSearch);
9054
Jeff Johnsone7245742012-09-05 17:12:55 -07009055 status = sme_ScanRequest( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07009056 pAdapter->sessionId, &scanRequest, &scanId,
9057 &hdd_cfg80211_scan_done_callback, dev );
Jeff Johnsone7245742012-09-05 17:12:55 -07009058
Jeff Johnson295189b2012-06-20 16:38:30 -07009059 if (eHAL_STATUS_SUCCESS != status)
9060 {
9061 hddLog(VOS_TRACE_LEVEL_ERROR,
9062 "%s: sme_ScanRequest returned error %d", __func__, status);
9063 complete(&pScanInfo->scan_req_completion_event);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -07009064 if(eHAL_STATUS_RESOURCES == status)
9065 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05309066 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: HO is in progress."
9067 "So defer the scan by informing busy",__func__);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -07009068 status = -EBUSY;
9069 } else {
9070 status = -EIO;
9071 }
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07009072 hdd_allow_suspend();
Jeff Johnson295189b2012-06-20 16:38:30 -07009073 goto free_mem;
9074 }
9075
9076 pScanInfo->mScanPending = TRUE;
9077 pAdapter->request = request;
9078 pScanInfo->scanId = scanId;
9079
9080 complete(&pScanInfo->scan_req_completion_event);
9081
9082free_mem:
9083 if( scanRequest.SSIDs.SSIDList )
9084 {
9085 vos_mem_free(scanRequest.SSIDs.SSIDList);
9086 }
9087
9088 if( channelList )
9089 vos_mem_free( channelList );
9090
9091 EXIT();
9092
9093 return status;
9094}
9095
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +05309096int wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
9097#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
9098 struct net_device *dev,
9099#endif
9100 struct cfg80211_scan_request *request)
9101{
9102 int ret;
9103
9104 vos_ssr_protect(__func__);
9105 ret = __wlan_hdd_cfg80211_scan(wiphy,
9106#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
9107 dev,
9108#endif
9109 request);
9110 vos_ssr_unprotect(__func__);
9111
9112 return ret;
9113}
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07009114
9115void hdd_select_cbmode( hdd_adapter_t *pAdapter,v_U8_t operationChannel)
9116{
9117 v_U8_t iniDot11Mode =
9118 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->dot11Mode;
9119 eHddDot11Mode hddDot11Mode = iniDot11Mode;
9120
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +05309121 hddLog(LOG1, FL("Channel Bonding Mode Selected is %u"),
9122 iniDot11Mode);
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07009123 switch ( iniDot11Mode )
9124 {
9125 case eHDD_DOT11_MODE_AUTO:
9126 case eHDD_DOT11_MODE_11ac:
9127 case eHDD_DOT11_MODE_11ac_ONLY:
9128#ifdef WLAN_FEATURE_11AC
9129 hddDot11Mode = eHDD_DOT11_MODE_11ac;
9130#else
9131 hddDot11Mode = eHDD_DOT11_MODE_11n;
9132#endif
9133 break;
9134 case eHDD_DOT11_MODE_11n:
9135 case eHDD_DOT11_MODE_11n_ONLY:
9136 hddDot11Mode = eHDD_DOT11_MODE_11n;
9137 break;
9138 default:
9139 hddDot11Mode = iniDot11Mode;
9140 break;
9141 }
9142 /* This call decides required channel bonding mode */
9143 sme_SelectCBMode((WLAN_HDD_GET_CTX(pAdapter)->hHal),
9144 hdd_cfg_xlate_to_csr_phy_mode(hddDot11Mode),
9145 operationChannel);
9146}
9147
Jeff Johnson295189b2012-06-20 16:38:30 -07009148/*
9149 * FUNCTION: wlan_hdd_cfg80211_connect_start
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309150 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -07009151 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309152int wlan_hdd_cfg80211_connect_start( hdd_adapter_t *pAdapter,
Jeff Johnson32d95a32012-09-10 13:15:23 -07009153 const u8 *ssid, size_t ssid_len, const u8 *bssid, u8 operatingChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -07009154{
9155 int status = 0;
9156 hdd_wext_state_t *pWextState;
Yue Mae36e3552014-03-05 17:06:20 -08009157 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07009158 v_U32_t roamId;
9159 tCsrRoamProfile *pRoamProfile;
Jeff Johnson295189b2012-06-20 16:38:30 -07009160 eCsrAuthType RSNAuthType;
9161
9162 ENTER();
9163
9164 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Yue Mae36e3552014-03-05 17:06:20 -08009165 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9166
9167 status = wlan_hdd_validate_context(pHddCtx);
9168 if (status)
9169 {
9170 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9171 "%s: HDD context is not valid!", __func__);
9172 return status;
9173 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309174
Jeff Johnson295189b2012-06-20 16:38:30 -07009175 if (SIR_MAC_MAX_SSID_LENGTH < ssid_len)
9176 {
9177 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wrong SSID len", __func__);
9178 return -EINVAL;
9179 }
9180
9181 pRoamProfile = &pWextState->roamProfile;
9182
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309183 if (pRoamProfile)
Jeff Johnson295189b2012-06-20 16:38:30 -07009184 {
Jeff Johnsone7245742012-09-05 17:12:55 -07009185 hdd_station_ctx_t *pHddStaCtx;
9186 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07009187
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309188 if (HDD_WMM_USER_MODE_NO_QOS ==
Jeff Johnson295189b2012-06-20 16:38:30 -07009189 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->WmmMode)
9190 {
9191 /*QoS not enabled in cfg file*/
9192 pRoamProfile->uapsd_mask = 0;
9193 }
9194 else
9195 {
9196 /*QoS enabled, update uapsd mask from cfg file*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309197 pRoamProfile->uapsd_mask =
Jeff Johnson295189b2012-06-20 16:38:30 -07009198 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask;
9199 }
9200
9201 pRoamProfile->SSIDs.numOfSSIDs = 1;
9202 pRoamProfile->SSIDs.SSIDList->SSID.length = ssid_len;
9203 vos_mem_zero(pRoamProfile->SSIDs.SSIDList->SSID.ssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309204 sizeof(pRoamProfile->SSIDs.SSIDList->SSID.ssId));
Jeff Johnson295189b2012-06-20 16:38:30 -07009205 vos_mem_copy((void *)(pRoamProfile->SSIDs.SSIDList->SSID.ssId),
9206 ssid, ssid_len);
9207
9208 if (bssid)
9209 {
9210 pRoamProfile->BSSIDs.numOfBSSIDs = 1;
9211 vos_mem_copy((void *)(pRoamProfile->BSSIDs.bssid), bssid,
9212 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309213 /* Save BSSID in seperate variable as well, as RoamProfile
9214 BSSID is getting zeroed out in the association process. And in
Jeff Johnson295189b2012-06-20 16:38:30 -07009215 case of join failure we should send valid BSSID to supplicant
9216 */
9217 vos_mem_copy((void *)(pWextState->req_bssId), bssid,
9218 WNI_CFG_BSSID_LEN);
9219 }
Dhanashri Atre51981c62013-06-13 11:47:57 -07009220 else
9221 {
9222 vos_mem_zero((void *)(pRoamProfile->BSSIDs.bssid),WNI_CFG_BSSID_LEN);
9223 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009224
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +05309225 hddLog(LOG1, FL("Connect to SSID: %s opertating Channel: %u"),
9226 pRoamProfile->SSIDs.SSIDList->SSID.ssId, operatingChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -07009227 if ((IW_AUTH_WPA_VERSION_WPA == pWextState->wpaVersion) ||
9228 (IW_AUTH_WPA_VERSION_WPA2 == pWextState->wpaVersion))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309229 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009230 /*set gen ie*/
9231 hdd_SetGENIEToCsr(pAdapter, &RSNAuthType);
9232 /*set auth*/
9233 hdd_set_csr_auth_type(pAdapter, RSNAuthType);
9234 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009235#ifdef FEATURE_WLAN_WAPI
9236 if (pAdapter->wapi_info.nWapiMode)
9237 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07009238 hddLog(LOG1, "%s: Setting WAPI AUTH Type and Encryption Mode values", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009239 switch (pAdapter->wapi_info.wapiAuthMode)
9240 {
9241 case WAPI_AUTH_MODE_PSK:
9242 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07009243 hddLog(LOG1, "%s: WAPI AUTH TYPE: PSK: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07009244 pAdapter->wapi_info.wapiAuthMode);
9245 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_PSK;
9246 break;
9247 }
9248 case WAPI_AUTH_MODE_CERT:
9249 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07009250 hddLog(LOG1, "%s: WAPI AUTH TYPE: CERT: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07009251 pAdapter->wapi_info.wapiAuthMode);
9252 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE;
9253 break;
9254 }
9255 } // End of switch
9256 if ( pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_PSK ||
9257 pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_CERT)
9258 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07009259 hddLog(LOG1, "%s: WAPI PAIRWISE/GROUP ENCRYPTION: WPI", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009260 pRoamProfile->AuthType.numEntries = 1;
9261 pRoamProfile->EncryptionType.numEntries = 1;
9262 pRoamProfile->EncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
9263 pRoamProfile->mcEncryptionType.numEntries = 1;
9264 pRoamProfile->mcEncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
9265 }
9266 }
9267#endif /* FEATURE_WLAN_WAPI */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309268#ifdef WLAN_FEATURE_GTK_OFFLOAD
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05309269 /* Initializing gtkOffloadReqParams */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309270 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
9271 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
9272 {
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05309273 memset(&pHddStaCtx->gtkOffloadReqParams, 0,
9274 sizeof (tSirGtkOffloadParams));
9275 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_DISABLE;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309276 }
9277#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009278 pRoamProfile->csrPersona = pAdapter->device_mode;
9279
Jeff Johnson32d95a32012-09-10 13:15:23 -07009280 if( operatingChannel )
9281 {
9282 pRoamProfile->ChannelInfo.ChannelList = &operatingChannel;
9283 pRoamProfile->ChannelInfo.numOfChannels = 1;
9284 }
Chet Lanctot186b5732013-03-18 10:26:30 -07009285 else
9286 {
9287 pRoamProfile->ChannelInfo.ChannelList = NULL;
9288 pRoamProfile->ChannelInfo.numOfChannels = 0;
9289 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07009290 if ( (WLAN_HDD_IBSS == pAdapter->device_mode) && operatingChannel)
9291 {
9292 hdd_select_cbmode(pAdapter,operatingChannel);
9293 }
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +05309294
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08009295 /* change conn_state to connecting before sme_RoamConnect(), because sme_RoamConnect()
9296 * has a direct path to call hdd_smeRoamCallback(), which will change the conn_state
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309297 * If direct path, conn_state will be accordingly changed to NotConnected or Associated
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08009298 * by either hdd_AssociationCompletionHandler() or hdd_DisConnectHandler() in sme_RoamCallback()
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -08009299 * if sme_RomConnect is to be queued, Connecting state will remain until it is completed.
9300 */
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05309301 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
9302 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode)
Abhishek Singhf4669da2014-05-26 15:07:49 +05309303 {
9304 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9305 "%s: Set HDD connState to eConnectionState_Connecting",
9306 __func__);
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -08009307 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
9308 eConnectionState_Connecting);
Abhishek Singhf4669da2014-05-26 15:07:49 +05309309 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309310 status = sme_RoamConnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07009311 pAdapter->sessionId, pRoamProfile, &roamId);
9312
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05309313 if ((eHAL_STATUS_SUCCESS != status) &&
9314 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
9315 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +05309316
9317 {
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08009318 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: sme_RoamConnect (session %d) failed with "
9319 "status %d. -> NotConnected", __func__, pAdapter->sessionId, status);
9320 /* change back to NotAssociated */
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +05309321 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08009322 eConnectionState_NotConnected);
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +05309323 }
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -08009324
9325 pRoamProfile->ChannelInfo.ChannelList = NULL;
9326 pRoamProfile->ChannelInfo.numOfChannels = 0;
9327
Jeff Johnson295189b2012-06-20 16:38:30 -07009328 }
9329 else
9330 {
9331 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid Roam profile", __func__);
9332 return -EINVAL;
9333 }
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08009334 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07009335 return status;
9336}
9337
9338/*
9339 * FUNCTION: wlan_hdd_set_cfg80211_auth_type
9340 * This function is used to set the authentication type (OPEN/SHARED).
9341 *
9342 */
9343static int wlan_hdd_cfg80211_set_auth_type(hdd_adapter_t *pAdapter,
9344 enum nl80211_auth_type auth_type)
9345{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309346 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07009347 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9348
9349 ENTER();
9350
9351 /*set authentication type*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309352 switch (auth_type)
Jeff Johnson295189b2012-06-20 16:38:30 -07009353 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009354 case NL80211_AUTHTYPE_AUTOMATIC:
Gopichand Nakkala29149562013-05-10 21:43:41 +05309355 hddLog(VOS_TRACE_LEVEL_INFO,
9356 "%s: set authentication type to AUTOSWITCH", __func__);
9357 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_AUTOSWITCH;
9358 break;
9359
9360 case NL80211_AUTHTYPE_OPEN_SYSTEM:
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07009361#ifdef WLAN_FEATURE_VOWIFI_11R
9362 case NL80211_AUTHTYPE_FT:
9363#endif /* WLAN_FEATURE_VOWIFI_11R */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309364 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -07009365 "%s: set authentication type to OPEN", __func__);
9366 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
9367 break;
9368
9369 case NL80211_AUTHTYPE_SHARED_KEY:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309370 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -07009371 "%s: set authentication type to SHARED", __func__);
9372 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_SHARED_KEY;
9373 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08009374#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -07009375 case NL80211_AUTHTYPE_NETWORK_EAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309376 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -07009377 "%s: set authentication type to CCKM WPA", __func__);
9378 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_CCKM_WPA;//eCSR_AUTH_TYPE_CCKM_RSN needs to be handled as well if required.
9379 break;
9380#endif
9381
9382
9383 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309384 hddLog(VOS_TRACE_LEVEL_ERROR,
9385 "%s: Unsupported authentication type %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07009386 auth_type);
9387 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_UNKNOWN;
9388 return -EINVAL;
9389 }
9390
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309391 pWextState->roamProfile.AuthType.authType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -07009392 pHddStaCtx->conn_info.authType;
9393 return 0;
9394}
9395
9396/*
9397 * FUNCTION: wlan_hdd_set_akm_suite
9398 * This function is used to set the key mgmt type(PSK/8021x).
9399 *
9400 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309401static int wlan_hdd_set_akm_suite( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07009402 u32 key_mgmt
9403 )
9404{
9405 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
9406 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309407
Jeff Johnson295189b2012-06-20 16:38:30 -07009408 /*set key mgmt type*/
9409 switch(key_mgmt)
9410 {
9411 case WLAN_AKM_SUITE_PSK:
Gopichand Nakkala356fb102013-03-06 12:34:04 +05309412#ifdef WLAN_FEATURE_VOWIFI_11R
9413 case WLAN_AKM_SUITE_FT_PSK:
9414#endif
9415 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to PSK",
Jeff Johnson295189b2012-06-20 16:38:30 -07009416 __func__);
9417 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_PSK;
9418 break;
9419
9420 case WLAN_AKM_SUITE_8021X:
Gopichand Nakkala356fb102013-03-06 12:34:04 +05309421#ifdef WLAN_FEATURE_VOWIFI_11R
9422 case WLAN_AKM_SUITE_FT_8021X:
9423#endif
9424 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to 8021x",
Jeff Johnson295189b2012-06-20 16:38:30 -07009425 __func__);
9426 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
9427 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08009428#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -07009429#define WLAN_AKM_SUITE_CCKM 0x00409600 /* Should be in ieee802_11_defs.h */
9430#define IW_AUTH_KEY_MGMT_CCKM 8 /* Should be in linux/wireless.h */
9431 case WLAN_AKM_SUITE_CCKM:
9432 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to CCKM",
9433 __func__);
9434 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_CCKM;
9435 break;
9436#endif
Leela Venkata Kiran Kumar Reddy Chiralae208a832014-04-27 22:34:25 -07009437#ifndef WLAN_AKM_SUITE_OSEN
9438#define WLAN_AKM_SUITE_OSEN 0x506f9a01 /* Should be in ieee802_11_defs.h */
9439 case WLAN_AKM_SUITE_OSEN:
9440 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to OSEN",
9441 __func__);
9442 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
9443 break;
9444#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009445
9446 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309447 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported key mgmt type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07009448 __func__, key_mgmt);
9449 return -EINVAL;
9450
9451 }
9452 return 0;
9453}
9454
9455/*
9456 * FUNCTION: wlan_hdd_cfg80211_set_cipher
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309457 * This function is used to set the encryption type
Jeff Johnson295189b2012-06-20 16:38:30 -07009458 * (NONE/WEP40/WEP104/TKIP/CCMP).
9459 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309460static int wlan_hdd_cfg80211_set_cipher( hdd_adapter_t *pAdapter,
9461 u32 cipher,
Jeff Johnson295189b2012-06-20 16:38:30 -07009462 bool ucast
9463 )
9464{
9465 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309466 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07009467 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9468
9469 ENTER();
9470
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309471 if (!cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -07009472 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309473 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: received cipher %d - considering none",
Jeff Johnson295189b2012-06-20 16:38:30 -07009474 __func__, cipher);
9475 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
9476 }
9477 else
9478 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309479
Jeff Johnson295189b2012-06-20 16:38:30 -07009480 /*set encryption method*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309481 switch (cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -07009482 {
9483 case IW_AUTH_CIPHER_NONE:
9484 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
9485 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309486
Jeff Johnson295189b2012-06-20 16:38:30 -07009487 case WLAN_CIPHER_SUITE_WEP40:
Gopichand Nakkala29149562013-05-10 21:43:41 +05309488 encryptionType = eCSR_ENCRYPT_TYPE_WEP40;
Jeff Johnson295189b2012-06-20 16:38:30 -07009489 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309490
Jeff Johnson295189b2012-06-20 16:38:30 -07009491 case WLAN_CIPHER_SUITE_WEP104:
Gopichand Nakkala29149562013-05-10 21:43:41 +05309492 encryptionType = eCSR_ENCRYPT_TYPE_WEP104;
Jeff Johnson295189b2012-06-20 16:38:30 -07009493 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309494
Jeff Johnson295189b2012-06-20 16:38:30 -07009495 case WLAN_CIPHER_SUITE_TKIP:
9496 encryptionType = eCSR_ENCRYPT_TYPE_TKIP;
9497 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309498
Jeff Johnson295189b2012-06-20 16:38:30 -07009499 case WLAN_CIPHER_SUITE_CCMP:
9500 encryptionType = eCSR_ENCRYPT_TYPE_AES;
9501 break;
9502#ifdef FEATURE_WLAN_WAPI
9503 case WLAN_CIPHER_SUITE_SMS4:
9504 encryptionType = eCSR_ENCRYPT_TYPE_WPI;
9505 break;
9506#endif
9507
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08009508#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -07009509 case WLAN_CIPHER_SUITE_KRK:
9510 encryptionType = eCSR_ENCRYPT_TYPE_KRK;
9511 break;
9512#endif
9513 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309514 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported cipher type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07009515 __func__, cipher);
9516 return -EOPNOTSUPP;
9517 }
9518 }
9519
9520 if (ucast)
9521 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309522 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting unicast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07009523 __func__, encryptionType);
9524 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
9525 pWextState->roamProfile.EncryptionType.numEntries = 1;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309526 pWextState->roamProfile.EncryptionType.encryptionType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -07009527 encryptionType;
9528 }
9529 else
9530 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309531 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting mcast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07009532 __func__, encryptionType);
9533 pHddStaCtx->conn_info.mcEncryptionType = encryptionType;
9534 pWextState->roamProfile.mcEncryptionType.numEntries = 1;
9535 pWextState->roamProfile.mcEncryptionType.encryptionType[0] = encryptionType;
9536 }
9537
9538 return 0;
9539}
9540
9541
9542/*
9543 * FUNCTION: wlan_hdd_cfg80211_set_ie
9544 * This function is used to parse WPA/RSN IE's.
9545 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309546int wlan_hdd_cfg80211_set_ie( hdd_adapter_t *pAdapter,
9547 u8 *ie,
Jeff Johnson295189b2012-06-20 16:38:30 -07009548 size_t ie_len
9549 )
9550{
9551 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
9552 u8 *genie = ie;
9553 v_U16_t remLen = ie_len;
9554#ifdef FEATURE_WLAN_WAPI
9555 v_U32_t akmsuite[MAX_NUM_AKM_SUITES];
9556 u16 *tmp;
9557 v_U16_t akmsuiteCount;
9558 int *akmlist;
9559#endif
9560 ENTER();
9561
9562 /* clear previous assocAddIE */
9563 pWextState->assocAddIE.length = 0;
9564 pWextState->roamProfile.bWPSAssociation = VOS_FALSE;
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -07009565 pWextState->roamProfile.bOSENAssociation = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07009566
9567 while (remLen >= 2)
9568 {
9569 v_U16_t eLen = 0;
9570 v_U8_t elementId;
9571 elementId = *genie++;
9572 eLen = *genie++;
9573 remLen -= 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309574
Arif Hussain6d2a3322013-11-17 19:50:10 -08009575 hddLog(VOS_TRACE_LEVEL_INFO, "%s: IE[0x%X], LEN[%d]",
Jeff Johnson295189b2012-06-20 16:38:30 -07009576 __func__, elementId, eLen);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309577
9578 switch ( elementId )
Jeff Johnson295189b2012-06-20 16:38:30 -07009579 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309580 case DOT11F_EID_WPA:
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07009581 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 -07009582 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309583 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07009584 "%s: Invalid WPA IE", __func__);
9585 return -EINVAL;
9586 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309587 else if (0 == memcmp(&genie[0], "\x00\x50\xf2\x04", 4))
Jeff Johnson295189b2012-06-20 16:38:30 -07009588 {
9589 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309590 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPS IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -07009591 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309592
Jeff Johnson295189b2012-06-20 16:38:30 -07009593 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
9594 {
Jeff Johnson902c9832012-12-10 14:28:09 -08009595 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE. "
9596 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -07009597 VOS_ASSERT(0);
9598 return -ENOMEM;
9599 }
9600 // WSC IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
9601 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
9602 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309603
Jeff Johnson295189b2012-06-20 16:38:30 -07009604 pWextState->roamProfile.bWPSAssociation = VOS_TRUE;
9605 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
9606 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
9607 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309608 else if (0 == memcmp(&genie[0], "\x00\x50\xf2", 3))
9609 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009610 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPA IE (len %d)",__func__, eLen + 2);
9611 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
9612 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2) /*ie_len*/);
9613 pWextState->roamProfile.pWPAReqIE = pWextState->WPARSNIE;
9614 pWextState->roamProfile.nWPAReqIELength = eLen + 2;//ie_len;
9615 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309616 else if ( (0 == memcmp(&genie[0], P2P_OUI_TYPE,
Kiet Lam8da98992013-11-21 15:59:07 +05309617 P2P_OUI_TYPE_SIZE)))
Jeff Johnson295189b2012-06-20 16:38:30 -07009618 {
9619 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309620 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set P2P 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 // P2P IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
9631 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
9632 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309633
Jeff Johnson295189b2012-06-20 16:38:30 -07009634 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
9635 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
9636 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009637#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309638 else if ( (0 == memcmp(&genie[0], WFD_OUI_TYPE,
9639 WFD_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07009640 /*Consider WFD IE, only for P2P Client */
9641 && (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
9642 {
9643 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309644 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WFD IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -07009645 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309646
Jeff Johnson295189b2012-06-20 16:38:30 -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");
Jeff Johnson295189b2012-06-20 16:38:30 -07009651 VOS_ASSERT(0);
9652 return -ENOMEM;
9653 }
9654 // WFD IE is saved to Additional IE ; it should be accumulated to handle
9655 // WPS IE + P2P IE + WFD IE
9656 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
9657 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309658
Jeff Johnson295189b2012-06-20 16:38:30 -07009659 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
9660 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
9661 }
9662#endif
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07009663 /* Appending HS 2.0 Indication Element in Assiciation Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309664 else if ( (0 == memcmp(&genie[0], HS20_OUI_TYPE,
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07009665 HS20_OUI_TYPE_SIZE)) )
9666 {
9667 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309668 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set HS20 IE(len %d)",
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07009669 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07009670
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07009671 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
9672 {
Jeff Johnson902c9832012-12-10 14:28:09 -08009673 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
9674 "Need bigger buffer space");
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07009675 VOS_ASSERT(0);
9676 return -ENOMEM;
9677 }
9678 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
9679 pWextState->assocAddIE.length += eLen + 2;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07009680
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07009681 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
9682 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
9683 }
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -07009684 /* Appending OSEN Information Element in Assiciation Request */
9685 else if ( (0 == memcmp(&genie[0], OSEN_OUI_TYPE,
9686 OSEN_OUI_TYPE_SIZE)) )
9687 {
9688 v_U16_t curAddIELen = pWextState->assocAddIE.length;
9689 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set OSEN IE(len %d)",
9690 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07009691
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -07009692 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
9693 {
9694 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
9695 "Need bigger buffer space");
9696 VOS_ASSERT(0);
9697 return -ENOMEM;
9698 }
9699 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
9700 pWextState->assocAddIE.length += eLen + 2;
9701
9702 pWextState->roamProfile.bOSENAssociation = VOS_TRUE;
9703 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
9704 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
9705 }
9706
9707 break;
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -07009708 if (WLAN_HDD_IBSS == pAdapter->device_mode) {
9709
9710 /* populating as ADDIE in beacon frames */
9711 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
9712 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, genie - 2, eLen + 2,
9713 NULL, eANI_BOOLEAN_FALSE)== eHAL_STATUS_SUCCESS)
9714 {
9715 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
9716 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
9717 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
9718 {
9719 hddLog(LOGE,
9720 "Coldn't pass "
9721 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
9722 }
9723 }/* ccmCfgSetStr(,WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, , )*/
9724 else
9725 hddLog(LOGE,
9726 "Could not pass on "
9727 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
9728
9729 /* IBSS mode doesn't contain params->proberesp_ies still
9730 beaconIE's need to be populated in probe response frames */
9731 if ( (NULL != (genie - 2)) && (0 != eLen + 2) )
9732 {
9733 u16 rem_probe_resp_ie_len = eLen + 2;
9734 u8 probe_rsp_ie_len[3] = {0};
9735 u8 counter = 0;
9736
9737 /* Check Probe Resp Length if it is greater then 255 then
9738 Store Probe Rsp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1
9739 & WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are
9740 not able Store More then 255 bytes into One Variable */
9741
9742 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
9743 {
9744 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
9745 {
9746 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
9747 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
9748 }
9749 else
9750 {
9751 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
9752 rem_probe_resp_ie_len = 0;
9753 }
9754 }
9755
9756 rem_probe_resp_ie_len = 0;
9757
9758 if (probe_rsp_ie_len[0] > 0)
9759 {
9760 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
9761 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
9762 (tANI_U8*)(genie - 2),
9763 probe_rsp_ie_len[0], NULL,
9764 eANI_BOOLEAN_FALSE)
9765 == eHAL_STATUS_FAILURE)
9766 {
9767 hddLog(LOGE,
9768 "Could not pass"
9769 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
9770 }
9771 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
9772 }
9773
9774 if (probe_rsp_ie_len[1] > 0)
9775 {
9776 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
9777 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
9778 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
9779 probe_rsp_ie_len[1], NULL,
9780 eANI_BOOLEAN_FALSE)
9781 == eHAL_STATUS_FAILURE)
9782 {
9783 hddLog(LOGE,
9784 "Could not pass"
9785 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
9786 }
9787 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
9788 }
9789
9790 if (probe_rsp_ie_len[2] > 0)
9791 {
9792 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
9793 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
9794 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
9795 probe_rsp_ie_len[2], NULL,
9796 eANI_BOOLEAN_FALSE)
9797 == eHAL_STATUS_FAILURE)
9798 {
9799 hddLog(LOGE,
9800 "Could not pass"
9801 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
9802 }
9803 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
9804 }
9805
9806 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
9807 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
9808 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
9809 {
9810 hddLog(LOGE,
9811 "Could not pass"
9812 "on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
9813 }
9814 }
9815 else
9816 {
9817 // Reset WNI_CFG_PROBE_RSP Flags
9818 wlan_hdd_reset_prob_rspies(pAdapter);
9819
9820 hddLog(VOS_TRACE_LEVEL_INFO,
9821 "%s: No Probe Response IE received in set beacon",
9822 __func__);
9823 }
9824 } /* end of if (WLAN_HDD_IBSS == pAdapter->device_mode) */
Jeff Johnson295189b2012-06-20 16:38:30 -07009825 break;
9826 case DOT11F_EID_RSN:
9827 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set RSN IE(len %d)",__func__, eLen + 2);
9828 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
9829 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2)/*ie_len*/);
9830 pWextState->roamProfile.pRSNReqIE = pWextState->WPARSNIE;
9831 pWextState->roamProfile.nRSNReqIELength = eLen + 2; //ie_len;
9832 break;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07009833 /* Appending Extended Capabilities with Interworking bit set in Assoc Req */
9834 case DOT11F_EID_EXTCAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309835 {
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07009836 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309837 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set Extended CAPS IE(len %d)",
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07009838 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309839
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07009840 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
9841 {
Jeff Johnson902c9832012-12-10 14:28:09 -08009842 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
9843 "Need bigger buffer space");
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07009844 VOS_ASSERT(0);
9845 return -ENOMEM;
9846 }
9847 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
9848 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309849
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07009850 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
9851 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
9852 break;
9853 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009854#ifdef FEATURE_WLAN_WAPI
9855 case WLAN_EID_WAPI:
9856 pAdapter->wapi_info.nWapiMode = 1; //Setting WAPI Mode to ON=1
Jeff Johnson0299d0a2013-10-30 12:37:43 -07009857 hddLog(VOS_TRACE_LEVEL_INFO, "WAPI MODE IS %u",
Jeff Johnson295189b2012-06-20 16:38:30 -07009858 pAdapter->wapi_info.nWapiMode);
9859 tmp = (u16 *)ie;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309860 tmp = tmp + 2; // Skip element Id and Len, Version
Jeff Johnson295189b2012-06-20 16:38:30 -07009861 akmsuiteCount = WPA_GET_LE16(tmp);
9862 tmp = tmp + 1;
9863 akmlist = (int *)(tmp);
9864 if(akmsuiteCount <= MAX_NUM_AKM_SUITES)
9865 {
9866 memcpy(akmsuite, akmlist, (4*akmsuiteCount));
9867 }
9868 else
9869 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08009870 hddLog(VOS_TRACE_LEVEL_FATAL, "Invalid akmSuite count");
Jeff Johnson295189b2012-06-20 16:38:30 -07009871 VOS_ASSERT(0);
9872 return -EINVAL;
9873 }
9874
9875 if (WAPI_PSK_AKM_SUITE == akmsuite[0])
9876 {
9877 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO PSK",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07009878 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009879 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_PSK;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309880 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009881 if (WAPI_CERT_AKM_SUITE == akmsuite[0])
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309882 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009883 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO CERTIFICATE",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07009884 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009885 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_CERT;
9886 }
9887 break;
9888#endif
9889 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309890 hddLog (VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07009891 "%s Set UNKNOWN IE %X", __func__, elementId);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07009892 /* when Unknown IE is received we should break and continue
9893 * to the next IE in the buffer instead we were returning
9894 * so changing this to break */
9895 break;
Jeff Johnson295189b2012-06-20 16:38:30 -07009896 }
9897 genie += eLen;
9898 remLen -= eLen;
9899 }
9900 EXIT();
9901 return 0;
9902}
9903
9904/*
Gopichand Nakkala18f0c262013-05-07 23:25:08 +05309905 * FUNCTION: hdd_isWPAIEPresent
9906 * Parse the received IE to find the WPA IE
9907 *
9908 */
9909static bool hdd_isWPAIEPresent(u8 *ie, u8 ie_len)
9910{
9911 v_U8_t eLen = 0;
9912 v_U16_t remLen = ie_len;
9913 v_U8_t elementId = 0;
9914
9915 while (remLen >= 2)
9916 {
9917 elementId = *ie++;
9918 eLen = *ie++;
9919 remLen -= 2;
9920 if (eLen > remLen)
9921 {
9922 hddLog(VOS_TRACE_LEVEL_ERROR,
9923 "%s: IE length is wrong %d", __func__, eLen);
9924 return FALSE;
9925 }
9926 if ((elementId == DOT11F_EID_WPA) && (remLen > 5))
9927 {
9928 /* OUI - 0x00 0X50 0XF2
9929 WPA Information Element - 0x01
9930 WPA version - 0x01*/
9931 if (0 == memcmp(&ie[0], "\x00\x50\xf2\x01\x01", 5))
9932 return TRUE;
9933 }
9934 ie += eLen;
9935 remLen -= eLen;
9936 }
9937 return FALSE;
9938}
9939
9940/*
Jeff Johnson295189b2012-06-20 16:38:30 -07009941 * FUNCTION: wlan_hdd_cfg80211_set_privacy
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309942 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -07009943 * parameters during connect operation.
9944 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309945int wlan_hdd_cfg80211_set_privacy( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07009946 struct cfg80211_connect_params *req
9947 )
9948{
9949 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309950 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07009951 ENTER();
9952
9953 /*set wpa version*/
9954 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
9955
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309956 if (req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -07009957 {
Gopichand Nakkala781ded42013-06-28 12:10:45 +05309958 if (NL80211_WPA_VERSION_1 == req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -07009959 {
9960 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
9961 }
9962 else if (NL80211_WPA_VERSION_2 == req->crypto.wpa_versions)
9963 {
9964 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
9965 }
9966 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309967
9968 hddLog(VOS_TRACE_LEVEL_INFO, "%s: set wpa version to %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07009969 pWextState->wpaVersion);
9970
9971 /*set authentication type*/
9972 status = wlan_hdd_cfg80211_set_auth_type(pAdapter, req->auth_type);
9973
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 authentication type ", __func__);
9978 return status;
9979 }
9980
9981 /*set key mgmt type*/
9982 if (req->crypto.n_akm_suites)
9983 {
9984 status = wlan_hdd_set_akm_suite(pAdapter, req->crypto.akm_suites[0]);
9985 if (0 > status)
9986 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309987 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set akm suite",
Jeff Johnson295189b2012-06-20 16:38:30 -07009988 __func__);
9989 return status;
9990 }
9991 }
9992
9993 /*set pairwise cipher type*/
9994 if (req->crypto.n_ciphers_pairwise)
9995 {
9996 status = wlan_hdd_cfg80211_set_cipher(pAdapter,
9997 req->crypto.ciphers_pairwise[0], true);
9998 if (0 > status)
9999 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010000 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070010001 "%s: failed to set unicast cipher type", __func__);
10002 return status;
10003 }
10004 }
10005 else
10006 {
10007 /*Reset previous cipher suite to none*/
10008 status = wlan_hdd_cfg80211_set_cipher(pAdapter, 0, true);
10009 if (0 > status)
10010 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010011 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070010012 "%s: failed to set unicast cipher type", __func__);
10013 return status;
10014 }
10015 }
10016
10017 /*set group cipher type*/
10018 status = wlan_hdd_cfg80211_set_cipher(pAdapter, req->crypto.cipher_group,
10019 false);
10020
10021 if (0 > status)
10022 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010023 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set mcast cipher type",
Jeff Johnson295189b2012-06-20 16:38:30 -070010024 __func__);
10025 return status;
10026 }
10027
Chet Lanctot186b5732013-03-18 10:26:30 -070010028#ifdef WLAN_FEATURE_11W
10029 pWextState->roamProfile.MFPEnabled = (req->mfp == NL80211_MFP_REQUIRED);
10030#endif
10031
Jeff Johnson295189b2012-06-20 16:38:30 -070010032 /*parse WPA/RSN IE, and set the correspoing fileds in Roam profile*/
10033 if (req->ie_len)
10034 {
10035 status = wlan_hdd_cfg80211_set_ie(pAdapter, req->ie, req->ie_len);
10036 if ( 0 > status)
10037 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010038 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse the WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -070010039 __func__);
10040 return status;
10041 }
10042 }
10043
10044 /*incase of WEP set default key information*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010045 if (req->key && req->key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -070010046 {
10047 if ( (WLAN_CIPHER_SUITE_WEP40 == req->crypto.ciphers_pairwise[0])
10048 || (WLAN_CIPHER_SUITE_WEP104 == req->crypto.ciphers_pairwise[0])
10049 )
10050 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010051 if ( IW_AUTH_KEY_MGMT_802_1X
Jeff Johnson295189b2012-06-20 16:38:30 -070010052 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X ))
10053 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010054 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Dynamic WEP not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -070010055 __func__);
10056 return -EOPNOTSUPP;
10057 }
10058 else
10059 {
10060 u8 key_len = req->key_len;
10061 u8 key_idx = req->key_idx;
10062
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010063 if ((eCSR_SECURITY_WEP_KEYSIZE_MAX_BYTES >= key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -070010064 && (CSR_MAX_NUM_KEY > key_idx)
10065 )
10066 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010067 hddLog(VOS_TRACE_LEVEL_INFO,
10068 "%s: setting default wep key, key_idx = %hu key_len %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070010069 __func__, key_idx, key_len);
10070 vos_mem_copy(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010071 &pWextState->roamProfile.Keys.KeyMaterial[key_idx][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070010072 req->key, key_len);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010073 pWextState->roamProfile.Keys.KeyLength[key_idx] =
Jeff Johnson295189b2012-06-20 16:38:30 -070010074 (u8)key_len;
10075 pWextState->roamProfile.Keys.defaultIndex = (u8)key_idx;
10076 }
10077 }
10078 }
10079 }
10080
10081 return status;
10082}
10083
10084/*
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053010085 * FUNCTION: wlan_hdd_try_disconnect
10086 * This function is used to disconnect from previous
10087 * connection
10088 */
10089static int wlan_hdd_try_disconnect( hdd_adapter_t *pAdapter )
10090{
10091 long ret = 0;
10092 hdd_station_ctx_t *pHddStaCtx;
10093 eMib_dot11DesiredBssType connectedBssType;
10094
10095 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
10096
10097 hdd_connGetConnectedBssType(pHddStaCtx,&connectedBssType );
10098
10099 if((eMib_dot11DesiredBssType_independent == connectedBssType) ||
10100 (eConnectionState_Associated == pHddStaCtx->conn_info.connState) ||
10101 (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState))
10102 {
10103 /* Issue disconnect to CSR */
10104 INIT_COMPLETION(pAdapter->disconnect_comp_var);
10105 if( eHAL_STATUS_SUCCESS ==
10106 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
10107 pAdapter->sessionId,
10108 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
10109 {
10110 ret = wait_for_completion_interruptible_timeout(
10111 &pAdapter->disconnect_comp_var,
10112 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
10113 if (0 >= ret)
10114 {
10115 hddLog(LOGE, FL("Failed to receive disconnect event"));
10116 return -EALREADY;
10117 }
10118 }
10119 }
10120 else if(eConnectionState_Disconnecting == pHddStaCtx->conn_info.connState)
10121 {
10122 ret = wait_for_completion_interruptible_timeout(
10123 &pAdapter->disconnect_comp_var,
10124 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
10125 if (0 >= ret)
10126 {
10127 hddLog(LOGE, FL("Failed to receive disconnect event"));
10128 return -EALREADY;
10129 }
10130 }
10131
10132 return 0;
10133}
10134
10135/*
Agarwal Ashish51325b52014-06-16 16:50:49 +053010136 * FUNCTION: __wlan_hdd_cfg80211_connect
10137 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -070010138 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053010139static int __wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070010140 struct net_device *ndev,
10141 struct cfg80211_connect_params *req
10142 )
10143{
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010144 int status;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010145 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Sushant Kaushikba6764e2014-06-30 19:52:09 +053010146 hdd_adapter_t *pHostapdAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070010147 VOS_STATUS exitbmpsStatus = VOS_STATUS_E_INVAL;
Sushant Kaushikba6764e2014-06-30 19:52:09 +053010148 hdd_context_t *pHddCtx = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070010149
10150 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010151
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010152 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10153 TRACE_CODE_HDD_CFG80211_CONNECT,
10154 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010155 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010156 "%s: device_mode = %s (%d)", __func__,
10157 hdd_device_modetoString(pAdapter->device_mode),
10158 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070010159
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010160 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -080010161 if (!pHddCtx)
10162 {
10163 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10164 "%s: HDD context is null", __func__);
Agarwal Ashish51325b52014-06-16 16:50:49 +053010165 return -EINVAL;
Rajesh Chauhana0516c62014-01-30 16:11:18 -080010166 }
10167
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010168 status = wlan_hdd_validate_context(pHddCtx);
10169
10170 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070010171 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010172 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10173 "%s: HDD context is not valid", __func__);
10174 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070010175 }
10176
Agarwal Ashish51325b52014-06-16 16:50:49 +053010177 if (vos_max_concurrent_connections_reached()) {
10178 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
10179 return -ECONNREFUSED;
10180 }
10181
Jeff Johnson295189b2012-06-20 16:38:30 -070010182#ifdef WLAN_BTAMP_FEATURE
10183 //Infra connect not supported when AMP traffic is on.
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010184 if( VOS_TRUE == WLANBAP_AmpSessionOn() )
Jeff Johnson295189b2012-06-20 16:38:30 -070010185 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010186 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070010187 "%s: No connection when AMP is on", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -080010188 return -ECONNREFUSED;
Jeff Johnson295189b2012-06-20 16:38:30 -070010189 }
10190#endif
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053010191
10192 //If Device Mode is Station Concurrent Sessions Exit BMps
10193 //P2P Mode will be taken care in Open/close adapter
10194 if((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
Agarwal Ashish51325b52014-06-16 16:50:49 +053010195 (vos_concurrent_open_sessions_running())) {
10196 exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx,
10197 WLAN_HDD_INFRA_STATION);
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053010198 }
10199
10200 /*Try disconnecting if already in connected state*/
10201 status = wlan_hdd_try_disconnect(pAdapter);
10202 if ( 0 > status)
10203 {
10204 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
10205 " connection"));
10206 return -EALREADY;
10207 }
10208
Jeff Johnson295189b2012-06-20 16:38:30 -070010209 /*initialise security parameters*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010210 status = wlan_hdd_cfg80211_set_privacy(pAdapter, req);
Jeff Johnson295189b2012-06-20 16:38:30 -070010211
10212 if ( 0 > status)
10213 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010214 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security params",
Jeff Johnson295189b2012-06-20 16:38:30 -070010215 __func__);
10216 return status;
10217 }
Sushant Kaushikba6764e2014-06-30 19:52:09 +053010218 /* For SAP + STA concurrency , driver only supports SCC.
10219 * if SAP is ON, driver will stop it and after assoc completion,
10220 * or failure, SAP will be started on STA channel to force SCC.
10221 */
10222 pHostapdAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_SOFTAP);
10223 if (pHostapdAdapter != NULL)
10224 {
10225 hddLog(VOS_TRACE_LEVEL_INFO, "Close SAP until STA is connected");
10226 if (test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags))
10227 {
10228 WLANSAP_StopBss((WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext);
10229 clear_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags);
10230 }
10231 }
Mohit Khanna765234a2012-09-11 15:08:35 -070010232 if ( req->channel )
10233 {
10234 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
10235 req->ssid_len, req->bssid,
10236 req->channel->hw_value);
10237 }
10238 else
10239 {
10240 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010241 req->ssid_len, req->bssid, 0);
Mohit Khanna765234a2012-09-11 15:08:35 -070010242 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010243
10244 if (0 > status)
10245 {
10246 //ReEnable BMPS if disabled
10247 if((VOS_STATUS_SUCCESS == exitbmpsStatus) &&
10248 (NULL != pHddCtx))
10249 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053010250 if (pHddCtx->hdd_wlan_suspended)
10251 {
10252 hdd_set_pwrparams(pHddCtx);
10253 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010254 //ReEnable Bmps and Imps back
10255 hdd_enable_bmps_imps(pHddCtx);
10256 }
Agarwal Ashish51325b52014-06-16 16:50:49 +053010257 hddLog(VOS_TRACE_LEVEL_ERROR, FL("connect failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -070010258 return status;
10259 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010260 pHddCtx->isAmpAllowed = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070010261 EXIT();
10262 return status;
10263}
10264
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053010265static int wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
10266 struct net_device *ndev,
10267 struct cfg80211_connect_params *req)
10268{
10269 int ret;
10270 vos_ssr_protect(__func__);
10271 ret = __wlan_hdd_cfg80211_connect(wiphy, ndev, req);
10272 vos_ssr_unprotect(__func__);
10273
10274 return ret;
10275}
Jeff Johnson295189b2012-06-20 16:38:30 -070010276
10277/*
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053010278 * FUNCTION: wlan_hdd_disconnect
10279 * This function is used to issue a disconnect request to SME
10280 */
10281int wlan_hdd_disconnect( hdd_adapter_t *pAdapter, u16 reason )
10282{
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010283 int status;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053010284 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010285 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053010286 long ret;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010287
10288 status = wlan_hdd_validate_context(pHddCtx);
10289
10290 if (0 != status)
10291 {
10292 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10293 "%s: HDD context is not valid", __func__);
10294 return status;
10295 }
10296
10297 pHddCtx->isAmpAllowed = VOS_TRUE;
Abhishek Singhf4669da2014-05-26 15:07:49 +053010298 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
10299 "%s: Set HDD connState to eConnectionState_Disconnecting",
10300 __func__);
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +053010301 pHddStaCtx->conn_info.connState = eConnectionState_Disconnecting;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053010302 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010303
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053010304 /*issue disconnect*/
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053010305
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053010306 status = sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
10307 pAdapter->sessionId, reason);
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053010308 if(eHAL_STATUS_CMD_NOT_QUEUED == status)
10309 {
10310 hddLog(VOS_TRACE_LEVEL_INFO,
10311 FL("status = %d, already disconnected"),
10312 (int)status );
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053010313
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053010314 }
10315 else if ( 0 != status )
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053010316 {
10317 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010318 "%s csrRoamDisconnect failure, returned %d",
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053010319 __func__, (int)status );
10320 return -EINVAL;
10321 }
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053010322 ret = wait_for_completion_interruptible_timeout(
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053010323 &pAdapter->disconnect_comp_var,
10324 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053010325 if (!ret && ( eHAL_STATUS_CMD_NOT_QUEUED != status ))
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010326 {
10327 hddLog(VOS_TRACE_LEVEL_ERROR,
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053010328 "%s: Failed to disconnect, timed out", __func__);
10329 return -ETIMEDOUT;
10330 }
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053010331 else if (ret == -ERESTARTSYS)
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053010332 {
10333 hddLog(VOS_TRACE_LEVEL_ERROR,
10334 "%s: Failed to disconnect, wait interrupted", __func__);
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053010335 return ret;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010336 }
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053010337 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
10338 FL("Set HDD connState to eConnectionState_NotConnected"));
10339 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
10340
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053010341 /*stop tx queues*/
10342 netif_tx_disable(pAdapter->dev);
10343 netif_carrier_off(pAdapter->dev);
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053010344 return 0;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053010345}
10346
10347
10348/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053010349 * FUNCTION: __wlan_hdd_cfg80211_disconnect
Jeff Johnson295189b2012-06-20 16:38:30 -070010350 * This function is used to issue a disconnect request to SME
10351 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053010352static int __wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070010353 struct net_device *dev,
10354 u16 reason
10355 )
10356{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010357 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010358 tCsrRoamProfile *pRoamProfile =
10359 &(WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter))->roamProfile;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010360 int status;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010361 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
10362 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053010363#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080010364 tANI_U8 staIdx;
10365#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010366
Jeff Johnson295189b2012-06-20 16:38:30 -070010367 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010368
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010369 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10370 TRACE_CODE_HDD_CFG80211_DISCONNECT,
10371 pAdapter->sessionId, reason));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010372 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s(%d)",
10373 __func__, hdd_device_modetoString(pAdapter->device_mode),
10374 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070010375
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010376 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Disconnect called with reason code %d",
10377 __func__, reason);
Jeff Johnson295189b2012-06-20 16:38:30 -070010378
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010379 status = wlan_hdd_validate_context(pHddCtx);
10380
10381 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070010382 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010383 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10384 "%s: HDD context is not valid", __func__);
10385 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070010386 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010387
Jeff Johnson295189b2012-06-20 16:38:30 -070010388 if (NULL != pRoamProfile)
10389 {
10390 /*issue disconnect request to SME, if station is in connected state*/
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +053010391 if ((pHddStaCtx->conn_info.connState == eConnectionState_Associated) ||
10392 (pHddStaCtx->conn_info.connState == eConnectionState_Connecting))
Jeff Johnson295189b2012-06-20 16:38:30 -070010393 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010394 eCsrRoamDisconnectReason reasonCode =
Jeff Johnson295189b2012-06-20 16:38:30 -070010395 eCSR_DISCONNECT_REASON_UNSPECIFIED;
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053010396 hdd_scaninfo_t *pScanInfo;
Jeff Johnson295189b2012-06-20 16:38:30 -070010397 switch(reason)
10398 {
10399 case WLAN_REASON_MIC_FAILURE:
10400 reasonCode = eCSR_DISCONNECT_REASON_MIC_ERROR;
10401 break;
10402
10403 case WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY:
10404 case WLAN_REASON_DISASSOC_AP_BUSY:
10405 case WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA:
10406 reasonCode = eCSR_DISCONNECT_REASON_DISASSOC;
10407 break;
10408
10409 case WLAN_REASON_PREV_AUTH_NOT_VALID:
10410 case WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA:
Abhishek Singhc3269a52014-05-21 17:22:24 +053010411 case WLAN_REASON_DEAUTH_LEAVING:
Jeff Johnson295189b2012-06-20 16:38:30 -070010412 reasonCode = eCSR_DISCONNECT_REASON_DEAUTH;
10413 break;
10414
Jeff Johnson295189b2012-06-20 16:38:30 -070010415 default:
10416 reasonCode = eCSR_DISCONNECT_REASON_UNSPECIFIED;
10417 break;
10418 }
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053010419 pScanInfo = &pHddCtx->scan_info;
10420 if (pScanInfo->mScanPending)
10421 {
Srinivas, Dasari138af4f2014-02-07 11:13:45 +053010422 hddLog(VOS_TRACE_LEVEL_INFO, "Disconnect is in progress, "
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053010423 "Aborting Scan");
Srinivas, Dasari138af4f2014-02-07 11:13:45 +053010424 hdd_abort_mac_scan(pHddCtx, pAdapter->sessionId,
10425 eCSR_SCAN_ABORT_DEFAULT);
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053010426 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010427
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080010428#ifdef FEATURE_WLAN_TDLS
10429 /* First clean up the tdls peers if any */
Gopichand Nakkala4327a152013-03-04 23:22:42 -080010430 for (staIdx = 0 ; staIdx < HDD_MAX_NUM_TDLS_STA; staIdx++)
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080010431 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -080010432 if ((pHddCtx->tdlsConnInfo[staIdx].sessionId == pAdapter->sessionId) &&
10433 (pHddCtx->tdlsConnInfo[staIdx].staId))
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080010434 {
Hoonki Lee11f7dda2013-02-14 16:55:44 -080010435 uint8 *mac;
Gopichand Nakkala4327a152013-03-04 23:22:42 -080010436 mac = pHddCtx->tdlsConnInfo[staIdx].peerMac.bytes;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080010437 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070010438 "%s: call sme_DeleteTdlsPeerSta staId %d sessionId %d " MAC_ADDRESS_STR,
Gopichand Nakkala4327a152013-03-04 23:22:42 -080010439 __func__, pHddCtx->tdlsConnInfo[staIdx].staId, pAdapter->sessionId,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070010440 MAC_ADDR_ARRAY(mac));
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080010441 sme_DeleteTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala4327a152013-03-04 23:22:42 -080010442 pAdapter->sessionId,
10443 mac);
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080010444 }
10445 }
10446#endif
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053010447 hddLog(LOG1, FL("Disconnecting with reasoncode:%u"), reasonCode);
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053010448 status = wlan_hdd_disconnect(pAdapter, reasonCode);
10449 if ( 0 != status )
Jeff Johnson295189b2012-06-20 16:38:30 -070010450 {
10451 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010452 "%s wlan_hdd_disconnect failure, returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070010453 __func__, (int)status );
10454 return -EINVAL;
10455 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010456 }
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +053010457 else
10458 {
10459 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unexpected cfg disconnect API"
10460 "called while in %d state", __func__,
10461 pHddStaCtx->conn_info.connState);
10462 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010463 }
10464 else
10465 {
10466 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid roam profile", __func__);
10467 }
10468
10469 return status;
10470}
10471
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053010472static int wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
10473 struct net_device *dev,
10474 u16 reason
10475 )
10476{
10477 int ret;
10478 vos_ssr_protect(__func__);
10479 ret = __wlan_hdd_cfg80211_disconnect(wiphy, dev, reason);
10480 vos_ssr_unprotect(__func__);
10481
10482 return ret;
10483}
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053010484
Jeff Johnson295189b2012-06-20 16:38:30 -070010485/*
10486 * FUNCTION: wlan_hdd_cfg80211_set_privacy_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010487 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -070010488 * settings in IBSS mode.
10489 */
10490static int wlan_hdd_cfg80211_set_privacy_ibss(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010491 hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070010492 struct cfg80211_ibss_params *params
10493 )
10494{
10495 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010496 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070010497 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
10498 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010499
Jeff Johnson295189b2012-06-20 16:38:30 -070010500 ENTER();
10501
10502 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
Ravi Joshib58ca0d2013-10-29 09:50:23 -070010503 vos_mem_zero(&pHddStaCtx->ibss_enc_key, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -070010504
10505 if (params->ie_len && ( NULL != params->ie) )
10506 {
Shailender Karmuchi67edd312013-06-18 16:30:48 -070010507 if (wlan_hdd_cfg80211_get_ie_ptr (params->ie,
10508 params->ie_len, WLAN_EID_RSN ))
Jeff Johnson295189b2012-06-20 16:38:30 -070010509 {
10510 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
10511 encryptionType = eCSR_ENCRYPT_TYPE_AES;
10512 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070010513 else if ( hdd_isWPAIEPresent (params->ie, params->ie_len ))
Jeff Johnson295189b2012-06-20 16:38:30 -070010514 {
Shailender Karmuchi642e9812013-05-30 14:34:49 -070010515 tDot11fIEWPA dot11WPAIE;
10516 tHalHandle halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
Shailender Karmuchi67edd312013-06-18 16:30:48 -070010517 u8 *ie;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070010518
Wilson Yang00256342013-10-10 23:13:38 -070010519 memset(&dot11WPAIE, 0, sizeof(dot11WPAIE));
Shailender Karmuchi67edd312013-06-18 16:30:48 -070010520 ie = wlan_hdd_cfg80211_get_ie_ptr (params->ie,
10521 params->ie_len, DOT11F_EID_WPA);
10522 if ( NULL != ie )
10523 {
10524 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
10525 // Unpack the WPA IE
10526 //Skip past the EID byte and length byte - and four byte WiFi OUI
10527 dot11fUnpackIeWPA((tpAniSirGlobal) halHandle,
10528 &ie[2+4],
10529 ie[1] - 4,
10530 &dot11WPAIE);
10531 /*Extract the multicast cipher, the encType for unicast
10532 cipher for wpa-none is none*/
10533 encryptionType =
10534 hdd_TranslateWPAToCsrEncryptionType(dot11WPAIE.multicast_cipher);
10535 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010536 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070010537
Jeff Johnson295189b2012-06-20 16:38:30 -070010538 status = wlan_hdd_cfg80211_set_ie(pAdapter, params->ie, params->ie_len);
10539
10540 if (0 > status)
10541 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010542 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -070010543 __func__);
10544 return status;
10545 }
10546 }
10547
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010548 pWextState->roamProfile.AuthType.authType[0] =
10549 pHddStaCtx->conn_info.authType =
Jeff Johnson295189b2012-06-20 16:38:30 -070010550 eCSR_AUTH_TYPE_OPEN_SYSTEM;
10551
10552 if (params->privacy)
10553 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010554 /* Security enabled IBSS, At this time there is no information available
10555 * about the security paramters, so initialise the encryption type to
Jeff Johnson295189b2012-06-20 16:38:30 -070010556 * eCSR_ENCRYPT_TYPE_WEP40_STATICKEY.
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010557 * The correct security parameters will be updated later in
Jeff Johnson295189b2012-06-20 16:38:30 -070010558 * wlan_hdd_cfg80211_add_key */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010559 /* Hal expects encryption type to be set inorder
Jeff Johnson295189b2012-06-20 16:38:30 -070010560 *enable privacy bit in beacons */
10561
10562 encryptionType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
10563 }
Shailender Karmuchi642e9812013-05-30 14:34:49 -070010564 VOS_TRACE (VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
10565 "encryptionType=%d", encryptionType);
Jeff Johnson295189b2012-06-20 16:38:30 -070010566 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
10567 pWextState->roamProfile.EncryptionType.numEntries = 1;
10568 pWextState->roamProfile.EncryptionType.encryptionType[0] = encryptionType;
Jeff Johnson295189b2012-06-20 16:38:30 -070010569 return status;
10570}
10571
10572/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053010573 * FUNCTION: __wlan_hdd_cfg80211_join_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010574 * This function is used to create/join an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -070010575 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053010576static int __wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070010577 struct net_device *dev,
10578 struct cfg80211_ibss_params *params
10579 )
10580{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010581 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Jeff Johnson295189b2012-06-20 16:38:30 -070010582 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
10583 tCsrRoamProfile *pRoamProfile;
10584 int status;
krunal sonie9002db2013-11-25 14:24:17 -080010585 bool alloc_bssid = VOS_FALSE;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010586 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
10587 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070010588
10589 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010590
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010591 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10592 TRACE_CODE_HDD_CFG80211_JOIN_IBSS,
10593 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010594 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010595 "%s: device_mode = %s (%d)", __func__,
10596 hdd_device_modetoString(pAdapter->device_mode),
10597 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070010598
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010599 status = wlan_hdd_validate_context(pHddCtx);
10600
10601 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070010602 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010603 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10604 "%s: HDD context is not valid", __func__);
10605 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070010606 }
10607
10608 if (NULL == pWextState)
10609 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080010610 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -070010611 __func__);
10612 return -EIO;
10613 }
10614
Agarwal Ashish51325b52014-06-16 16:50:49 +053010615 if (vos_max_concurrent_connections_reached()) {
10616 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
10617 return -ECONNREFUSED;
10618 }
10619
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053010620 /*Try disconnecting if already in connected state*/
10621 status = wlan_hdd_try_disconnect(pAdapter);
10622 if ( 0 > status)
10623 {
10624 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
10625 " IBSS connection"));
10626 return -EALREADY;
10627 }
10628
Jeff Johnson295189b2012-06-20 16:38:30 -070010629 pRoamProfile = &pWextState->roamProfile;
10630
10631 if ( eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType )
10632 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010633 hddLog (VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010634 "%s Interface type is not set to IBSS", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010635 return -EINVAL;
10636 }
10637
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070010638 /* BSSID is provided by upper layers hence no need to AUTO generate */
10639 if (NULL != params->bssid) {
10640 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
10641 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) {
10642 hddLog (VOS_TRACE_LEVEL_ERROR,
10643 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
10644 return -EIO;
10645 }
10646 }
krunal sonie9002db2013-11-25 14:24:17 -080010647 else if(pHddCtx->cfg_ini->isCoalesingInIBSSAllowed == 0)
10648 {
10649 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
10650 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
10651 {
10652 hddLog (VOS_TRACE_LEVEL_ERROR,
10653 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
10654 return -EIO;
10655 }
10656 params->bssid = vos_mem_malloc(sizeof(VOS_MAC_ADDR_SIZE));
10657 if (!params->bssid)
10658 {
10659 hddLog (VOS_TRACE_LEVEL_ERROR,
10660 "%s:Failed memory allocation", __func__);
10661 return -EIO;
10662 }
10663 vos_mem_copy((v_U8_t *)params->bssid,
10664 (v_U8_t *)&pHddCtx->cfg_ini->IbssBssid.bytes[0],
10665 VOS_MAC_ADDR_SIZE);
10666 alloc_bssid = VOS_TRUE;
10667 }
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070010668
Jeff Johnson295189b2012-06-20 16:38:30 -070010669 /* Set Channel */
Yue Maf49ba872013-08-19 12:04:25 -070010670 if (NULL !=
10671#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
10672 params->chandef.chan)
10673#else
10674 params->channel)
10675#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010676 {
10677 u8 channelNum;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070010678 v_U32_t numChans = WNI_CFG_VALID_CHANNEL_LIST_LEN;
10679 v_U8_t validChan[WNI_CFG_VALID_CHANNEL_LIST_LEN];
10680 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
10681 int indx;
Jeff Johnson295189b2012-06-20 16:38:30 -070010682
10683 /* Get channel number */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010684 channelNum =
Yue Maf49ba872013-08-19 12:04:25 -070010685 ieee80211_frequency_to_channel(
10686#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
10687 params->chandef.chan->center_freq);
10688#else
10689 params->channel->center_freq);
10690#endif
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070010691
10692 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
10693 validChan, &numChans))
Jeff Johnson295189b2012-06-20 16:38:30 -070010694 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070010695 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid channel list",
10696 __func__);
10697 return -EOPNOTSUPP;
Jeff Johnson295189b2012-06-20 16:38:30 -070010698 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070010699
10700 for (indx = 0; indx < numChans; indx++)
Jeff Johnson295189b2012-06-20 16:38:30 -070010701 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070010702 if (channelNum == validChan[indx])
10703 {
10704 break;
10705 }
10706 }
10707 if (indx >= numChans)
10708 {
10709 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Not valid Channel %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070010710 __func__, channelNum);
10711 return -EINVAL;
10712 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070010713 /* Set the Operational Channel */
10714 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: set channel %d", __func__,
10715 channelNum);
10716 pRoamProfile->ChannelInfo.numOfChannels = 1;
10717 pHddStaCtx->conn_info.operationChannel = channelNum;
10718 pRoamProfile->ChannelInfo.ChannelList =
10719 &pHddStaCtx->conn_info.operationChannel;
Jeff Johnson295189b2012-06-20 16:38:30 -070010720 }
10721
10722 /* Initialize security parameters */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010723 status = wlan_hdd_cfg80211_set_privacy_ibss(pAdapter, params);
Jeff Johnson295189b2012-06-20 16:38:30 -070010724 if (status < 0)
10725 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010726 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security parameters",
Jeff Johnson295189b2012-06-20 16:38:30 -070010727 __func__);
10728 return status;
10729 }
10730
10731 /* Issue connect start */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010732 status = wlan_hdd_cfg80211_connect_start(pAdapter, params->ssid,
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070010733 params->ssid_len, params->bssid,
10734 pHddStaCtx->conn_info.operationChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -070010735
10736 if (0 > status)
10737 {
10738 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: connect failed", __func__);
10739 return status;
10740 }
10741
krunal sonie9002db2013-11-25 14:24:17 -080010742 if (NULL != params->bssid &&
10743 pHddCtx->cfg_ini->isCoalesingInIBSSAllowed == 0 &&
10744 alloc_bssid == VOS_TRUE)
10745 {
10746 vos_mem_free(params->bssid);
10747 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010748 return 0;
10749}
10750
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053010751static int wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
10752 struct net_device *dev,
10753 struct cfg80211_ibss_params *params
10754 )
10755{
10756 int ret = 0;
10757
10758 vos_ssr_protect(__func__);
10759 ret = __wlan_hdd_cfg80211_join_ibss(wiphy, dev, params);
10760 vos_ssr_unprotect(__func__);
10761
10762 return ret;
10763}
10764
Jeff Johnson295189b2012-06-20 16:38:30 -070010765/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053010766 * FUNCTION: __wlan_hdd_cfg80211_leave_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010767 * This function is used to leave an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -070010768 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053010769static int __wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070010770 struct net_device *dev
10771 )
10772{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010773 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010774 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
10775 tCsrRoamProfile *pRoamProfile;
10776 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010777 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070010778
10779 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010780
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010781 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10782 TRACE_CODE_HDD_CFG80211_LEAVE_IBSS,
10783 pAdapter->sessionId, eCSR_DISCONNECT_REASON_IBSS_LEAVE));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010784 status = wlan_hdd_validate_context(pHddCtx);
10785
10786 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010787 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010788 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10789 "%s: HDD context is not valid", __func__);
10790 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010791 }
10792
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010793 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)", __func__,
10794 hdd_device_modetoString(pAdapter->device_mode),
10795 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070010796 if (NULL == pWextState)
10797 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080010798 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -070010799 __func__);
10800 return -EIO;
10801 }
10802
10803 pRoamProfile = &pWextState->roamProfile;
10804
10805 /* Issue disconnect only if interface type is set to IBSS */
10806 if (eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType)
10807 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010808 hddLog (VOS_TRACE_LEVEL_ERROR, "%s: BSS Type is not set to IBSS",
Jeff Johnson295189b2012-06-20 16:38:30 -070010809 __func__);
10810 return -EINVAL;
10811 }
10812
10813 /* Issue Disconnect request */
10814 INIT_COMPLETION(pAdapter->disconnect_comp_var);
10815 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
10816 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
10817
10818 return 0;
10819}
10820
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053010821static int wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
10822 struct net_device *dev
10823 )
10824{
10825 int ret = 0;
10826
10827 vos_ssr_protect(__func__);
10828 ret = __wlan_hdd_cfg80211_leave_ibss(wiphy, dev);
10829 vos_ssr_unprotect(__func__);
10830
10831 return ret;
10832}
10833
Jeff Johnson295189b2012-06-20 16:38:30 -070010834/*
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053010835 * FUNCTION: __wlan_hdd_cfg80211_set_wiphy_params
Jeff Johnson295189b2012-06-20 16:38:30 -070010836 * This function is used to set the phy parameters
10837 * (RTS Threshold/FRAG Threshold/Retry Count etc ...)
10838 */
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053010839static int __wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070010840 u32 changed)
10841{
10842 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
10843 tHalHandle hHal = pHddCtx->hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010844 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070010845
10846 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010847 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10848 TRACE_CODE_HDD_CFG80211_SET_WIPHY_PARAMS,
10849 NO_SESSION, wiphy->rts_threshold));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010850 status = wlan_hdd_validate_context(pHddCtx);
10851
10852 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010853 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010854 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10855 "%s: HDD context is not valid", __func__);
10856 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010857 }
10858
Jeff Johnson295189b2012-06-20 16:38:30 -070010859 if (changed & WIPHY_PARAM_RTS_THRESHOLD)
10860 {
10861 u16 rts_threshold = (wiphy->rts_threshold == -1) ?
10862 WNI_CFG_RTS_THRESHOLD_STAMAX :
10863 wiphy->rts_threshold;
10864
10865 if ((WNI_CFG_RTS_THRESHOLD_STAMIN > rts_threshold) ||
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010866 (WNI_CFG_RTS_THRESHOLD_STAMAX < rts_threshold))
Jeff Johnson295189b2012-06-20 16:38:30 -070010867 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010868 hddLog(VOS_TRACE_LEVEL_ERROR,
10869 "%s: Invalid RTS Threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070010870 __func__, rts_threshold);
10871 return -EINVAL;
10872 }
10873
10874 if (0 != ccmCfgSetInt(hHal, WNI_CFG_RTS_THRESHOLD,
10875 rts_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010876 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070010877 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010878 hddLog(VOS_TRACE_LEVEL_ERROR,
10879 "%s: ccmCfgSetInt failed for rts_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070010880 __func__, rts_threshold);
10881 return -EIO;
10882 }
10883
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010884 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set rts threshold %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070010885 rts_threshold);
10886 }
10887
10888 if (changed & WIPHY_PARAM_FRAG_THRESHOLD)
10889 {
10890 u16 frag_threshold = (wiphy->frag_threshold == -1) ?
10891 WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX :
10892 wiphy->frag_threshold;
10893
10894 if ((WNI_CFG_FRAGMENTATION_THRESHOLD_STAMIN > frag_threshold)||
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010895 (WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX < frag_threshold) )
Jeff Johnson295189b2012-06-20 16:38:30 -070010896 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010897 hddLog(VOS_TRACE_LEVEL_ERROR,
10898 "%s: Invalid frag_threshold value %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070010899 frag_threshold);
10900 return -EINVAL;
10901 }
10902
10903 if (0 != ccmCfgSetInt(hHal, WNI_CFG_FRAGMENTATION_THRESHOLD,
10904 frag_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010905 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070010906 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010907 hddLog(VOS_TRACE_LEVEL_ERROR,
10908 "%s: ccmCfgSetInt failed for frag_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070010909 __func__, frag_threshold);
10910 return -EIO;
10911 }
10912
10913 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set frag threshold %hu", __func__,
10914 frag_threshold);
10915 }
10916
10917 if ((changed & WIPHY_PARAM_RETRY_SHORT)
10918 || (changed & WIPHY_PARAM_RETRY_LONG))
10919 {
10920 u8 retry_value = (changed & WIPHY_PARAM_RETRY_SHORT) ?
10921 wiphy->retry_short :
10922 wiphy->retry_long;
10923
10924 if ((WNI_CFG_LONG_RETRY_LIMIT_STAMIN > retry_value) ||
10925 (WNI_CFG_LONG_RETRY_LIMIT_STAMAX < retry_value))
10926 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010927 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070010928 __func__, retry_value);
10929 return -EINVAL;
10930 }
10931
10932 if (changed & WIPHY_PARAM_RETRY_SHORT)
10933 {
10934 if (0 != ccmCfgSetInt(hHal, WNI_CFG_LONG_RETRY_LIMIT,
10935 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010936 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070010937 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010938 hddLog(VOS_TRACE_LEVEL_ERROR,
10939 "%s: ccmCfgSetInt failed for long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070010940 __func__, retry_value);
10941 return -EIO;
10942 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010943 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070010944 __func__, retry_value);
10945 }
10946 else if (changed & WIPHY_PARAM_RETRY_SHORT)
10947 {
10948 if (0 != ccmCfgSetInt(hHal, WNI_CFG_SHORT_RETRY_LIMIT,
10949 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010950 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070010951 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010952 hddLog(VOS_TRACE_LEVEL_ERROR,
10953 "%s: ccmCfgSetInt failed for short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070010954 __func__, retry_value);
10955 return -EIO;
10956 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010957 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070010958 __func__, retry_value);
10959 }
10960 }
10961
10962 return 0;
10963}
10964
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053010965static int wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
10966 u32 changed)
10967{
10968 int ret;
10969
10970 vos_ssr_protect(__func__);
10971 ret = __wlan_hdd_cfg80211_set_wiphy_params(wiphy, changed);
10972 vos_ssr_unprotect(__func__);
10973
10974 return ret;
10975}
10976
Jeff Johnson295189b2012-06-20 16:38:30 -070010977/*
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053010978 * FUNCTION: __wlan_hdd_cfg80211_set_txpower
Jeff Johnson295189b2012-06-20 16:38:30 -070010979 * This function is used to set the txpower
10980 */
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053010981static int __wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
Yue Maf49ba872013-08-19 12:04:25 -070010982#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
10983 struct wireless_dev *wdev,
10984#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010985#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010986 enum tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -070010987#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010988 enum nl80211_tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -070010989#endif
10990 int dbm)
10991{
10992 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010993 tHalHandle hHal = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070010994 tSirMacAddr bssid = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
10995 tSirMacAddr selfMac = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010996 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070010997
10998 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010999 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11000 TRACE_CODE_HDD_CFG80211_SET_TXPOWER,
11001 NO_SESSION, type ));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011002 status = wlan_hdd_validate_context(pHddCtx);
11003
11004 if (0 != status)
11005 {
11006 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11007 "%s: HDD context is not valid", __func__);
11008 return status;
11009 }
11010
11011 hHal = pHddCtx->hHal;
11012
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011013 if (0 != ccmCfgSetInt(hHal, WNI_CFG_CURRENT_TX_POWER_LEVEL,
11014 dbm, ccmCfgSetCallback,
11015 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070011016 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011017 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070011018 "%s: ccmCfgSetInt failed for tx power %hu", __func__, dbm);
11019 return -EIO;
11020 }
11021
11022 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set tx power level %d dbm", __func__,
11023 dbm);
11024
11025 switch(type)
11026 {
11027 case NL80211_TX_POWER_AUTOMATIC: /*automatically determine transmit power*/
11028 /* Fall through */
11029 case NL80211_TX_POWER_LIMITED: /*limit TX power by the mBm parameter*/
11030 if( sme_SetMaxTxPower(hHal, bssid, selfMac, dbm) != eHAL_STATUS_SUCCESS )
11031 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011032 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Setting maximum tx power failed",
11033 __func__);
11034 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -070011035 }
11036 break;
11037 case NL80211_TX_POWER_FIXED: /*fix TX power to the mBm parameter*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011038 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: NL80211_TX_POWER_FIXED not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -070011039 __func__);
11040 return -EOPNOTSUPP;
11041 break;
11042 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011043 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid power setting type %d",
11044 __func__, type);
Jeff Johnson295189b2012-06-20 16:38:30 -070011045 return -EIO;
11046 }
11047
11048 return 0;
11049}
11050
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053011051static int wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
11052#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
11053 struct wireless_dev *wdev,
11054#endif
11055#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
11056 enum tx_power_setting type,
11057#else
11058 enum nl80211_tx_power_setting type,
11059#endif
11060 int dbm)
11061{
11062 int ret;
11063 vos_ssr_protect(__func__);
11064 ret = __wlan_hdd_cfg80211_set_txpower(wiphy,
11065#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
11066 wdev,
11067#endif
11068#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
11069 type,
11070#else
11071 type,
11072#endif
11073 dbm);
11074 vos_ssr_unprotect(__func__);
11075
11076 return ret;
11077}
11078
Jeff Johnson295189b2012-06-20 16:38:30 -070011079/*
11080 * FUNCTION: wlan_hdd_cfg80211_get_txpower
11081 * This function is used to read the txpower
11082 */
Yue Maf49ba872013-08-19 12:04:25 -070011083static int wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy,
11084#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
11085 struct wireless_dev *wdev,
11086#endif
11087 int *dbm)
Jeff Johnson295189b2012-06-20 16:38:30 -070011088{
11089
11090 hdd_adapter_t *pAdapter;
11091 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011092 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070011093
Jeff Johnsone7245742012-09-05 17:12:55 -070011094 ENTER();
11095
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011096 status = wlan_hdd_validate_context(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070011097
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011098 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011099 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011100 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11101 "%s: HDD context is not valid", __func__);
11102 *dbm = 0;
11103 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011104 }
11105
Jeff Johnson295189b2012-06-20 16:38:30 -070011106 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
11107 if (NULL == pAdapter)
11108 {
11109 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Not in station context " ,__func__);
11110 return -ENOENT;
11111 }
11112
11113 wlan_hdd_get_classAstats(pAdapter);
11114 *dbm = pAdapter->hdd_stats.ClassA_stat.max_pwr;
11115
Jeff Johnsone7245742012-09-05 17:12:55 -070011116 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070011117 return 0;
11118}
11119
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053011120static int __wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -070011121 u8* mac, struct station_info *sinfo)
11122{
11123 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
11124 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11125 int ssidlen = pHddStaCtx->conn_info.SSID.SSID.length;
c_hpothu44ff4e02014-05-08 00:13:57 +053011126 tANI_U32 rate_flags;
Jeff Johnson295189b2012-06-20 16:38:30 -070011127
11128 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
11129 hdd_config_t *pCfg = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -070011130
11131 tANI_U8 OperationalRates[CSR_DOT11_SUPPORTED_RATES_MAX];
11132 tANI_U32 ORLeng = CSR_DOT11_SUPPORTED_RATES_MAX;
11133 tANI_U8 ExtendedRates[CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX];
11134 tANI_U32 ERLeng = CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX;
11135 tANI_U8 MCSRates[SIZE_OF_BASIC_MCS_SET];
11136 tANI_U32 MCSLeng = SIZE_OF_BASIC_MCS_SET;
11137 tANI_U16 maxRate = 0;
11138 tANI_U16 myRate;
11139 tANI_U16 currentRate = 0;
11140 tANI_U8 maxSpeedMCS = 0;
11141 tANI_U8 maxMCSIdx = 0;
11142 tANI_U8 rateFlag = 1;
c_hpothu79aab322014-07-14 21:11:01 +053011143 tANI_U8 i, j, rssidx, mode=0;
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070011144 tANI_U16 temp;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011145 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070011146
Leo Chang6f8870f2013-03-26 18:11:36 -070011147#ifdef WLAN_FEATURE_11AC
11148 tANI_U32 vht_mcs_map;
11149 eDataRate11ACMaxMcs vhtMaxMcs;
11150#endif /* WLAN_FEATURE_11AC */
11151
Jeff Johnsone7245742012-09-05 17:12:55 -070011152 ENTER();
11153
Jeff Johnson295189b2012-06-20 16:38:30 -070011154 if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) ||
11155 (0 == ssidlen))
11156 {
11157 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Not associated or"
11158 " Invalid ssidlen, %d", __func__, ssidlen);
11159 /*To keep GUI happy*/
11160 return 0;
11161 }
11162
Mukul Sharma811205f2014-07-09 21:07:30 +053011163 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
11164 {
11165 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11166 "%s: Roaming in progress, so unable to proceed this request", __func__);
11167 return 0;
11168 }
11169
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011170 status = wlan_hdd_validate_context(pHddCtx);
11171
11172 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011173 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011174 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11175 "%s: HDD context is not valid", __func__);
11176 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011177 }
11178
Jeff Johnson295189b2012-06-20 16:38:30 -070011179
Kiet Lam3b17fc82013-09-27 05:24:08 +053011180 wlan_hdd_get_rssi(pAdapter, &sinfo->signal);
11181 sinfo->filled |= STATION_INFO_SIGNAL;
11182
c_hpothu09f19542014-05-30 21:53:31 +053011183 wlan_hdd_get_station_stats(pAdapter);
11184 rate_flags = pAdapter->hdd_stats.ClassA_stat.tx_rate_flags;
11185
11186 /*overwrite rate_flags if MAX link-speed need to be reported*/
c_hpothu44ff4e02014-05-08 00:13:57 +053011187 if ((eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed) ||
11188 (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed &&
c_hpothu79aab322014-07-14 21:11:01 +053011189 sinfo->signal >= pCfg->linkSpeedRssiLow))
c_hpothu44ff4e02014-05-08 00:13:57 +053011190 {
11191 rate_flags = pAdapter->maxRateFlags;
11192 }
c_hpothu44ff4e02014-05-08 00:13:57 +053011193
Jeff Johnson295189b2012-06-20 16:38:30 -070011194 //convert to the UI units of 100kbps
11195 myRate = pAdapter->hdd_stats.ClassA_stat.tx_rate * 5;
11196
11197#ifdef LINKSPEED_DEBUG_ENABLED
Leo Chang6f8870f2013-03-26 18:11:36 -070011198 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 -070011199 sinfo->signal,
11200 pCfg->reportMaxLinkSpeed,
11201 myRate,
11202 (int) pCfg->linkSpeedRssiHigh,
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070011203 (int) pCfg->linkSpeedRssiMid,
11204 (int) pCfg->linkSpeedRssiLow,
Leo Chang6f8870f2013-03-26 18:11:36 -070011205 (int) rate_flags,
11206 (int) pAdapter->hdd_stats.ClassA_stat.mcs_index);
Jeff Johnson295189b2012-06-20 16:38:30 -070011207#endif //LINKSPEED_DEBUG_ENABLED
11208
11209 if (eHDD_LINK_SPEED_REPORT_ACTUAL != pCfg->reportMaxLinkSpeed)
11210 {
11211 // we do not want to necessarily report the current speed
11212 if (eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed)
11213 {
11214 // report the max possible speed
11215 rssidx = 0;
11216 }
11217 else if (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed)
11218 {
11219 // report the max possible speed with RSSI scaling
11220 if (sinfo->signal >= pCfg->linkSpeedRssiHigh)
11221 {
11222 // report the max possible speed
11223 rssidx = 0;
11224 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070011225 else if (sinfo->signal >= pCfg->linkSpeedRssiMid)
Jeff Johnson295189b2012-06-20 16:38:30 -070011226 {
11227 // report middle speed
11228 rssidx = 1;
11229 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070011230 else if (sinfo->signal >= pCfg->linkSpeedRssiLow)
11231 {
11232 // report middle speed
11233 rssidx = 2;
11234 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011235 else
11236 {
11237 // report actual speed
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070011238 rssidx = 3;
Jeff Johnson295189b2012-06-20 16:38:30 -070011239 }
11240 }
11241 else
11242 {
11243 // unknown, treat as eHDD_LINK_SPEED_REPORT_MAX
11244 hddLog(VOS_TRACE_LEVEL_ERROR,
11245 "%s: Invalid value for reportMaxLinkSpeed: %u",
11246 __func__, pCfg->reportMaxLinkSpeed);
11247 rssidx = 0;
11248 }
11249
11250 maxRate = 0;
11251
11252 /* Get Basic Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053011253 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_OPERATIONAL_RATE_SET,
11254 OperationalRates, &ORLeng))
11255 {
11256 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
11257 /*To keep GUI happy*/
11258 return 0;
11259 }
11260
Jeff Johnson295189b2012-06-20 16:38:30 -070011261 for (i = 0; i < ORLeng; i++)
11262 {
Jeff Johnsone7245742012-09-05 17:12:55 -070011263 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -070011264 {
11265 /* Validate Rate Set */
11266 if (supported_data_rate[j].beacon_rate_index == (OperationalRates[i] & 0x7F))
11267 {
11268 currentRate = supported_data_rate[j].supported_rate[rssidx];
11269 break;
11270 }
11271 }
11272 /* Update MAX rate */
11273 maxRate = (currentRate > maxRate)?currentRate:maxRate;
11274 }
11275
11276 /* Get Extended Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053011277 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET,
11278 ExtendedRates, &ERLeng))
11279 {
11280 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
11281 /*To keep GUI happy*/
11282 return 0;
11283 }
11284
Jeff Johnson295189b2012-06-20 16:38:30 -070011285 for (i = 0; i < ERLeng; i++)
11286 {
Jeff Johnsone7245742012-09-05 17:12:55 -070011287 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -070011288 {
11289 if (supported_data_rate[j].beacon_rate_index == (ExtendedRates[i] & 0x7F))
11290 {
11291 currentRate = supported_data_rate[j].supported_rate[rssidx];
11292 break;
11293 }
11294 }
11295 /* Update MAX rate */
11296 maxRate = (currentRate > maxRate)?currentRate:maxRate;
11297 }
c_hpothu79aab322014-07-14 21:11:01 +053011298
Kiet Lamb69f8dc2013-11-15 15:34:27 +053011299 /* Get MCS Rate Set --
Kaushik, Sushantdc304d82014-01-22 10:58:37 +053011300 Only if we are always reporting max speed (or)
Kiet Lamb69f8dc2013-11-15 15:34:27 +053011301 if we have good rssi */
c_hpothu79aab322014-07-14 21:11:01 +053011302 if ((3 != rssidx) && !(rate_flags & eHAL_TX_RATE_LEGACY))
Jeff Johnson295189b2012-06-20 16:38:30 -070011303 {
c_hpothu79aab322014-07-14 21:11:01 +053011304 if (rate_flags & eHAL_TX_RATE_VHT80)
11305 mode = 2;
11306 else if (rate_flags & (eHAL_TX_RATE_VHT40 | eHAL_TX_RATE_HT40))
11307 mode = 1;
11308 else
11309 mode = 0;
11310
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053011311 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_CURRENT_MCS_SET,
11312 MCSRates, &MCSLeng))
11313 {
11314 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
11315 /*To keep GUI happy*/
11316 return 0;
11317 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011318 rateFlag = 0;
Leo Chang6f8870f2013-03-26 18:11:36 -070011319#ifdef WLAN_FEATURE_11AC
11320 /* VHT80 rate has seperate rate table */
Gopichand Nakkala4c705372013-04-24 13:20:33 +053011321 if (rate_flags & (eHAL_TX_RATE_VHT20|eHAL_TX_RATE_VHT40|eHAL_TX_RATE_VHT80))
Jeff Johnson295189b2012-06-20 16:38:30 -070011322 {
Leo Chang6f8870f2013-03-26 18:11:36 -070011323 ccmCfgGetInt(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_VHT_TX_MCS_MAP, &vht_mcs_map);
Gopichand Nakkala4c705372013-04-24 13:20:33 +053011324 vhtMaxMcs = (eDataRate11ACMaxMcs)(vht_mcs_map & DATA_RATE_11AC_MCS_MASK );
Leo Chang6f8870f2013-03-26 18:11:36 -070011325 if (rate_flags & eHAL_TX_RATE_SGI)
Jeff Johnson295189b2012-06-20 16:38:30 -070011326 {
Leo Chang6f8870f2013-03-26 18:11:36 -070011327 rateFlag |= 1;
Jeff Johnson295189b2012-06-20 16:38:30 -070011328 }
Leo Chang6f8870f2013-03-26 18:11:36 -070011329 if (DATA_RATE_11AC_MAX_MCS_7 == vhtMaxMcs)
Jeff Johnson295189b2012-06-20 16:38:30 -070011330 {
Leo Chang6f8870f2013-03-26 18:11:36 -070011331 maxMCSIdx = 7;
11332 }
11333 else if (DATA_RATE_11AC_MAX_MCS_8 == vhtMaxMcs)
11334 {
11335 maxMCSIdx = 8;
11336 }
11337 else if (DATA_RATE_11AC_MAX_MCS_9 == vhtMaxMcs)
11338 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +053011339 //VHT20 is supporting 0~8
11340 if (rate_flags & eHAL_TX_RATE_VHT20)
11341 maxMCSIdx = 8;
11342 else
11343 maxMCSIdx = 9;
Leo Chang6f8870f2013-03-26 18:11:36 -070011344 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053011345
c_hpothu79aab322014-07-14 21:11:01 +053011346 if (0 != rssidx)/*check for scaled */
11347 {
11348 //get middle rate MCS index if rssi=1/2
11349 for (i=0; i <= maxMCSIdx; i++)
11350 {
11351 if (sinfo->signal <= rssiMcsTbl[mode][i])
11352 {
11353 maxMCSIdx = i;
11354 break;
11355 }
11356 }
11357 }
11358
Gopichand Nakkala4c705372013-04-24 13:20:33 +053011359 if (rate_flags & eHAL_TX_RATE_VHT80)
11360 {
11361 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT80_rate[rateFlag];
11362 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT80_rate[rateFlag];
11363 }
11364 else if (rate_flags & eHAL_TX_RATE_VHT40)
11365 {
11366 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT40_rate[rateFlag];
11367 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT40_rate[rateFlag];
11368 }
11369 else if (rate_flags & eHAL_TX_RATE_VHT20)
11370 {
11371 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT20_rate[rateFlag];
11372 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT20_rate[rateFlag];
11373 }
11374
Leo Chang6f8870f2013-03-26 18:11:36 -070011375 maxSpeedMCS = 1;
11376 if (currentRate > maxRate)
11377 {
11378 maxRate = currentRate;
11379 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053011380
Leo Chang6f8870f2013-03-26 18:11:36 -070011381 }
11382 else
11383#endif /* WLAN_FEATURE_11AC */
11384 {
11385 if (rate_flags & eHAL_TX_RATE_HT40)
11386 {
11387 rateFlag |= 1;
11388 }
11389 if (rate_flags & eHAL_TX_RATE_SGI)
11390 {
11391 rateFlag |= 2;
11392 }
11393
c_hpothu79aab322014-07-14 21:11:01 +053011394 if (rssidx == 1 || rssidx == 2)
11395 {
11396 //get middle rate MCS index if rssi=1/2
11397 for (i=0; i <= 7; i++)
11398 {
11399 if (sinfo->signal <= rssiMcsTbl[mode][i])
11400 {
11401 temp = i+1;
11402 break;
11403 }
11404 }
11405 }
11406 else
Leo Chang6f8870f2013-03-26 18:11:36 -070011407 {
11408 temp = sizeof(supported_mcs_rate) / sizeof(supported_mcs_rate[0]);
c_hpothu79aab322014-07-14 21:11:01 +053011409 }
11410
11411 for (i = 0; i < MCSLeng; i++)
11412 {
Leo Chang6f8870f2013-03-26 18:11:36 -070011413 for (j = 0; j < temp; j++)
11414 {
11415 if (supported_mcs_rate[j].beacon_rate_index == MCSRates[i])
11416 {
11417 currentRate = supported_mcs_rate[j].supported_rate[rateFlag];
11418 break;
11419 }
11420 }
11421 if ((j < temp) && (currentRate > maxRate))
11422 {
11423 maxRate = currentRate;
11424 maxSpeedMCS = 1;
11425 maxMCSIdx = supported_mcs_rate[j].beacon_rate_index;
11426 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011427 }
11428 }
11429 }
11430
Gopichand Nakkala4c705372013-04-24 13:20:33 +053011431 else if (!(rate_flags & eHAL_TX_RATE_LEGACY))
11432 {
11433 maxRate = myRate;
11434 maxSpeedMCS = 1;
11435 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
11436 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011437 // make sure we report a value at least as big as our current rate
c_hpothu79aab322014-07-14 21:11:01 +053011438 if ((maxRate < myRate) || (0 == maxRate))
Jeff Johnson295189b2012-06-20 16:38:30 -070011439 {
11440 maxRate = myRate;
11441 if (rate_flags & eHAL_TX_RATE_LEGACY)
11442 {
11443 maxSpeedMCS = 0;
11444 }
11445 else
11446 {
11447 maxSpeedMCS = 1;
11448 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
11449 }
11450 }
11451
Gopichand Nakkala4c705372013-04-24 13:20:33 +053011452 if (rate_flags & eHAL_TX_RATE_LEGACY)
Jeff Johnson295189b2012-06-20 16:38:30 -070011453 {
11454 sinfo->txrate.legacy = maxRate;
11455#ifdef LINKSPEED_DEBUG_ENABLED
11456 pr_info("Reporting legacy rate %d\n", sinfo->txrate.legacy);
11457#endif //LINKSPEED_DEBUG_ENABLED
11458 }
11459 else
11460 {
11461 sinfo->txrate.mcs = maxMCSIdx;
Leo Chang6f8870f2013-03-26 18:11:36 -070011462#ifdef WLAN_FEATURE_11AC
11463 sinfo->txrate.nss = 1;
11464 if (rate_flags & eHAL_TX_RATE_VHT80)
11465 {
11466 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
Gopichand Nakkala4c705372013-04-24 13:20:33 +053011467 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
Leo Chang6f8870f2013-03-26 18:11:36 -070011468 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053011469 else if (rate_flags & eHAL_TX_RATE_VHT40)
Leo Chang6f8870f2013-03-26 18:11:36 -070011470 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +053011471 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
11472 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
11473 }
11474 else if (rate_flags & eHAL_TX_RATE_VHT20)
11475 {
11476 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
11477 }
11478#endif /* WLAN_FEATURE_11AC */
11479 if (rate_flags & (eHAL_TX_RATE_HT20 | eHAL_TX_RATE_HT40))
11480 {
11481 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
11482 if (rate_flags & eHAL_TX_RATE_HT40)
11483 {
11484 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
11485 }
Leo Chang6f8870f2013-03-26 18:11:36 -070011486 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011487 if (rate_flags & eHAL_TX_RATE_SGI)
11488 {
11489 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
11490 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053011491
Jeff Johnson295189b2012-06-20 16:38:30 -070011492#ifdef LINKSPEED_DEBUG_ENABLED
11493 pr_info("Reporting MCS rate %d flags %x\n",
11494 sinfo->txrate.mcs,
11495 sinfo->txrate.flags );
11496#endif //LINKSPEED_DEBUG_ENABLED
11497 }
11498 }
11499 else
11500 {
11501 // report current rate instead of max rate
11502
11503 if (rate_flags & eHAL_TX_RATE_LEGACY)
11504 {
11505 //provide to the UI in units of 100kbps
11506 sinfo->txrate.legacy = myRate;
11507#ifdef LINKSPEED_DEBUG_ENABLED
11508 pr_info("Reporting actual legacy rate %d\n", sinfo->txrate.legacy);
11509#endif //LINKSPEED_DEBUG_ENABLED
11510 }
11511 else
11512 {
11513 //must be MCS
11514 sinfo->txrate.mcs = pAdapter->hdd_stats.ClassA_stat.mcs_index;
Leo Chang6f8870f2013-03-26 18:11:36 -070011515#ifdef WLAN_FEATURE_11AC
11516 sinfo->txrate.nss = 1;
11517 if (rate_flags & eHAL_TX_RATE_VHT80)
11518 {
11519 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
11520 }
11521 else
11522#endif /* WLAN_FEATURE_11AC */
11523 {
11524 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
11525 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011526 if (rate_flags & eHAL_TX_RATE_SGI)
11527 {
11528 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
11529 }
11530 if (rate_flags & eHAL_TX_RATE_HT40)
11531 {
11532 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
11533 }
Leo Chang6f8870f2013-03-26 18:11:36 -070011534#ifdef WLAN_FEATURE_11AC
11535 else if (rate_flags & eHAL_TX_RATE_VHT80)
11536 {
11537 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
11538 }
11539#endif /* WLAN_FEATURE_11AC */
Jeff Johnson295189b2012-06-20 16:38:30 -070011540#ifdef LINKSPEED_DEBUG_ENABLED
11541 pr_info("Reporting actual MCS rate %d flags %x\n",
11542 sinfo->txrate.mcs,
11543 sinfo->txrate.flags );
11544#endif //LINKSPEED_DEBUG_ENABLED
11545 }
11546 }
11547 sinfo->filled |= STATION_INFO_TX_BITRATE;
11548
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070011549 sinfo->tx_packets =
11550 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[0] +
11551 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[1] +
11552 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[2] +
11553 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[3];
11554
11555 sinfo->tx_retries =
11556 pAdapter->hdd_stats.summary_stat.retry_cnt[0] +
11557 pAdapter->hdd_stats.summary_stat.retry_cnt[1] +
11558 pAdapter->hdd_stats.summary_stat.retry_cnt[2] +
11559 pAdapter->hdd_stats.summary_stat.retry_cnt[3];
11560
11561 sinfo->tx_failed =
11562 pAdapter->hdd_stats.summary_stat.fail_cnt[0] +
11563 pAdapter->hdd_stats.summary_stat.fail_cnt[1] +
11564 pAdapter->hdd_stats.summary_stat.fail_cnt[2] +
11565 pAdapter->hdd_stats.summary_stat.fail_cnt[3];
11566
11567 sinfo->filled |=
11568 STATION_INFO_TX_PACKETS |
11569 STATION_INFO_TX_RETRIES |
11570 STATION_INFO_TX_FAILED;
11571
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011572 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11573 TRACE_CODE_HDD_CFG80211_GET_STA,
11574 pAdapter->sessionId, maxRate));
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070011575 EXIT();
11576 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070011577}
11578
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053011579static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
11580 u8* mac, struct station_info *sinfo)
11581{
11582 int ret;
11583
11584 vos_ssr_protect(__func__);
11585 ret = __wlan_hdd_cfg80211_get_station(wiphy, dev, mac, sinfo);
11586 vos_ssr_unprotect(__func__);
11587
11588 return ret;
11589}
11590
11591static int __wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
Sameer Thalappilc9f26e92013-06-07 10:11:06 -070011592 struct net_device *dev, bool mode, int timeout)
Jeff Johnson295189b2012-06-20 16:38:30 -070011593{
11594 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053011595 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070011596 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011597 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070011598
Jeff Johnsone7245742012-09-05 17:12:55 -070011599 ENTER();
11600
Jeff Johnson295189b2012-06-20 16:38:30 -070011601 if (NULL == pAdapter)
11602 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080011603 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011604 return -ENODEV;
11605 }
11606
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011607 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11608 TRACE_CODE_HDD_CFG80211_SET_POWER_MGMT,
11609 pAdapter->sessionId, timeout));
11610
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053011611 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011612 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053011613
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011614 if (0 != status)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011615 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011616 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11617 "%s: HDD context is not valid", __func__);
11618 return status;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011619 }
11620
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053011621 if ((DRIVER_POWER_MODE_AUTO == !mode) &&
11622 (TRUE == pHddCtx->hdd_wlan_suspended) &&
11623 (pHddCtx->cfg_ini->fhostArpOffload) &&
11624 (eConnectionState_Associated ==
11625 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
11626 {
Amar Singhald53568e2013-09-26 11:03:45 -070011627
11628 hddLog(VOS_TRACE_LEVEL_INFO,
11629 "offload: in cfg80211_set_power_mgmt, calling arp offload");
Gopichand Nakkalab03e8082013-05-30 18:09:25 +053011630 vos_status = hdd_conf_arp_offload(pAdapter, TRUE);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053011631 if (!VOS_IS_STATUS_SUCCESS(vos_status))
11632 {
11633 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011634 "%s:Failed to enable ARPOFFLOAD Feature %d",
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053011635 __func__, vos_status);
11636 }
11637 }
11638
Jeff Johnson295189b2012-06-20 16:38:30 -070011639 /**The get power cmd from the supplicant gets updated by the nl only
11640 *on successful execution of the function call
11641 *we are oppositely mapped w.r.t mode in the driver
11642 **/
11643 vos_status = wlan_hdd_enter_bmps(pAdapter, !mode);
11644
Jeff Johnsone7245742012-09-05 17:12:55 -070011645 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070011646 if (VOS_STATUS_E_FAILURE == vos_status)
11647 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011648 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11649 "%s: failed to enter bmps mode", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011650 return -EINVAL;
11651 }
11652 return 0;
11653}
11654
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053011655static int wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
11656 struct net_device *dev, bool mode, int timeout)
11657{
11658 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070011659
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053011660 vos_ssr_protect(__func__);
11661 ret = __wlan_hdd_cfg80211_set_power_mgmt(wiphy, dev, mode, timeout);
11662 vos_ssr_unprotect(__func__);
11663
11664 return ret;
11665}
Jeff Johnson295189b2012-06-20 16:38:30 -070011666#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
11667static int wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
11668 struct net_device *netdev,
11669 u8 key_index)
11670{
Jeff Johnsone7245742012-09-05 17:12:55 -070011671 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -070011672 return 0;
11673}
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011674#endif //LINUX_VERSION_CODE
Jeff Johnson295189b2012-06-20 16:38:30 -070011675
11676#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
11677static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
11678 struct net_device *dev,
11679 struct ieee80211_txq_params *params)
11680{
Jeff Johnsone7245742012-09-05 17:12:55 -070011681 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -070011682 return 0;
11683}
11684#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
11685static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
11686 struct ieee80211_txq_params *params)
11687{
Jeff Johnsone7245742012-09-05 17:12:55 -070011688 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -070011689 return 0;
11690}
11691#endif //LINUX_VERSION_CODE
11692
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053011693static int __wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011694 struct net_device *dev, u8 *mac)
11695{
11696 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011697 hdd_context_t *pHddCtx;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080011698 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011699 int status;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080011700 v_U8_t staId;
Jeff Johnson295189b2012-06-20 16:38:30 -070011701
Jeff Johnsone7245742012-09-05 17:12:55 -070011702 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011703
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011704 if ( NULL == pAdapter )
Jeff Johnson295189b2012-06-20 16:38:30 -070011705 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011706 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011707 return -EINVAL;
11708 }
11709
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011710 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11711 TRACE_CODE_HDD_CFG80211_DEL_STA,
11712 pAdapter->sessionId, pAdapter->device_mode));
11713
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011714 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11715 status = wlan_hdd_validate_context(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070011716
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011717 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011718 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011719 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11720 "%s: HDD context is not valid", __func__);
11721 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011722 }
11723
Jeff Johnson295189b2012-06-20 16:38:30 -070011724 if ( (WLAN_HDD_SOFTAP == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070011725 || (WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070011726 )
11727 {
11728 if( NULL == mac )
11729 {
11730 v_U16_t i;
11731 for(i = 0; i < WLAN_MAX_STA_COUNT; i++)
11732 {
Rajesh Chauhan18488fc2013-08-22 10:15:03 -070011733 if ((pAdapter->aStaInfo[i].isUsed) &&
11734 (!pAdapter->aStaInfo[i].isDeauthInProgress))
Jeff Johnson295189b2012-06-20 16:38:30 -070011735 {
11736 u8 *macAddr = pAdapter->aStaInfo[i].macAddrSTA.bytes;
11737 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080011738 "%s: Delete STA with MAC::"
11739 MAC_ADDRESS_STR,
11740 __func__, MAC_ADDR_ARRAY(macAddr));
Rajesh Chauhan18488fc2013-08-22 10:15:03 -070011741 vos_status = hdd_softap_sta_deauth(pAdapter, macAddr);
11742 if (VOS_IS_STATUS_SUCCESS(vos_status))
11743 pAdapter->aStaInfo[i].isDeauthInProgress = TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -070011744 }
11745 }
11746 }
11747 else
11748 {
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080011749
11750 vos_status = hdd_softap_GetStaId(pAdapter,(v_MACADDR_t *)mac, &staId);
11751 if (!VOS_IS_STATUS_SUCCESS(vos_status))
11752 {
11753 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080011754 "%s: Skip this DEL STA as this is not used::"
11755 MAC_ADDRESS_STR,
11756 __func__, MAC_ADDR_ARRAY(mac));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080011757 return -ENOENT;
11758 }
11759
11760 if( pAdapter->aStaInfo[staId].isDeauthInProgress == TRUE)
11761 {
11762 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080011763 "%s: Skip this DEL STA as deauth is in progress::"
11764 MAC_ADDRESS_STR,
11765 __func__, MAC_ADDR_ARRAY(mac));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080011766 return -ENOENT;
11767 }
11768
11769 pAdapter->aStaInfo[staId].isDeauthInProgress = TRUE;
11770
Jeff Johnson295189b2012-06-20 16:38:30 -070011771 hddLog(VOS_TRACE_LEVEL_INFO,
11772 "%s: Delete STA with MAC::"
Arif Hussain24bafea2013-11-15 15:10:03 -080011773 MAC_ADDRESS_STR,
Jeff Johnson295189b2012-06-20 16:38:30 -070011774 __func__,
Arif Hussain24bafea2013-11-15 15:10:03 -080011775 MAC_ADDR_ARRAY(mac));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080011776
11777 vos_status = hdd_softap_sta_deauth(pAdapter, mac);
11778 if (!VOS_IS_STATUS_SUCCESS(vos_status))
11779 {
11780 pAdapter->aStaInfo[staId].isDeauthInProgress = FALSE;
11781 hddLog(VOS_TRACE_LEVEL_INFO,
11782 "%s: STA removal failed for ::"
Arif Hussain24bafea2013-11-15 15:10:03 -080011783 MAC_ADDRESS_STR,
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080011784 __func__,
Arif Hussain24bafea2013-11-15 15:10:03 -080011785 MAC_ADDR_ARRAY(mac));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080011786 return -ENOENT;
11787 }
11788
Jeff Johnson295189b2012-06-20 16:38:30 -070011789 }
11790 }
11791
11792 EXIT();
11793
11794 return 0;
11795}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053011796static int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
11797 struct net_device *dev, u8 *mac)
11798{
11799 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070011800
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053011801 vos_ssr_protect(__func__);
11802 ret = __wlan_hdd_cfg80211_del_station(wiphy, dev, mac);
11803 vos_ssr_unprotect(__func__);
11804
11805 return ret;
11806}
11807
11808static int __wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
Hoonki Lee11f7dda2013-02-14 16:55:44 -080011809 struct net_device *dev, u8 *mac, struct station_parameters *params)
11810{
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011811 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkalab977a972013-02-18 19:15:09 -080011812 int status = -EPERM;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080011813#ifdef FEATURE_WLAN_TDLS
11814 u32 mask, set;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080011815 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011816
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011817 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11818 TRACE_CODE_HDD_CFG80211_ADD_STA,
11819 pAdapter->sessionId, params->listen_interval));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080011820 mask = params->sta_flags_mask;
11821
11822 set = params->sta_flags_set;
11823
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070011824#ifdef WLAN_FEATURE_TDLS_DEBUG
11825 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11826 "%s: mask 0x%x set 0x%x " MAC_ADDRESS_STR,
11827 __func__, mask, set, MAC_ADDR_ARRAY(mac));
11828#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080011829
11830 if (mask & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
11831 if (set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011832 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 0, NULL);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080011833 }
11834 }
11835#endif
Gopichand Nakkalab977a972013-02-18 19:15:09 -080011836 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070011837}
11838
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053011839static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
11840 struct net_device *dev, u8 *mac, struct station_parameters *params)
11841{
11842 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011843
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053011844 vos_ssr_protect(__func__);
11845 ret = __wlan_hdd_cfg80211_add_station(wiphy, dev, mac, params);
11846 vos_ssr_unprotect(__func__);
11847
11848 return ret;
11849}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011850#ifdef FEATURE_WLAN_LFR
Wilson Yang6507c4e2013-10-01 20:11:19 -070011851
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053011852static int __wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
Jeff Johnsond13512a2012-07-17 11:42:19 -070011853 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011854{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011855 tANI_U32 j=0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011856 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Agarwal Ashish3da95242014-05-21 14:57:17 +053011857 hdd_station_ctx_t *pHddStaCtx;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011858 tHalHandle halHandle;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011859 eHalStatus result;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011860 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011861 tANI_U8 BSSIDMatched = 0;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011862 hdd_context_t *pHddCtx;
Jeff Johnson0299d0a2013-10-30 12:37:43 -070011863 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: set PMKSA for " MAC_ADDRESS_STR,
11864 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
Jeff Johnsone7245742012-09-05 17:12:55 -070011865
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011866 // Validate pAdapter
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011867 if ( NULL == pAdapter )
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011868 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011869 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011870 return -EINVAL;
11871 }
11872
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011873 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11874 status = wlan_hdd_validate_context(pHddCtx);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011875
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011876 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011877 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011878 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11879 "%s: HDD context is not valid", __func__);
11880 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011881 }
11882
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011883 // Retrieve halHandle
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011884 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
Agarwal Ashish3da95242014-05-21 14:57:17 +053011885 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011886
Agarwal Ashish3da95242014-05-21 14:57:17 +053011887 for (j = 0; j < pHddStaCtx->PMKIDCacheIndex; j++)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011888 {
Agarwal Ashish3da95242014-05-21 14:57:17 +053011889 if (vos_mem_compare(pHddStaCtx->PMKIDCache[j].BSSID,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011890 pmksa->bssid, WNI_CFG_BSSID_LEN))
11891 {
11892 /* BSSID matched previous entry. Overwrite it. */
11893 BSSIDMatched = 1;
Agarwal Ashish3da95242014-05-21 14:57:17 +053011894 vos_mem_copy(pHddStaCtx->PMKIDCache[j].BSSID,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011895 pmksa->bssid, WNI_CFG_BSSID_LEN);
Agarwal Ashish3da95242014-05-21 14:57:17 +053011896 vos_mem_copy(pHddStaCtx->PMKIDCache[j].PMKID,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011897 pmksa->pmkid,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011898 CSR_RSN_PMKID_SIZE);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011899 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Reusing cache entry %d.",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070011900 __func__, j );
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011901 dump_bssid(pmksa->bssid);
11902 dump_pmkid(halHandle, pmksa->pmkid);
11903 break;
11904 }
11905 }
11906
Madan Mohan Koyyalamudic4b317d2012-10-18 19:43:08 -070011907 /* Check we compared all entries,if then take the first slot now */
Agarwal Ashish3da95242014-05-21 14:57:17 +053011908 if (j == MAX_PMKSAIDS_IN_CACHE) pHddStaCtx->PMKIDCacheIndex=0;
Madan Mohan Koyyalamudic4b317d2012-10-18 19:43:08 -070011909
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011910 if (!BSSIDMatched)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011911 {
11912 // Now, we DON'T have a BSSID match, so take a new entry in the cache.
Agarwal Ashish3da95242014-05-21 14:57:17 +053011913 vos_mem_copy(pHddStaCtx->PMKIDCache[pHddStaCtx->PMKIDCacheIndex].BSSID,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011914 pmksa->bssid, ETHER_ADDR_LEN);
Agarwal Ashish3da95242014-05-21 14:57:17 +053011915 vos_mem_copy(pHddStaCtx->PMKIDCache[pHddStaCtx->PMKIDCacheIndex].PMKID,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011916 pmksa->pmkid,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011917 CSR_RSN_PMKID_SIZE);
Agarwal Ashish3da95242014-05-21 14:57:17 +053011918 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: Adding a new cache entry %d.",
11919 __func__, pHddStaCtx->PMKIDCacheIndex );
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011920 dump_bssid(pmksa->bssid);
11921 dump_pmkid(halHandle, pmksa->pmkid);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011922 // Increment the HDD Local Cache index
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011923 // The "i=0" doesn't work for the call to sme_RoamSetPMKIDCache() - LFR FIXME
Agarwal Ashish3da95242014-05-21 14:57:17 +053011924 if (pHddStaCtx->PMKIDCacheIndex <= (MAX_PMKSAIDS_IN_CACHE-1))
11925 pHddStaCtx->PMKIDCacheIndex++;
11926 else
11927 pHddStaCtx->PMKIDCacheIndex = 0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011928 }
11929
11930
11931 // Calling csrRoamSetPMKIDCache to configure the PMKIDs into the cache
Agarwal Ashish3da95242014-05-21 14:57:17 +053011932 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: Calling csrRoamSetPMKIDCache with %d cache entries.",
11933 __func__, pHddStaCtx->PMKIDCacheIndex );
11934
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011935 // Finally set the PMKSA ID Cache in CSR
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011936 result = sme_RoamSetPMKIDCache(halHandle,pAdapter->sessionId,
Agarwal Ashish3da95242014-05-21 14:57:17 +053011937 pHddStaCtx->PMKIDCache,
11938 pHddStaCtx->PMKIDCacheIndex);
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011939 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11940 TRACE_CODE_HDD_CFG80211_SET_PMKSA,
11941 pAdapter->sessionId, result));
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011942 return 0;
11943}
11944
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053011945static int wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
11946 struct cfg80211_pmksa *pmksa)
11947{
11948 int ret;
11949
11950 vos_ssr_protect(__func__);
11951 ret = __wlan_hdd_cfg80211_set_pmksa(wiphy, dev, pmksa);
11952 vos_ssr_unprotect(__func__);
11953
11954 return ret;
11955}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011956
Wilson Yang6507c4e2013-10-01 20:11:19 -070011957
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053011958static int __wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
Wilson Yang6507c4e2013-10-01 20:11:19 -070011959 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011960{
Wilson Yang6507c4e2013-10-01 20:11:19 -070011961 tANI_U32 j=0;
11962 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Agarwal Ashish3da95242014-05-21 14:57:17 +053011963 hdd_station_ctx_t *pHddStaCtx;
Wilson Yang6507c4e2013-10-01 20:11:19 -070011964 tHalHandle halHandle;
Wilson Yang6507c4e2013-10-01 20:11:19 -070011965 tANI_U8 BSSIDMatched = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070011966 hdd_context_t *pHddCtx;
Wilson Yangef657d32014-01-15 19:19:23 -080011967 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070011968
Jeff Johnson0299d0a2013-10-30 12:37:43 -070011969 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: deleting PMKSA for " MAC_ADDRESS_STR,
11970 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
Wilson Yang6507c4e2013-10-01 20:11:19 -070011971
11972 /* Validate pAdapter */
11973 if (NULL == pAdapter)
11974 {
11975 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
11976 return -EINVAL;
11977 }
11978
11979 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11980 status = wlan_hdd_validate_context(pHddCtx);
11981
11982 if (0 != status)
11983 {
11984 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11985 "%s: HDD context is not valid", __func__);
11986 return status;
11987 }
11988
11989 /*Retrieve halHandle*/
11990 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
Agarwal Ashish3da95242014-05-21 14:57:17 +053011991 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Wilson Yang6507c4e2013-10-01 20:11:19 -070011992
11993 /*in case index is 0,no entry to delete*/
Agarwal Ashish3da95242014-05-21 14:57:17 +053011994 if (0 == pHddStaCtx->PMKIDCacheIndex)
Wilson Yang6507c4e2013-10-01 20:11:19 -070011995 {
Agarwal Ashish3da95242014-05-21 14:57:17 +053011996 hddLog(VOS_TRACE_LEVEL_INFO, FL("No entries to flush"));
11997 return 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070011998 }
11999
12000 /*find the matching PMKSA entry from j=0 to (index-1),
12001 * and delete the matched one
12002 */
Agarwal Ashish3da95242014-05-21 14:57:17 +053012003 for (j = 0; j < pHddStaCtx->PMKIDCacheIndex; j++)
Wilson Yang6507c4e2013-10-01 20:11:19 -070012004 {
Agarwal Ashish3da95242014-05-21 14:57:17 +053012005 if (vos_mem_compare(pHddStaCtx->PMKIDCache[j].BSSID,
Wilson Yang6507c4e2013-10-01 20:11:19 -070012006 pmksa->bssid,
12007 WNI_CFG_BSSID_LEN))
12008 {
12009 /* BSSID matched entry */
12010 BSSIDMatched = 1;
Agarwal Ashish3da95242014-05-21 14:57:17 +053012011 if (j < pHddStaCtx->PMKIDCacheIndex-1)
Wilson Yang6507c4e2013-10-01 20:11:19 -070012012 {
12013 /*replace the matching entry with the last entry in HDD local cache*/
Agarwal Ashish3da95242014-05-21 14:57:17 +053012014 vos_mem_copy(pHddStaCtx->PMKIDCache[j].BSSID,
12015 pHddStaCtx->PMKIDCache[pHddStaCtx->PMKIDCacheIndex-1].BSSID,
12016 VOS_MAC_ADDR_SIZE);
12017 vos_mem_copy(pHddStaCtx->PMKIDCache[j].PMKID,
12018 pHddStaCtx->PMKIDCache[pHddStaCtx->PMKIDCacheIndex-1].PMKID,
12019 CSR_RSN_PMKID_SIZE);
12020 }
Wilson Yang6507c4e2013-10-01 20:11:19 -070012021
12022 /*clear the last entry in HDD cache ---[index-1]*/
Agarwal Ashish3da95242014-05-21 14:57:17 +053012023 vos_mem_zero(pHddStaCtx->PMKIDCache[pHddStaCtx->PMKIDCacheIndex-1].BSSID,
12024 VOS_MAC_ADDR_SIZE);
12025 vos_mem_zero(pHddStaCtx->PMKIDCache[pHddStaCtx->PMKIDCacheIndex-1].PMKID,
12026 CSR_RSN_PMKID_SIZE);
Wilson Yang6507c4e2013-10-01 20:11:19 -070012027 /*reduce the PMKID array index*/
Agarwal Ashish3da95242014-05-21 14:57:17 +053012028 pHddStaCtx->PMKIDCacheIndex--;
Wilson Yang6507c4e2013-10-01 20:11:19 -070012029 /*delete the last PMKID cache in CSR*/
Wilson Yangef657d32014-01-15 19:19:23 -080012030 if (eHAL_STATUS_SUCCESS !=
12031 sme_RoamDelPMKIDfromCache(halHandle, pAdapter->sessionId, pmksa->bssid))
Wilson Yang6507c4e2013-10-01 20:11:19 -070012032 {
12033 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: cannot delete PMKSA %d CONTENT.",
Agarwal Ashish3da95242014-05-21 14:57:17 +053012034 __func__, pHddStaCtx->PMKIDCacheIndex);
Wilson Yangef657d32014-01-15 19:19:23 -080012035 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -070012036 }
12037
12038 dump_bssid(pmksa->bssid);
12039 dump_pmkid(halHandle,pmksa->pmkid);
12040
12041 break;
12042 }
12043 }
12044
12045 /* we compare all entries,but cannot find matching entry */
12046 if (j == MAX_PMKSAIDS_IN_CACHE && !BSSIDMatched)
12047 {
Jeff Johnson0299d0a2013-10-30 12:37:43 -070012048 hddLog(VOS_TRACE_LEVEL_FATAL,
12049 "%s: No such PMKSA entry existed " MAC_ADDRESS_STR,
12050 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
Wilson Yang6507c4e2013-10-01 20:11:19 -070012051 dump_bssid(pmksa->bssid);
12052 dump_pmkid(halHandle, pmksa->pmkid);
12053 return -EINVAL;
12054 }
Wilson Yangef657d32014-01-15 19:19:23 -080012055 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012056}
12057
Wilson Yang6507c4e2013-10-01 20:11:19 -070012058
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053012059static int wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
12060 struct cfg80211_pmksa *pmksa)
12061{
12062 int ret;
Wilson Yang6507c4e2013-10-01 20:11:19 -070012063
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053012064 vos_ssr_protect(__func__);
12065 ret = __wlan_hdd_cfg80211_del_pmksa(wiphy, dev, pmksa);
12066 vos_ssr_unprotect(__func__);
12067
12068 return ret;
12069
12070}
12071
12072static int __wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012073{
Wilson Yang6507c4e2013-10-01 20:11:19 -070012074 tANI_U32 j=0;
12075 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Agarwal Ashish3da95242014-05-21 14:57:17 +053012076 hdd_station_ctx_t *pHddStaCtx;
Wilson Yang6507c4e2013-10-01 20:11:19 -070012077 tHalHandle halHandle;
12078 hdd_context_t *pHddCtx;
12079 tANI_U8 *pBSSId;
Wilson Yangef657d32014-01-15 19:19:23 -080012080 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070012081
12082 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: flushing PMKSA ",__func__);
12083
12084 /* Validate pAdapter */
12085 if (NULL == pAdapter)
12086 {
12087 hddLog(VOS_TRACE_LEVEL_ERROR,
12088 "%s: Invalid Adapter" ,__func__);
12089 return -EINVAL;
12090 }
12091
12092 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
12093 status = wlan_hdd_validate_context(pHddCtx);
12094
12095 if (0 != status)
12096 {
12097 hddLog(VOS_TRACE_LEVEL_ERROR,
12098 "%s: HDD context is not valid", __func__);
12099 return status;
12100 }
12101
12102 /*Retrieve halHandle*/
12103 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
Agarwal Ashish3da95242014-05-21 14:57:17 +053012104 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Wilson Yang6507c4e2013-10-01 20:11:19 -070012105
12106 /*in case index is 0,no entry to delete*/
Agarwal Ashish3da95242014-05-21 14:57:17 +053012107 if (0 == pHddStaCtx->PMKIDCacheIndex)
Wilson Yang6507c4e2013-10-01 20:11:19 -070012108 {
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053012109 hddLog(VOS_TRACE_LEVEL_ERROR, FL("No entries to flush"));
Agarwal Ashish3da95242014-05-21 14:57:17 +053012110 return 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070012111 }
12112
12113 /*delete all the PMKSA one by one */
Agarwal Ashish3da95242014-05-21 14:57:17 +053012114 for (j = 0; j < pHddStaCtx->PMKIDCacheIndex; j++)
Wilson Yang6507c4e2013-10-01 20:11:19 -070012115 {
Agarwal Ashish3da95242014-05-21 14:57:17 +053012116 pBSSId =(tANI_U8 *)(pHddStaCtx->PMKIDCache[j].BSSID);
Wilson Yang6507c4e2013-10-01 20:11:19 -070012117 /*delete the PMKID in CSR*/
Wilson Yangef657d32014-01-15 19:19:23 -080012118 if (eHAL_STATUS_SUCCESS !=
12119 sme_RoamDelPMKIDfromCache(halHandle, pAdapter->sessionId, pBSSId))
Wilson Yang6507c4e2013-10-01 20:11:19 -070012120 {
12121 hddLog(VOS_TRACE_LEVEL_ERROR ,"%s cannot flush PMKIDCache %d.",
12122 __func__,j);
Wilson Yangef657d32014-01-15 19:19:23 -080012123 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -070012124 }
Kiet Lam8d21d5b2013-10-31 17:18:29 +053012125 /*clear the entry in HDD cache 0--index-1 */
Agarwal Ashish3da95242014-05-21 14:57:17 +053012126 vos_mem_zero(pHddStaCtx->PMKIDCache[j].BSSID, VOS_MAC_ADDR_SIZE);
12127 vos_mem_zero(pHddStaCtx->PMKIDCache[j].PMKID, CSR_RSN_PMKID_SIZE);
12128 }
Wilson Yang6507c4e2013-10-01 20:11:19 -070012129
Agarwal Ashish3da95242014-05-21 14:57:17 +053012130 pHddStaCtx->PMKIDCacheIndex = 0;
Wilson Yangef657d32014-01-15 19:19:23 -080012131 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012132}
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053012133
12134static int wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
12135{
12136 int ret;
12137
12138 vos_ssr_protect(__func__);
12139 ret = __wlan_hdd_cfg80211_flush_pmksa(wiphy, dev);
12140 vos_ssr_unprotect(__func__);
12141
12142 return ret;
12143}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012144#endif
12145
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070012146#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012147static int __wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
12148 struct net_device *dev,
12149 struct cfg80211_update_ft_ies_params *ftie)
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070012150{
12151 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
12152 hdd_station_ctx_t *pHddStaCtx;
12153
12154 if (NULL == pAdapter)
12155 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080012156 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070012157 return -ENODEV;
12158 }
12159
12160 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
12161
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012162 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12163 TRACE_CODE_HDD_CFG80211_UPDATE_FT_IES,
12164 pAdapter->sessionId, pHddStaCtx->conn_info.connState));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070012165 // Added for debug on reception of Re-assoc Req.
12166 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
12167 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080012168 hddLog(LOGE, FL("Called with Ie of length = %zu when not associated"),
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070012169 ftie->ie_len);
Arif Hussain6d2a3322013-11-17 19:50:10 -080012170 hddLog(LOGE, FL("Should be Re-assoc Req IEs"));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070012171 }
12172
12173#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG
Arif Hussain6d2a3322013-11-17 19:50:10 -080012174 hddLog(LOGE, FL("%s called with Ie of length = %zu"), __func__,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070012175 ftie->ie_len);
12176#endif
12177
12178 // Pass the received FT IEs to SME
Gopichand Nakkala356fb102013-03-06 12:34:04 +053012179 sme_SetFTIEs( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
12180 (const u8 *)ftie->ie,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070012181 ftie->ie_len);
12182 return 0;
12183}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012184
12185static int wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
12186 struct net_device *dev,
12187 struct cfg80211_update_ft_ies_params *ftie)
12188{
12189 int ret;
12190
12191 vos_ssr_protect(__func__);
12192 ret = __wlan_hdd_cfg80211_update_ft_ies(wiphy, dev, ftie);
12193 vos_ssr_unprotect(__func__);
12194
12195 return ret;
12196}
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070012197#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012198
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012199#ifdef FEATURE_WLAN_SCAN_PNO
12200
12201void hdd_cfg80211_sched_scan_done_callback(void *callbackContext,
12202 tSirPrefNetworkFoundInd *pPrefNetworkFoundInd)
12203{
12204 int ret;
12205 hdd_adapter_t* pAdapter = (hdd_adapter_t*)callbackContext;
12206 hdd_context_t *pHddCtx;
12207
Nirav Shah80830bf2013-12-31 16:35:12 +053012208 ENTER();
12209
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012210 if (NULL == pAdapter)
12211 {
Agarwal Ashish971c2882013-10-30 20:11:12 +053012212 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012213 "%s: HDD adapter is Null", __func__);
12214 return ;
12215 }
12216
12217 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
12218 if (NULL == pHddCtx)
12219 {
12220 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12221 "%s: HDD context is Null!!!", __func__);
12222 return ;
12223 }
12224
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053012225 spin_lock(&pHddCtx->schedScan_lock);
12226 if (TRUE == pHddCtx->isWiphySuspended)
12227 {
12228 pHddCtx->isSchedScanUpdatePending = TRUE;
12229 spin_unlock(&pHddCtx->schedScan_lock);
12230 hddLog(VOS_TRACE_LEVEL_INFO,
12231 "%s: Update cfg80211 scan database after it resume", __func__);
12232 return ;
12233 }
12234 spin_unlock(&pHddCtx->schedScan_lock);
12235
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012236 ret = wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter);
12237
12238 if (0 > ret)
12239 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
12240
12241 cfg80211_sched_scan_results(pHddCtx->wiphy);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053012242 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12243 "%s: cfg80211 scan result database updated", __func__);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012244}
12245
12246/*
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053012247 * FUNCTION: wlan_hdd_is_pno_allowed
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053012248 * Disallow pno if any session is active
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053012249 */
12250static eHalStatus wlan_hdd_is_pno_allowed(hdd_adapter_t *pAdapter)
12251{
12252 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
12253 hdd_adapter_t *pTempAdapter = NULL;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053012254 hdd_station_ctx_t *pStaCtx;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053012255 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
12256 int status = 0;
12257 status = hdd_get_front_adapter(pHddCtx, &pAdapterNode);
12258
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053012259 /* The current firmware design does not allow PNO during any
12260 * active sessions. Hence, determine the active sessions
12261 * and return a failure.
12262 */
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053012263 while ((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status))
12264 {
12265 pTempAdapter = pAdapterNode->pAdapter;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053012266 pStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pTempAdapter);
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053012267
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053012268 if (((WLAN_HDD_INFRA_STATION == pTempAdapter->device_mode)
12269 && (eConnectionState_NotConnected != pStaCtx->conn_info.connState))
12270 || (WLAN_HDD_P2P_CLIENT == pTempAdapter->device_mode)
12271 || (WLAN_HDD_P2P_GO == pTempAdapter->device_mode)
12272 || (WLAN_HDD_SOFTAP == pTempAdapter->device_mode)
12273 )
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053012274 {
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053012275 return eHAL_STATUS_FAILURE;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053012276 }
12277 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
12278 pAdapterNode = pNext;
12279 }
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053012280 return eHAL_STATUS_SUCCESS;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053012281}
12282
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053012283void hdd_cfg80211_sched_scan_start_status_cb(void *callbackContext, VOS_STATUS status)
12284{
12285 hdd_adapter_t *pAdapter = callbackContext;
12286 hdd_context_t *pHddCtx;
12287
12288 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
12289 {
12290 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12291 FL("Invalid adapter or adapter has invalid magic"));
12292 return;
12293 }
12294
12295 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
12296 if (0 != wlan_hdd_validate_context(pHddCtx))
12297 {
12298 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12299 FL("HDD context is not valid"));
12300 return;
12301 }
12302
12303 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12304 FL("PNO enable response status = %d"), status);
12305
12306 pAdapter->pno_req_status = (status == VOS_STATUS_SUCCESS) ? 0 : -EBUSY;
12307 complete(&pAdapter->pno_comp_var);
12308}
12309
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053012310/*
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053012311 * FUNCTION: __wlan_hdd_cfg80211_sched_scan_start
12312 * Function to enable PNO
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012313 */
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053012314static int __wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012315 struct net_device *dev, struct cfg80211_sched_scan_request *request)
12316{
12317 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
12318 tpSirPNOScanReq pPnoRequest = NULL;
12319 hdd_context_t *pHddCtx;
12320 tHalHandle hHal;
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053012321 v_U32_t i, indx, num_ch, tempInterval;
Sushant Kaushikd62d9782014-02-19 15:39:40 +053012322 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
12323 u8 channels_allowed[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012324 v_U32_t num_channels_allowed = WNI_CFG_VALID_CHANNEL_LIST_LEN;
12325 eHalStatus status = eHAL_STATUS_FAILURE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053012326 int ret = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012327
12328 if (NULL == pAdapter)
12329 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012330 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012331 "%s: HDD adapter is Null", __func__);
12332 return -ENODEV;
12333 }
12334
12335 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053012336 ret = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012337
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053012338 if (0 != ret)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012339 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053012340 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12341 "%s: HDD context is not valid", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053012342 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012343 }
12344
12345 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
12346 if (NULL == hHal)
12347 {
12348 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12349 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053012350 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012351 }
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053012352
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053012353 ret = wlan_hdd_scan_abort(pAdapter);
Girish Gowli4bf7a632014-06-12 13:42:11 +053012354 if (ret < 0)
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053012355 {
12356 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12357 "%s: aborting the existing scan is unsuccessfull", __func__);
12358 return -EBUSY;
12359 }
12360
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053012361 if (eHAL_STATUS_SUCCESS != wlan_hdd_is_pno_allowed(pAdapter))
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053012362 {
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053012363 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053012364 FL("Cannot handle sched_scan"));
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053012365 return -EBUSY;
12366 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012367
c_hpothu37f21312014-04-09 21:49:54 +053012368 if (TRUE == pHddCtx->isPnoEnable)
12369 {
12370 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
12371 FL("already PNO is enabled"));
12372 return -EBUSY;
12373 }
12374 pHddCtx->isPnoEnable = TRUE;
12375
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012376 pPnoRequest = (tpSirPNOScanReq) vos_mem_malloc(sizeof (tSirPNOScanReq));
12377 if (NULL == pPnoRequest)
12378 {
12379 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
12380 "%s: vos_mem_malloc failed", __func__);
c_hpothu37f21312014-04-09 21:49:54 +053012381 pHddCtx->isPnoEnable = FALSE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053012382 return -ENOMEM;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012383 }
12384
Madan Mohan Koyyalamudic3f04352013-09-26 19:21:48 +053012385 memset(pPnoRequest, 0, sizeof (tSirPNOScanReq));
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012386 pPnoRequest->enable = 1; /*Enable PNO */
12387 pPnoRequest->ucNetworksCount = request->n_match_sets;
12388
12389 if (( !pPnoRequest->ucNetworksCount ) ||
12390 ( pPnoRequest->ucNetworksCount > SIR_PNO_MAX_SUPP_NETWORKS ))
12391 {
12392 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik1e406c32014-05-09 15:57:52 +053012393 "%s: Network input is not correct %d Max Network supported is %d",
12394 __func__, pPnoRequest->ucNetworksCount,
12395 SIR_PNO_MAX_SUPP_NETWORKS);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053012396 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012397 goto error;
12398 }
12399
12400 if ( SIR_PNO_MAX_NETW_CHANNELS_EX < request->n_channels )
12401 {
12402 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053012403 "%s: Incorrect number of channels %d",
12404 __func__, request->n_channels);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053012405 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012406 goto error;
12407 }
12408
12409 /* Framework provides one set of channels(all)
12410 * common for all saved profile */
12411 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
12412 channels_allowed, &num_channels_allowed))
12413 {
12414 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12415 "%s: failed to get valid channel list", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053012416 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012417 goto error;
12418 }
12419 /* Checking each channel against allowed channel list */
12420 num_ch = 0;
Nirav Shah80830bf2013-12-31 16:35:12 +053012421 if (request->n_channels)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012422 {
Nirav Shah80830bf2013-12-31 16:35:12 +053012423 char chList [(request->n_channels*5)+1];
12424 int len;
12425 for (i = 0, len = 0; i < request->n_channels; i++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012426 {
Nirav Shah80830bf2013-12-31 16:35:12 +053012427 for (indx = 0; indx < num_channels_allowed; indx++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012428 {
Nirav Shah80830bf2013-12-31 16:35:12 +053012429 if (request->channels[i]->hw_value == channels_allowed[indx])
12430 {
12431 valid_ch[num_ch++] = request->channels[i]->hw_value;
12432 len += snprintf(chList+len, 5, "%d ",
12433 request->channels[i]->hw_value);
12434 break ;
12435 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012436 }
12437 }
Nirav Shah80830bf2013-12-31 16:35:12 +053012438 hddLog(VOS_TRACE_LEVEL_INFO,"Channel-List: %s ", chList);
12439 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012440
12441 /* Filling per profile params */
12442 for (i = 0; i < pPnoRequest->ucNetworksCount; i++)
12443 {
12444 pPnoRequest->aNetworks[i].ssId.length =
12445 request->match_sets[i].ssid.ssid_len;
12446
12447 if (( 0 == pPnoRequest->aNetworks[i].ssId.length ) ||
12448 ( pPnoRequest->aNetworks[i].ssId.length > 32 ) )
12449 {
12450 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053012451 "%s: SSID Len %d is not correct for network %d",
12452 __func__, pPnoRequest->aNetworks[i].ssId.length, i);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053012453 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012454 goto error;
12455 }
12456
12457 memcpy(pPnoRequest->aNetworks[i].ssId.ssId,
12458 request->match_sets[i].ssid.ssid,
12459 request->match_sets[i].ssid.ssid_len);
Sushant Kaushik1e406c32014-05-09 15:57:52 +053012460 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12461 "%s: SSID of network %d is %s ", __func__,
12462 i, pPnoRequest->aNetworks[i].ssId.ssId);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012463 pPnoRequest->aNetworks[i].authentication = 0; /*eAUTH_TYPE_ANY*/
12464 pPnoRequest->aNetworks[i].encryption = 0; /*eED_ANY*/
12465 pPnoRequest->aNetworks[i].bcastNetwType = 0; /*eBCAST_UNKNOWN*/
12466
12467 /*Copying list of valid channel into request */
12468 memcpy(pPnoRequest->aNetworks[i].aChannels, valid_ch, num_ch);
12469 pPnoRequest->aNetworks[i].ucChannelCount = num_ch;
12470
12471 pPnoRequest->aNetworks[i].rssiThreshold = 0; //Default value
12472 }
12473
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053012474 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnson59a121e2013-11-30 09:46:08 -080012475 "request->ie_len = %zu", request->ie_len);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053012476 if ((0 < request->ie_len) && (NULL != request->ie))
12477 {
12478 pPnoRequest->us24GProbeTemplateLen = request->ie_len;
12479 memcpy(&pPnoRequest->p24GProbeTemplate, request->ie,
12480 pPnoRequest->us24GProbeTemplateLen);
12481
12482 pPnoRequest->us5GProbeTemplateLen = request->ie_len;
12483 memcpy(&pPnoRequest->p5GProbeTemplate, request->ie,
12484 pPnoRequest->us5GProbeTemplateLen);
12485 }
12486
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053012487 /* Driver gets only one time interval which is hardcoded in
12488 * supplicant for 10000ms. Taking power consumption into account 6 timers
12489 * will be used, Timervalue is increased exponentially i.e 10,20,40,
12490 * 80,160,320 secs. And number of scan cycle for each timer
12491 * is configurable through INI param gPNOScanTimerRepeatValue.
12492 * If it is set to 0 only one timer will be used and PNO scan cycle
12493 * will be repeated after each interval specified by supplicant
12494 * till PNO is disabled.
12495 */
12496 if (0 == pHddCtx->cfg_ini->configPNOScanTimerRepeatValue)
12497 pPnoRequest->scanTimers.ucScanTimersCount = HDD_PNO_SCAN_TIMERS_SET_ONE;
12498 else
12499 pPnoRequest->scanTimers.ucScanTimersCount =
12500 HDD_PNO_SCAN_TIMERS_SET_MULTIPLE;
12501
12502 tempInterval = (request->interval)/1000;
12503 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12504 "Base scan interval = %d PNOScanTimerRepeatValue = %d",
12505 tempInterval, pHddCtx->cfg_ini->configPNOScanTimerRepeatValue);
12506 for ( i = 0; i < pPnoRequest->scanTimers.ucScanTimersCount; i++)
12507 {
12508 pPnoRequest->scanTimers.aTimerValues[i].uTimerRepeat =
12509 pHddCtx->cfg_ini->configPNOScanTimerRepeatValue;
12510 pPnoRequest->scanTimers.aTimerValues[i].uTimerValue = tempInterval;
12511 tempInterval *= 2;
12512 }
12513 //Repeat last timer until pno disabled.
12514 pPnoRequest->scanTimers.aTimerValues[i-1].uTimerRepeat = 0;
12515
Madan Mohan Koyyalamudid206c7b2013-09-26 22:54:51 +053012516 pPnoRequest->modePNO = SIR_PNO_MODE_IMMEDIATE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012517
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053012518 INIT_COMPLETION(pAdapter->pno_comp_var);
12519 pPnoRequest->statusCallback = hdd_cfg80211_sched_scan_start_status_cb;
12520 pPnoRequest->callbackContext = pAdapter;
12521 pAdapter->pno_req_status = 0;
12522
Nirav Shah80830bf2013-12-31 16:35:12 +053012523 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12524 "SessionId %d, enable %d, modePNO %d, ucScanTimersCount %d",
12525 pAdapter->sessionId, pPnoRequest->enable, pPnoRequest->modePNO,
12526 pPnoRequest->scanTimers.ucScanTimersCount);
12527
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012528 status = sme_SetPreferredNetworkList(WLAN_HDD_GET_HAL_CTX(pAdapter),
12529 pPnoRequest, pAdapter->sessionId,
12530 hdd_cfg80211_sched_scan_done_callback, pAdapter);
12531 if (eHAL_STATUS_SUCCESS != status)
12532 {
12533 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053012534 "%s: Failed to enable PNO", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053012535 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012536 goto error;
12537 }
12538
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053012539 ret = wait_for_completion_timeout(
12540 &pAdapter->pno_comp_var,
12541 msecs_to_jiffies(WLAN_WAIT_TIME_PNO));
12542 if (0 >= ret)
12543 {
12544 // Did not receive the response for PNO enable in time.
12545 // Assuming the PNO enable was success.
12546 // Returning error from here, because we timeout, results
12547 // in side effect of Wifi (Wifi Setting) not to work.
12548 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12549 FL("Timed out waiting for PNO to be Enabled"));
12550 ret = 0;
12551 goto error;
12552 }
12553
c_hpothu3c986b22014-07-09 14:45:09 +053012554 vos_mem_free(pPnoRequest);
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053012555 ret = pAdapter->pno_req_status;
c_hpothu37f21312014-04-09 21:49:54 +053012556 return ret;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053012557
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012558error:
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053012559 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12560 FL("PNO scanRequest offloaded ret = %d"), ret);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012561 vos_mem_free(pPnoRequest);
c_hpothu37f21312014-04-09 21:49:54 +053012562 pHddCtx->isPnoEnable = FALSE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053012563 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012564}
12565
12566/*
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053012567 * FUNCTION: wlan_hdd_cfg80211_sched_scan_start
12568 * NL interface to enable PNO
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012569 */
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053012570static int wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
12571 struct net_device *dev, struct cfg80211_sched_scan_request *request)
12572{
12573 int ret;
12574
12575 vos_ssr_protect(__func__);
12576 ret = __wlan_hdd_cfg80211_sched_scan_start(wiphy, dev, request);
12577 vos_ssr_unprotect(__func__);
12578
12579 return ret;
12580}
12581
12582/*
12583 * FUNCTION: __wlan_hdd_cfg80211_sched_scan_stop
12584 * Function to disable PNO
12585 */
12586static int __wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012587 struct net_device *dev)
12588{
12589 eHalStatus status = eHAL_STATUS_FAILURE;
12590 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
12591 hdd_context_t *pHddCtx;
12592 tHalHandle hHal;
12593 tpSirPNOScanReq pPnoRequest = NULL;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053012594 int ret = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012595
12596 ENTER();
12597
12598 if (NULL == pAdapter)
12599 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012600 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012601 "%s: HDD adapter is Null", __func__);
12602 return -ENODEV;
12603 }
12604
12605 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012606
Kamath Vinayakba5313f2013-08-22 15:52:39 +053012607 if (NULL == pHddCtx)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012608 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053012609 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Kamath Vinayakba5313f2013-08-22 15:52:39 +053012610 "%s: HDD context is Null", __func__);
12611 return -ENODEV;
12612 }
12613
12614 /* The return 0 is intentional when isLogpInProgress and
12615 * isLoadUnloadInProgress. We did observe a crash due to a return of
12616 * failure in sched_scan_stop , especially for a case where the unload
12617 * of the happens at the same time. The function __cfg80211_stop_sched_scan
12618 * was clearing rdev->sched_scan_req only when the sched_scan_stop returns
12619 * success. If it returns a failure , then its next invocation due to the
12620 * clean up of the second interface will have the dev pointer corresponding
12621 * to the first one leading to a crash.
12622 */
12623 if (pHddCtx->isLogpInProgress)
12624 {
12625 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12626 "%s: LOGP in Progress. Ignore!!!", __func__);
12627 return ret;
12628 }
12629
Mihir Shete18156292014-03-11 15:38:30 +053012630 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Kamath Vinayakba5313f2013-08-22 15:52:39 +053012631 {
12632 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12633 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
12634 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012635 }
12636
12637 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
12638 if (NULL == hHal)
12639 {
12640 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12641 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053012642 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012643 }
12644
12645 pPnoRequest = (tpSirPNOScanReq) vos_mem_malloc(sizeof (tSirPNOScanReq));
12646 if (NULL == pPnoRequest)
12647 {
12648 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
12649 "%s: vos_mem_malloc failed", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053012650 return -ENOMEM;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012651 }
12652
12653 memset(pPnoRequest, 0, sizeof (tSirPNOScanReq));
12654 pPnoRequest->enable = 0; /* Disable PNO */
12655 pPnoRequest->ucNetworksCount = 0;
12656
12657 status = sme_SetPreferredNetworkList(hHal, pPnoRequest,
12658 pAdapter->sessionId,
12659 NULL, pAdapter);
12660 if (eHAL_STATUS_SUCCESS != status)
12661 {
12662 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12663 "Failed to disabled PNO");
Kamath Vinayakba5313f2013-08-22 15:52:39 +053012664 ret = -EINVAL;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053012665 goto error;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012666 }
c_hpothu37f21312014-04-09 21:49:54 +053012667 pHddCtx->isPnoEnable = FALSE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012668
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053012669error:
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053012670 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053012671 FL("PNO scan disabled ret = %d"), ret);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012672 vos_mem_free(pPnoRequest);
12673
12674 EXIT();
Kamath Vinayakba5313f2013-08-22 15:52:39 +053012675 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012676}
12677
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053012678/*
12679 * FUNCTION: wlan_hdd_cfg80211_sched_scan_stop
12680 * NL interface to disable PNO
12681 */
12682static int wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
12683 struct net_device *dev)
12684{
12685 int ret;
12686
12687 vos_ssr_protect(__func__);
12688 ret = __wlan_hdd_cfg80211_sched_scan_stop(wiphy, dev);
12689 vos_ssr_unprotect(__func__);
12690
12691 return ret;
12692}
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053012693#endif /*FEATURE_WLAN_SCAN_PNO*/
12694
12695
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012696#ifdef FEATURE_WLAN_TDLS
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053012697#if TDLS_MGMT_VERSION2
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012698static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
12699 u8 *peer, u8 action_code, u8 dialog_token,
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053012700 u16 status_code, u32 peer_capability, const u8 *buf, size_t len)
12701#else
12702static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
12703 u8 *peer, u8 action_code, u8 dialog_token,
12704 u16 status_code, const u8 *buf, size_t len)
12705#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012706{
12707
12708 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
12709 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012710 u8 peerMac[6];
12711 VOS_STATUS status;
Gopichand Nakkala05922802013-03-14 12:23:19 -070012712 int max_sta_failed = 0;
Hoonki Leea34dd892013-02-05 22:56:02 -080012713 int responder;
Hoonki Leed37cbb32013-04-20 00:31:14 -070012714 long rc;
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053012715#if !(TDLS_MGMT_VERSION2)
12716 u32 peer_capability = 0;
12717#endif
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053012718 tANI_U16 numCurrTdlsPeers;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012719
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012720 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12721 TRACE_CODE_HDD_CFG80211_TDLS_MGMT,
12722 pAdapter->sessionId, action_code));
Hoonki Lee11f7dda2013-02-14 16:55:44 -080012723 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012724 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012725 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012726 "Invalid arguments");
12727 return -EINVAL;
12728 }
12729
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080012730 if (pHddCtx->isLogpInProgress)
12731 {
12732 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12733 "%s:LOGP in Progress. Ignore!!!", __func__);
Gopichand Nakkala05922802013-03-14 12:23:19 -070012734 wlan_hdd_tdls_set_link_status(pAdapter, peer, eTDLS_LINK_IDLE);
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080012735 return -EBUSY;
12736 }
12737
Hoonki Lee27511902013-03-14 18:19:06 -070012738 if (eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012739 {
Hoonki Lee27511902013-03-14 18:19:06 -070012740 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
12741 "%s: TDLS mode is disabled OR not enabled in FW."
12742 MAC_ADDRESS_STR " action %d declined.",
12743 __func__, MAC_ADDR_ARRAY(peer), action_code);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012744 return -ENOTSUPP;
12745 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080012746
Hoonki Lee27511902013-03-14 18:19:06 -070012747 /* other than teardown frame, other mgmt frames are not sent if disabled */
12748 if (SIR_MAC_TDLS_TEARDOWN != action_code)
12749 {
12750 /* if tdls_mode is disabled to respond to peer's request */
12751 if (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode)
12752 {
12753 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
12754 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070012755 " TDLS mode is disabled. action %d declined.",
12756 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee27511902013-03-14 18:19:06 -070012757
12758 return -ENOTSUPP;
12759 }
Agarwal Ashish4b87f922014-06-18 03:03:21 +053012760
12761 if (vos_max_concurrent_connections_reached())
12762 {
12763 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
12764 return -EINVAL;
12765 }
Hoonki Lee27511902013-03-14 18:19:06 -070012766 }
12767
Gopichand Nakkalab977a972013-02-18 19:15:09 -080012768 if (WLAN_IS_TDLS_SETUP_ACTION(action_code))
12769 {
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053012770 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, peer, TRUE))
Gopichand Nakkalab977a972013-02-18 19:15:09 -080012771 {
12772 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070012773 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070012774 " TDLS setup is ongoing. action %d declined.",
12775 __func__, MAC_ADDR_ARRAY(peer), action_code);
12776 return -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080012777 }
12778 }
12779
Hoonki Lee11f7dda2013-02-14 16:55:44 -080012780 if (SIR_MAC_TDLS_SETUP_REQ == action_code ||
12781 SIR_MAC_TDLS_SETUP_RSP == action_code )
Lee Hoonkic1262f22013-01-24 21:59:00 -080012782 {
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053012783 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
12784 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Lee Hoonkic1262f22013-01-24 21:59:00 -080012785 {
12786 /* supplicant still sends tdls_mgmt(SETUP_REQ) even after
12787 we return error code at 'add_station()'. Hence we have this
12788 check again in addtion to add_station().
12789 Anyway, there is no hard to double-check. */
Hoonki Lee11f7dda2013-02-14 16:55:44 -080012790 if (SIR_MAC_TDLS_SETUP_REQ == action_code)
Lee Hoonkic1262f22013-01-24 21:59:00 -080012791 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070012792 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12793 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053012794 " TDLS Max peer already connected. action (%d) declined. Num of peers (%d), Max allowed (%d).",
12795 __func__, MAC_ADDR_ARRAY(peer), action_code,
12796 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Sunil Dutt388ac8f2013-11-28 18:06:52 +053012797 return -EINVAL;
Lee Hoonkic1262f22013-01-24 21:59:00 -080012798 }
12799 else
12800 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -080012801 /* maximum reached. tweak to send error code to peer and return
12802 error code to supplicant */
Lee Hoonkic1262f22013-01-24 21:59:00 -080012803 status_code = eSIR_MAC_UNSPEC_FAILURE_STATUS;
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070012804 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12805 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053012806 " TDLS Max peer already connected, send response status (%d). Num of peers (%d), Max allowed (%d).",
12807 __func__, MAC_ADDR_ARRAY(peer), status_code,
12808 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -070012809 max_sta_failed = -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080012810 /* fall through to send setup resp with failure status
12811 code */
Lee Hoonkic1262f22013-01-24 21:59:00 -080012812 }
12813 }
Hoonki Lee11f7dda2013-02-14 16:55:44 -080012814 else
12815 {
12816 hddTdlsPeer_t *pTdlsPeer;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053012817 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012818 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Hoonki Lee11f7dda2013-02-14 16:55:44 -080012819 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070012820 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070012821 "%s:" MAC_ADDRESS_STR " already connected. action %d declined.",
12822 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080012823 return -EPERM;
12824 }
12825 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080012826 }
Hoonki Lee11f7dda2013-02-14 16:55:44 -080012827 vos_mem_copy(peerMac, peer, 6);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012828
Hoonki Lee1090c6a2013-01-16 17:40:54 -080012829#ifdef WLAN_FEATURE_TDLS_DEBUG
12830 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +053012831 "%s: " MAC_ADDRESS_STR " action %d, dialog_token %d status %d, len = %zu",
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070012832 "tdls_mgmt", MAC_ADDR_ARRAY(peer),
12833 action_code, dialog_token, status_code, len);
Hoonki Lee1090c6a2013-01-16 17:40:54 -080012834#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012835
Hoonki Leea34dd892013-02-05 22:56:02 -080012836 /*Except teardown responder will not be used so just make 0*/
12837 responder = 0;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080012838 if (SIR_MAC_TDLS_TEARDOWN == action_code)
Hoonki Leea34dd892013-02-05 22:56:02 -080012839 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070012840
12841 hddTdlsPeer_t *pTdlsPeer;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053012842 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peerMac, TRUE);
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070012843
12844 if(pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
12845 responder = pTdlsPeer->is_responder;
12846 else
Hoonki Leea34dd892013-02-05 22:56:02 -080012847 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070012848 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +053012849 "%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 -070012850 __func__, MAC_ADDR_ARRAY(peer), (NULL == pTdlsPeer) ? -1 : pTdlsPeer->link_status,
12851 dialog_token, status_code, len);
12852 return -EPERM;
Hoonki Leea34dd892013-02-05 22:56:02 -080012853 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012854 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012855
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053012856 /* For explicit trigger of DIS_REQ come out of BMPS for
12857 successfully receiving DIS_RSP from peer. */
Hoonki Lee14621352013-04-16 17:51:19 -070012858 if ((SIR_MAC_TDLS_SETUP_RSP == action_code) ||
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053012859 (SIR_MAC_TDLS_DIS_RSP == action_code) ||
12860 (SIR_MAC_TDLS_DIS_REQ == action_code))
Hoonki Lee14621352013-04-16 17:51:19 -070012861 {
12862 if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter)))
12863 {
12864 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053012865 "%s: Sending frame action_code %u.Disable BMPS", __func__, action_code);
Hoonki Lee14621352013-04-16 17:51:19 -070012866 hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
12867 }
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053012868 if (SIR_MAC_TDLS_DIS_REQ != action_code)
12869 wlan_hdd_tdls_set_cap(pAdapter, peerMac, eTDLS_CAP_SUPPORTED);
Hoonki Lee14621352013-04-16 17:51:19 -070012870 }
12871
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012872 /* make sure doesn't call send_mgmt() while it is pending */
12873 if (TDLS_CTX_MAGIC == pAdapter->mgmtTxCompletionStatus)
12874 {
12875 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080012876 "%s: " MAC_ADDRESS_STR " action %d couldn't sent, as one is pending. return EBUSY",
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012877 __func__, MAC_ADDR_ARRAY(peer), action_code);
12878 return -EBUSY;
12879 }
12880
12881 pAdapter->mgmtTxCompletionStatus = TDLS_CTX_MAGIC;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080012882 INIT_COMPLETION(pAdapter->tdls_mgmt_comp);
12883
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012884 status = sme_SendTdlsMgmtFrame(WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
Pradeep Reddy POTTETIca171f82014-03-21 14:17:35 +053012885 peerMac, action_code, dialog_token, status_code, peer_capability, (tANI_U8 *)buf, len, responder);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012886
Gopichand Nakkalab977a972013-02-18 19:15:09 -080012887 if (VOS_STATUS_SUCCESS != status)
12888 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012889 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12890 "%s: sme_SendTdlsMgmtFrame failed!", __func__);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012891 pAdapter->mgmtTxCompletionStatus = FALSE;
Hoonki Lee14621352013-04-16 17:51:19 -070012892 wlan_hdd_tdls_check_bmps(pAdapter);
Sunil Dutt388ac8f2013-11-28 18:06:52 +053012893 return -EINVAL;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012894 }
12895
Hoonki Leed37cbb32013-04-20 00:31:14 -070012896 rc = wait_for_completion_interruptible_timeout(&pAdapter->tdls_mgmt_comp,
12897 msecs_to_jiffies(WAIT_TIME_TDLS_MGMT));
12898
12899 if ((rc <= 0) || (TRUE != pAdapter->mgmtTxCompletionStatus))
Gopichand Nakkalab977a972013-02-18 19:15:09 -080012900 {
Hoonki Leed37cbb32013-04-20 00:31:14 -070012901 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson0299d0a2013-10-30 12:37:43 -070012902 "%s: Mgmt Tx Completion failed status %ld TxCompletion %u",
Hoonki Leed37cbb32013-04-20 00:31:14 -070012903 __func__, rc, pAdapter->mgmtTxCompletionStatus);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012904 pAdapter->mgmtTxCompletionStatus = FALSE;
Yue Ma4f55ef32014-01-23 16:45:33 -080012905
12906 if (pHddCtx->isLogpInProgress)
12907 {
12908 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12909 "%s: LOGP in Progress. Ignore!!!", __func__);
12910 return -EAGAIN;
12911 }
12912
Hoonki Leed37cbb32013-04-20 00:31:14 -070012913 wlan_hdd_tdls_check_bmps(pAdapter);
Sunil Dutt388ac8f2013-11-28 18:06:52 +053012914 return -EINVAL;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080012915 }
12916
Gopichand Nakkala05922802013-03-14 12:23:19 -070012917 if (max_sta_failed)
Hoonki Lee14621352013-04-16 17:51:19 -070012918 {
12919 wlan_hdd_tdls_check_bmps(pAdapter);
Gopichand Nakkala05922802013-03-14 12:23:19 -070012920 return max_sta_failed;
Hoonki Lee14621352013-04-16 17:51:19 -070012921 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -080012922
Hoonki Leea34dd892013-02-05 22:56:02 -080012923 if (SIR_MAC_TDLS_SETUP_RSP == action_code)
12924 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -080012925 wlan_hdd_tdls_set_responder(pAdapter, peerMac, TRUE);
Hoonki Leea34dd892013-02-05 22:56:02 -080012926 }
12927 else if (SIR_MAC_TDLS_SETUP_CNF == action_code)
12928 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -080012929 wlan_hdd_tdls_set_responder(pAdapter, peerMac, FALSE);
Hoonki Leea34dd892013-02-05 22:56:02 -080012930 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012931
12932 return 0;
12933}
12934
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012935static int __wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012936 u8 *peer, enum nl80211_tdls_operation oper)
12937{
12938 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
12939 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012940 int status;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012941 hddTdlsPeer_t *pTdlsPeer;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012942
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012943 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12944 TRACE_CODE_HDD_CFG80211_TDLS_OPER,
12945 pAdapter->sessionId, oper));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012946 if ( NULL == peer )
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012947 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -080012948 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chilam Ngc4244af2013-04-01 15:37:32 -070012949 "%s: Invalid arguments", __func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012950 return -EINVAL;
12951 }
Hoonki Lee1090c6a2013-01-16 17:40:54 -080012952
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012953 status = wlan_hdd_validate_context(pHddCtx);
12954
12955 if (0 != status)
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080012956 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012957 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12958 "%s: HDD context is not valid", __func__);
12959 return status;
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080012960 }
12961
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012962
12963 if( FALSE == pHddCtx->cfg_ini->fEnableTDLSSupport ||
Hoonki Lee1090c6a2013-01-16 17:40:54 -080012964 FALSE == sme_IsFeatureSupportedByFW(TDLS))
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012965 {
Hoonki Lee1090c6a2013-01-16 17:40:54 -080012966 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chilam Ngc4244af2013-04-01 15:37:32 -070012967 "TDLS Disabled in INI OR not enabled in FW. "
12968 "Cannot process TDLS commands");
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012969 return -ENOTSUPP;
12970 }
12971
12972 switch (oper) {
12973 case NL80211_TDLS_ENABLE_LINK:
12974 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012975 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012976 long ret;
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053012977 tCsrTdlsLinkEstablishParams tdlsLinkEstablishParams;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080012978
Sunil Dutt41de4e22013-11-14 18:09:02 +053012979 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
12980
12981 if ( NULL == pTdlsPeer ) {
12982 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
12983 " (oper %d) not exsting. ignored",
12984 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
12985 return -EINVAL;
12986 }
12987
12988 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12989 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
12990 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
12991 "NL80211_TDLS_ENABLE_LINK");
12992
Gopichand Nakkala2f4a2822013-04-17 11:22:01 -070012993 if (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
12994 {
12995 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Staion Index %u "
12996 MAC_ADDRESS_STR " failed",
12997 __func__, pTdlsPeer->staId, MAC_ADDR_ARRAY(peer));
12998 return -EINVAL;
12999 }
13000
Hoonki Lee5305c3a2013-04-29 23:28:59 -070013001 if (eTDLS_LINK_CONNECTED != pTdlsPeer->link_status)
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070013002 {
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053013003 if (IS_ADVANCE_TDLS_ENABLE) {
Gopichand Nakkala24be5312013-07-02 16:47:12 +053013004
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053013005 if (0 != wlan_hdd_tdls_get_link_establish_params(
13006 pAdapter, peer,&tdlsLinkEstablishParams)) {
13007 return -EINVAL;
13008 }
13009 INIT_COMPLETION(pAdapter->tdls_link_establish_req_comp);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053013010
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053013011 sme_SendTdlsLinkEstablishParams(WLAN_HDD_GET_HAL_CTX(pAdapter),
13012 pAdapter->sessionId, peer, &tdlsLinkEstablishParams);
13013 /* Send TDLS peer UAPSD capabilities to the firmware and
13014 * register with the TL on after the response for this operation
13015 * is received .
13016 */
13017 ret = wait_for_completion_interruptible_timeout(
13018 &pAdapter->tdls_link_establish_req_comp,
13019 msecs_to_jiffies(WAIT_TIME_TDLS_LINK_ESTABLISH_REQ));
13020 if (ret <= 0)
13021 {
13022 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13023 "%s: Link Establish Request Faled Status %ld",
13024 __func__, ret);
13025 return -EINVAL;
13026 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053013027 }
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070013028 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer, eTDLS_LINK_CONNECTED);
Gopichand Nakkala471708b2013-06-04 20:03:01 +053013029 /* Mark TDLS client Authenticated .*/
13030 status = WLANTL_ChangeSTAState( pHddCtx->pvosContext,
13031 pTdlsPeer->staId,
13032 WLANTL_STA_AUTHENTICATED);
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070013033 if (VOS_STATUS_SUCCESS == status)
13034 {
Hoonki Lee14621352013-04-16 17:51:19 -070013035 if (pTdlsPeer->is_responder == 0)
13036 {
13037 v_U8_t staId = (v_U8_t)pTdlsPeer->staId;
13038
13039 wlan_hdd_tdls_timer_restart(pAdapter,
13040 &pTdlsPeer->initiatorWaitTimeoutTimer,
13041 WAIT_TIME_TDLS_INITIATOR);
13042 /* suspend initiator TX until it receives direct packet from the
13043 reponder or WAIT_TIME_TDLS_INITIATOR timer expires */
13044 WLANTL_SuspendDataTx( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
13045 &staId, NULL);
13046 }
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070013047 wlan_hdd_tdls_increment_peer_count(pAdapter);
13048 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070013049 wlan_hdd_tdls_check_bmps(pAdapter);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053013050
13051 /* Update TL about the UAPSD masks , to route the packets to firmware */
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053013052 if ((TRUE == pHddCtx->cfg_ini->fEnableTDLSBufferSta)
13053 || pHddCtx->cfg_ini->fTDLSUapsdMask )
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053013054 {
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053013055 int ac;
13056 uint8 ucAc[4] = { WLANTL_AC_VO,
13057 WLANTL_AC_VI,
13058 WLANTL_AC_BK,
13059 WLANTL_AC_BE };
13060 uint8 tlTid[4] = { 7, 5, 2, 3 } ;
13061 for(ac=0; ac < 4; ac++)
13062 {
13063 status = WLANTL_EnableUAPSDForAC( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
13064 pTdlsPeer->staId, ucAc[ac],
13065 tlTid[ac], tlTid[ac], 0, 0,
13066 WLANTL_BI_DIR );
13067 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053013068 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070013069 }
13070
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013071 }
13072 break;
13073 case NL80211_TDLS_DISABLE_LINK:
Lee Hoonkic1262f22013-01-24 21:59:00 -080013074 {
Sunil Dutt41de4e22013-11-14 18:09:02 +053013075 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
13076
13077 if ( NULL == pTdlsPeer ) {
13078 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
13079 " (oper %d) not exsting. ignored",
13080 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
13081 return -EINVAL;
13082 }
13083
13084 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13085 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
13086 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
13087 "NL80211_TDLS_DISABLE_LINK");
13088
Hoonki Lee5305c3a2013-04-29 23:28:59 -070013089 if(TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
Lee Hoonkic1262f22013-01-24 21:59:00 -080013090 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070013091 long status;
13092
13093 INIT_COMPLETION(pAdapter->tdls_del_station_comp);
13094
Lee Hoonkic1262f22013-01-24 21:59:00 -080013095 sme_DeleteTdlsPeerSta( WLAN_HDD_GET_HAL_CTX(pAdapter),
13096 pAdapter->sessionId, peer );
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070013097
13098 status = wait_for_completion_interruptible_timeout(&pAdapter->tdls_del_station_comp,
13099 msecs_to_jiffies(WAIT_TIME_TDLS_DEL_STA));
13100 if (status <= 0)
13101 {
Hoonki Lee5305c3a2013-04-29 23:28:59 -070013102 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer, eTDLS_LINK_IDLE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070013103 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13104 "%s: Del station failed status %ld",
13105 __func__, status);
13106 return -EPERM;
13107 }
Hoonki Lee5305c3a2013-04-29 23:28:59 -070013108 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer, eTDLS_LINK_IDLE);
Lee Hoonkic1262f22013-01-24 21:59:00 -080013109 }
13110 else
13111 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070013112 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13113 "%s: TDLS Peer Station doesn't exist.", __func__);
Lee Hoonkic1262f22013-01-24 21:59:00 -080013114 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080013115 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070013116 break;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013117 case NL80211_TDLS_TEARDOWN:
Sunil Dutt41de4e22013-11-14 18:09:02 +053013118 {
13119 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13120 " %s : NL80211_TDLS_TEARDOWN for " MAC_ADDRESS_STR,
13121 __func__, MAC_ADDR_ARRAY(peer));
13122
13123 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
13124 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
13125
13126 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13127 " %s TDLS External control and Implicit Trigger not enabled ",
13128 __func__);
13129 return -ENOTSUPP;
13130 }
13131
Sunil Dutt41de4e22013-11-14 18:09:02 +053013132
13133 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
13134
13135 if ( NULL == pTdlsPeer ) {
13136 hddLog(VOS_TRACE_LEVEL_INFO, "%s: " MAC_ADDRESS_STR
13137 " peer not exsting",
13138 __func__, MAC_ADDR_ARRAY(peer));
Naresh Jayaram937abdf2013-11-26 19:50:25 +053013139 return -EINVAL;
Sunil Dutt41de4e22013-11-14 18:09:02 +053013140 }
13141 else {
13142 wlan_hdd_tdls_indicate_teardown(pAdapter, pTdlsPeer,
13143 eSIR_MAC_TDLS_TEARDOWN_UNSPEC_REASON);
13144 }
Naresh Jayaram937abdf2013-11-26 19:50:25 +053013145
13146 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, FALSE) )
13147 return -EINVAL;
Sunil Dutt41de4e22013-11-14 18:09:02 +053013148 break;
13149 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013150 case NL80211_TDLS_SETUP:
Sunil Dutt41de4e22013-11-14 18:09:02 +053013151 {
Naresh Jayaramdb4514b2013-11-25 18:08:10 +053013152 hddTdlsPeer_t *pTdlsPeer;
Sunil Dutt41de4e22013-11-14 18:09:02 +053013153 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13154 " %s : NL80211_TDLS_SETUP for " MAC_ADDRESS_STR,
13155 __func__, MAC_ADDR_ARRAY(peer));
13156
13157 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
13158 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
13159
13160 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13161 " %s TDLS External control and Implicit Trigger not enabled ",
13162 __func__);
13163 return -ENOTSUPP;
13164 }
13165
Naresh Jayaramdb4514b2013-11-25 18:08:10 +053013166 /* To cater the requirement of establishing the TDLS link
13167 * irrespective of the data traffic , get an entry of TDLS peer.
13168 */
13169 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, peer);
13170 if (pTdlsPeer == NULL) {
13171 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13172 "%s: peer " MAC_ADDRESS_STR " not existing",
13173 __func__, MAC_ADDR_ARRAY(peer));
13174 return -EINVAL;
13175 }
Naresh Jayaram937abdf2013-11-26 19:50:25 +053013176
13177 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, TRUE) ) {
13178
13179 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13180 " %s TDLS Add Force Peer Failed",
13181 __func__);
13182 return -EINVAL;
13183 }
Naresh Jayaramdb4514b2013-11-25 18:08:10 +053013184 break;
Sunil Dutt41de4e22013-11-14 18:09:02 +053013185 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013186 case NL80211_TDLS_DISCOVERY_REQ:
13187 /* We don't support in-driver setup/teardown/discovery */
c_hpothu6ff1c3c2013-10-01 19:01:57 +053013188 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
13189 "%s: We don't support in-driver setup/teardown/discovery "
13190 ,__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013191 return -ENOTSUPP;
13192 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +053013193 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13194 "%s: unsupported event",__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013195 return -ENOTSUPP;
13196 }
13197 return 0;
13198}
Chilam NG571c65a2013-01-19 12:27:36 +053013199
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013200static int wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
13201 u8 *peer, enum nl80211_tdls_operation oper)
13202{
13203 int ret;
13204
13205 vos_ssr_protect(__func__);
13206 ret = __wlan_hdd_cfg80211_tdls_oper(wiphy, dev, peer, oper);
13207 vos_ssr_unprotect(__func__);
13208
13209 return ret;
13210}
13211
Chilam NG571c65a2013-01-19 12:27:36 +053013212int wlan_hdd_cfg80211_send_tdls_discover_req(struct wiphy *wiphy,
13213 struct net_device *dev, u8 *peer)
13214{
Arif Hussaina7c8e412013-11-20 11:06:42 -080013215 hddLog(VOS_TRACE_LEVEL_INFO,
13216 "tdls send discover req: "MAC_ADDRESS_STR,
13217 MAC_ADDR_ARRAY(peer));
Chilam NG571c65a2013-01-19 12:27:36 +053013218
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053013219#if TDLS_MGMT_VERSION2
13220 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
13221 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
13222#else
Chilam NG571c65a2013-01-19 12:27:36 +053013223 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
13224 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, NULL, 0);
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053013225#endif
Chilam NG571c65a2013-01-19 12:27:36 +053013226}
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013227#endif
13228
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013229#ifdef WLAN_FEATURE_GTK_OFFLOAD
13230/*
13231 * FUNCTION: wlan_hdd_cfg80211_update_replayCounterCallback
13232 * Callback rountine called upon receiving response for
13233 * get offload info
13234 */
13235void wlan_hdd_cfg80211_update_replayCounterCallback(void *callbackContext,
13236 tpSirGtkOffloadGetInfoRspParams pGtkOffloadGetInfoRsp)
13237{
13238
13239 hdd_adapter_t *pAdapter = (hdd_adapter_t *)callbackContext;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053013240 tANI_U8 tempReplayCounter[8];
13241 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013242
13243 ENTER();
13244
13245 if (NULL == pAdapter)
13246 {
Agarwal Ashish971c2882013-10-30 20:11:12 +053013247 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013248 "%s: HDD adapter is Null", __func__);
13249 return ;
13250 }
13251
13252 if (NULL == pGtkOffloadGetInfoRsp)
13253 {
13254 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13255 "%s: pGtkOffloadGetInfoRsp is Null", __func__);
13256 return ;
13257 }
13258
13259 if (VOS_STATUS_SUCCESS != pGtkOffloadGetInfoRsp->ulStatus)
13260 {
13261 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13262 "%s: wlan Failed to get replay counter value",
13263 __func__);
13264 return ;
13265 }
13266
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053013267 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13268 /* Update replay counter */
13269 pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter =
13270 pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
13271
13272 {
13273 /* changing from little to big endian since supplicant
13274 * works on big endian format
13275 */
13276 int i;
13277 tANI_U8 *p = (tANI_U8 *)&pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
13278
13279 for (i = 0; i < 8; i++)
13280 {
13281 tempReplayCounter[7-i] = (tANI_U8)p[i];
13282 }
13283 }
13284
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013285 /* Update replay counter to NL */
13286 cfg80211_gtk_rekey_notify(pAdapter->dev, pGtkOffloadGetInfoRsp->bssId,
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053013287 tempReplayCounter, GFP_KERNEL);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013288}
13289
13290/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013291 * FUNCTION: __wlan_hdd_cfg80211_set_rekey_data
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013292 * This function is used to offload GTK rekeying job to the firmware.
13293 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013294int __wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013295 struct cfg80211_gtk_rekey_data *data)
13296{
13297 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
13298 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
13299 hdd_station_ctx_t *pHddStaCtx;
13300 tHalHandle hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013301 int result;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053013302 tSirGtkOffloadParams hddGtkOffloadReqParams;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013303 eHalStatus status = eHAL_STATUS_FAILURE;
13304
13305 ENTER();
13306
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013307
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013308 if (NULL == pAdapter)
13309 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013310 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013311 "%s: HDD adapter is Null", __func__);
13312 return -ENODEV;
13313 }
13314
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013315 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13316 TRACE_CODE_HDD_CFG80211_SET_REKEY_DATA,
13317 pAdapter->sessionId, pAdapter->device_mode));
13318
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013319 result = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013320
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013321 if (0 != result)
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013322 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013323 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13324 "%s: HDD context is not valid", __func__);
13325 return result;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013326 }
13327
13328 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13329 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
13330 if (NULL == hHal)
13331 {
13332 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13333 "%s: HAL context is Null!!!", __func__);
13334 return -EAGAIN;
13335 }
13336
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053013337 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_ENABLE;
13338 memcpy(pHddStaCtx->gtkOffloadReqParams.aKCK, data->kck, NL80211_KCK_LEN);
13339 memcpy(pHddStaCtx->gtkOffloadReqParams.aKEK, data->kek, NL80211_KEK_LEN);
13340 memcpy(pHddStaCtx->gtkOffloadReqParams.bssId, &pHddStaCtx->conn_info.bssId,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013341 WNI_CFG_BSSID_LEN);
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053013342 {
13343 /* changing from big to little endian since driver
13344 * works on little endian format
13345 */
13346 tANI_U8 *p =
13347 (tANI_U8 *)&pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter;
13348 int i;
13349
13350 for (i = 0; i < 8; i++)
13351 {
13352 p[7-i] = data->replay_ctr[i];
13353 }
13354 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013355
13356 if (TRUE == pHddCtx->hdd_wlan_suspended)
13357 {
13358 /* if wlan is suspended, enable GTK offload directly from here */
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053013359 memcpy(&hddGtkOffloadReqParams, &pHddStaCtx->gtkOffloadReqParams,
13360 sizeof (tSirGtkOffloadParams));
13361 status = sme_SetGTKOffload(hHal, &hddGtkOffloadReqParams,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013362 pAdapter->sessionId);
13363
13364 if (eHAL_STATUS_SUCCESS != status)
13365 {
13366 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13367 "%s: sme_SetGTKOffload failed, returned %d",
13368 __func__, status);
13369 return status;
13370 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013371 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13372 "%s: sme_SetGTKOffload successfull", __func__);
13373 }
13374 else
13375 {
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013376 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13377 "%s: wlan not suspended GTKOffload request is stored",
13378 __func__);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013379 }
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053013380
13381 return eHAL_STATUS_SUCCESS;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013382}
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013383
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013384int wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
13385 struct cfg80211_gtk_rekey_data *data)
13386{
13387 int ret;
13388
13389 vos_ssr_protect(__func__);
13390 ret = __wlan_hdd_cfg80211_set_rekey_data(wiphy, dev, data);
13391 vos_ssr_unprotect(__func__);
13392
13393 return ret;
13394}
13395#endif /*WLAN_FEATURE_GTK_OFFLOAD*/
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053013396/*
13397 * FUNCTION: wlan_hdd_cfg80211_set_mac_acl
13398 * This function is used to set access control policy
13399 */
13400static int wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy,
13401 struct net_device *dev, const struct cfg80211_acl_data *params)
13402{
13403 int i;
13404 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
13405 hdd_hostapd_state_t *pHostapdState;
13406 tsap_Config_t *pConfig;
13407 v_CONTEXT_t pVosContext = NULL;
13408 hdd_context_t *pHddCtx;
13409 int status;
13410
13411 ENTER();
13412
13413 if (NULL == pAdapter)
13414 {
13415 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
13416 "%s: HDD adapter is Null", __func__);
13417 return -ENODEV;
13418 }
13419
13420 if (NULL == params)
13421 {
13422 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
13423 "%s: params is Null", __func__);
13424 return -EINVAL;
13425 }
13426
13427 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13428 status = wlan_hdd_validate_context(pHddCtx);
13429
13430 if (0 != status)
13431 {
13432 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13433 "%s: HDD context is not valid", __func__);
13434 return status;
13435 }
13436
13437 pVosContext = pHddCtx->pvosContext;
13438 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
13439
13440 if (NULL == pHostapdState)
13441 {
13442 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
13443 "%s: pHostapdState is Null", __func__);
13444 return -EINVAL;
13445 }
13446
13447 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"acl policy: = %d"
13448 "no acl entries = %d", params->acl_policy, params->n_acl_entries);
13449
13450 if (WLAN_HDD_SOFTAP == pAdapter->device_mode)
13451 {
13452 pConfig = &pAdapter->sessionCtx.ap.sapConfig;
13453
13454 /* default value */
13455 pConfig->num_accept_mac = 0;
13456 pConfig->num_deny_mac = 0;
13457
13458 /**
13459 * access control policy
13460 * @NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED: Deny stations which are
13461 * listed in hostapd.deny file.
13462 * @NL80211_ACL_POLICY_DENY_UNLESS_LISTED: Allow stations which are
13463 * listed in hostapd.accept file.
13464 */
13465 if (NL80211_ACL_POLICY_DENY_UNLESS_LISTED == params->acl_policy)
13466 {
13467 pConfig->SapMacaddr_acl = eSAP_DENY_UNLESS_ACCEPTED;
13468 }
13469 else if (NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED == params->acl_policy)
13470 {
13471 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
13472 }
13473 else
13474 {
13475 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13476 "%s:Acl Policy : %d is not supported",
13477 __func__, params->acl_policy);
13478 return -ENOTSUPP;
13479 }
13480
13481 if (eSAP_DENY_UNLESS_ACCEPTED == pConfig->SapMacaddr_acl)
13482 {
13483 pConfig->num_accept_mac = params->n_acl_entries;
13484 for (i = 0; i < params->n_acl_entries; i++)
13485 {
13486 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13487 "** Add ACL MAC entry %i in WhiletList :"
13488 MAC_ADDRESS_STR, i,
13489 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
13490
13491 vos_mem_copy(&pConfig->accept_mac[i], params->mac_addrs[i].addr,
13492 sizeof(qcmacaddr));
13493 }
13494 }
13495 else if (eSAP_ACCEPT_UNLESS_DENIED == pConfig->SapMacaddr_acl)
13496 {
13497 pConfig->num_deny_mac = params->n_acl_entries;
13498 for (i = 0; i < params->n_acl_entries; i++)
13499 {
13500 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13501 "** Add ACL MAC entry %i in BlackList :"
13502 MAC_ADDRESS_STR, i,
13503 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
13504
13505 vos_mem_copy(&pConfig->deny_mac[i], params->mac_addrs[i].addr,
13506 sizeof(qcmacaddr));
13507 }
13508 }
13509
13510 if (VOS_STATUS_SUCCESS != WLANSAP_SetMacACL(pVosContext, pConfig))
13511 {
13512 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13513 "%s: SAP Set Mac Acl fail", __func__);
13514 return -EINVAL;
13515 }
13516 }
13517 else
13518 {
13519 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053013520 "%s: Invalid device_mode = %s (%d)",
13521 __func__, hdd_device_modetoString(pAdapter->device_mode),
13522 pAdapter->device_mode);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053013523 return -EINVAL;
13524 }
13525
13526 return 0;
13527}
13528
Leo Chang9056f462013-08-01 19:21:11 -070013529#ifdef WLAN_NL80211_TESTMODE
13530#ifdef FEATURE_WLAN_LPHB
Leo Changd9df8aa2013-09-26 13:32:26 -070013531void wlan_hdd_cfg80211_lphb_ind_handler
Leo Chang9056f462013-08-01 19:21:11 -070013532(
13533 void *pAdapter,
13534 void *indCont
13535)
13536{
Leo Changd9df8aa2013-09-26 13:32:26 -070013537 tSirLPHBInd *lphbInd;
13538 struct sk_buff *skb;
c_hpothu73f35e62014-04-18 13:40:08 +053013539 hdd_context_t *pHddCtxt;
Leo Chang9056f462013-08-01 19:21:11 -070013540
13541 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -070013542 "LPHB indication arrived");
Leo Chang9056f462013-08-01 19:21:11 -070013543
c_hpothu73f35e62014-04-18 13:40:08 +053013544 if (pAdapter == NULL)
13545 {
13546 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13547 "%s: pAdapter is NULL\n",__func__);
13548 return;
13549 }
13550
Leo Chang9056f462013-08-01 19:21:11 -070013551 if (NULL == indCont)
13552 {
13553 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -070013554 "LPHB IND, invalid argument");
Leo Chang9056f462013-08-01 19:21:11 -070013555 return;
13556 }
13557
c_hpothu73f35e62014-04-18 13:40:08 +053013558 pHddCtxt = (hdd_context_t *)pAdapter;
Leo Changd9df8aa2013-09-26 13:32:26 -070013559 lphbInd = (tSirLPHBInd *)indCont;
Leo Chang9056f462013-08-01 19:21:11 -070013560 skb = cfg80211_testmode_alloc_event_skb(
c_hpothu73f35e62014-04-18 13:40:08 +053013561 pHddCtxt->wiphy,
Leo Changd9df8aa2013-09-26 13:32:26 -070013562 sizeof(tSirLPHBInd),
Leo Chang9056f462013-08-01 19:21:11 -070013563 GFP_ATOMIC);
13564 if (!skb)
13565 {
13566 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13567 "LPHB timeout, NL buffer alloc fail");
13568 return;
13569 }
13570
Leo Changac3ba772013-10-07 09:47:04 -070013571 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_CMD, WLAN_HDD_TM_CMD_WLAN_HB))
Leo Changd9df8aa2013-09-26 13:32:26 -070013572 {
13573 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13574 "WLAN_HDD_TM_ATTR_CMD put fail");
13575 goto nla_put_failure;
13576 }
Leo Changac3ba772013-10-07 09:47:04 -070013577 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_TYPE, lphbInd->protocolType))
Leo Changd9df8aa2013-09-26 13:32:26 -070013578 {
13579 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13580 "WLAN_HDD_TM_ATTR_TYPE put fail");
13581 goto nla_put_failure;
13582 }
Leo Changac3ba772013-10-07 09:47:04 -070013583 if(nla_put(skb, WLAN_HDD_TM_ATTR_DATA,
Leo Changd9df8aa2013-09-26 13:32:26 -070013584 sizeof(tSirLPHBInd), lphbInd))
13585 {
13586 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13587 "WLAN_HDD_TM_ATTR_DATA put fail");
13588 goto nla_put_failure;
13589 }
Leo Chang9056f462013-08-01 19:21:11 -070013590 cfg80211_testmode_event(skb, GFP_ATOMIC);
13591 return;
13592
13593nla_put_failure:
13594 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13595 "NLA Put fail");
13596 kfree_skb(skb);
13597
13598 return;
13599}
13600#endif /* FEATURE_WLAN_LPHB */
13601
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013602static int __wlan_hdd_cfg80211_testmode(struct wiphy *wiphy, void *data, int len)
Leo Chang9056f462013-08-01 19:21:11 -070013603{
13604 struct nlattr *tb[WLAN_HDD_TM_ATTR_MAX + 1];
13605 int err = 0;
13606#ifdef FEATURE_WLAN_LPHB
13607 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Leo Changd9df8aa2013-09-26 13:32:26 -070013608 eHalStatus smeStatus;
Leo Chang9056f462013-08-01 19:21:11 -070013609#endif /* FEATURE_WLAN_LPHB */
13610
13611 err = nla_parse(tb, WLAN_HDD_TM_ATTR_MAX, data, len, wlan_hdd_tm_policy);
13612 if (err)
13613 {
13614 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13615 "%s Testmode INV ATTR", __func__);
13616 return err;
13617 }
13618
13619 if (!tb[WLAN_HDD_TM_ATTR_CMD])
13620 {
13621 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13622 "%s Testmode INV CMD", __func__);
13623 return -EINVAL;
13624 }
13625
13626 switch (nla_get_u32(tb[WLAN_HDD_TM_ATTR_CMD]))
13627 {
13628#ifdef FEATURE_WLAN_LPHB
13629 /* Low Power Heartbeat configuration request */
13630 case WLAN_HDD_TM_CMD_WLAN_HB:
13631 {
13632 int buf_len;
13633 void *buf;
13634 tSirLPHBReq *hb_params = NULL;
Amar Singhal05852702014-02-04 14:40:00 -080013635 tSirLPHBReq *hb_params_temp = NULL;
Leo Chang9056f462013-08-01 19:21:11 -070013636
13637 if (!tb[WLAN_HDD_TM_ATTR_DATA])
13638 {
13639 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13640 "%s Testmode INV DATA", __func__);
13641 return -EINVAL;
13642 }
13643
13644 buf = nla_data(tb[WLAN_HDD_TM_ATTR_DATA]);
13645 buf_len = nla_len(tb[WLAN_HDD_TM_ATTR_DATA]);
Amar Singhal05852702014-02-04 14:40:00 -080013646
13647 hb_params_temp =(tSirLPHBReq *)buf;
13648 if ((hb_params_temp->cmd == LPHB_SET_TCP_PARAMS_INDID) &&
13649 (hb_params_temp->params.lphbTcpParamReq.timePeriodSec == 0))
13650 return -EINVAL;
13651
Leo Chang9056f462013-08-01 19:21:11 -070013652 hb_params = (tSirLPHBReq *)vos_mem_malloc(sizeof(tSirLPHBReq));
13653 if (NULL == hb_params)
13654 {
13655 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13656 "%s Request Buffer Alloc Fail", __func__);
13657 return -EINVAL;
13658 }
13659
13660 vos_mem_copy(hb_params, buf, buf_len);
Leo Changd9df8aa2013-09-26 13:32:26 -070013661 smeStatus = sme_LPHBConfigReq((tHalHandle)(pHddCtx->hHal),
13662 hb_params,
13663 wlan_hdd_cfg80211_lphb_ind_handler);
13664 if (eHAL_STATUS_SUCCESS != smeStatus)
Leo Chang9056f462013-08-01 19:21:11 -070013665 {
Leo Changd9df8aa2013-09-26 13:32:26 -070013666 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13667 "LPHB Config Fail, disable");
Leo Chang9056f462013-08-01 19:21:11 -070013668 vos_mem_free(hb_params);
13669 }
Leo Chang9056f462013-08-01 19:21:11 -070013670 return 0;
13671 }
13672#endif /* FEATURE_WLAN_LPHB */
13673 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +053013674 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13675 "%s: unsupported event",__func__);
Leo Chang9056f462013-08-01 19:21:11 -070013676 return -EOPNOTSUPP;
13677 }
13678
13679 return err;
13680}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013681
13682static int wlan_hdd_cfg80211_testmode(struct wiphy *wiphy, void *data, int len)
13683{
13684 int ret;
13685
13686 vos_ssr_protect(__func__);
13687 ret = __wlan_hdd_cfg80211_testmode(wiphy, data, len);
13688 vos_ssr_unprotect(__func__);
13689
13690 return ret;
13691}
Leo Chang9056f462013-08-01 19:21:11 -070013692#endif /* CONFIG_NL80211_TESTMODE */
13693
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013694static int __wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053013695 struct net_device *dev,
13696 int idx, struct survey_info *survey)
13697{
13698 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
13699 hdd_context_t *pHddCtx;
Mihir Sheted9072e02013-08-21 17:02:29 +053013700 hdd_station_ctx_t *pHddStaCtx;
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053013701 tHalHandle halHandle;
Mihir Sheted9072e02013-08-21 17:02:29 +053013702 v_U32_t channel = 0, freq = 0; /* Initialization Required */
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053013703 v_S7_t snr,rssi;
13704 int status, i, j, filled = 0;
13705
13706 ENTER();
13707
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053013708 if (NULL == pAdapter)
13709 {
13710 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
13711 "%s: HDD adapter is Null", __func__);
13712 return -ENODEV;
13713 }
13714
13715 if (NULL == wiphy)
13716 {
13717 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
13718 "%s: wiphy is Null", __func__);
13719 return -ENODEV;
13720 }
13721
13722 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13723 status = wlan_hdd_validate_context(pHddCtx);
13724
13725 if (0 != status)
13726 {
13727 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13728 "%s: HDD context is not valid", __func__);
13729 return status;
13730 }
13731
Mihir Sheted9072e02013-08-21 17:02:29 +053013732 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13733
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053013734 if (0 == pHddCtx->cfg_ini->fEnableSNRMonitoring ||
Mihir Sheted9072e02013-08-21 17:02:29 +053013735 0 != pAdapter->survey_idx ||
13736 eConnectionState_Associated != pHddStaCtx->conn_info.connState)
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053013737 {
13738 /* The survey dump ops when implemented completely is expected to
13739 * return a survey of all channels and the ops is called by the
13740 * kernel with incremental values of the argument 'idx' till it
13741 * returns -ENONET. But we can only support the survey for the
13742 * operating channel for now. survey_idx is used to track
13743 * that the ops is called only once and then return -ENONET for
13744 * the next iteration
13745 */
13746 pAdapter->survey_idx = 0;
13747 return -ENONET;
13748 }
13749
13750 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
13751
13752 wlan_hdd_get_snr(pAdapter, &snr);
13753 wlan_hdd_get_rssi(pAdapter, &rssi);
13754
13755 sme_GetOperationChannel(halHandle, &channel, pAdapter->sessionId);
13756 hdd_wlan_get_freq(channel, &freq);
13757
13758
13759 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
13760 {
13761 if (NULL == wiphy->bands[i])
13762 {
13763 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
13764 "%s: wiphy->bands[i] is NULL, i = %d", __func__, i);
13765 continue;
13766 }
13767
13768 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
13769 {
13770 struct ieee80211_supported_band *band = wiphy->bands[i];
13771
13772 if (band->channels[j].center_freq == (v_U16_t)freq)
13773 {
13774 survey->channel = &band->channels[j];
13775 /* The Rx BDs contain SNR values in dB for the received frames
13776 * while the supplicant expects noise. So we calculate and
13777 * return the value of noise (dBm)
13778 * SNR (dB) = RSSI (dBm) - NOISE (dBm)
13779 */
13780 survey->noise = rssi - snr;
13781 survey->filled = SURVEY_INFO_NOISE_DBM;
13782 filled = 1;
13783 }
13784 }
13785 }
13786
13787 if (filled)
13788 pAdapter->survey_idx = 1;
13789 else
13790 {
13791 pAdapter->survey_idx = 0;
13792 return -ENONET;
13793 }
13794
13795 return 0;
13796}
13797
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013798static int wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
13799 struct net_device *dev,
13800 int idx, struct survey_info *survey)
13801{
13802 int ret;
13803
13804 vos_ssr_protect(__func__);
13805 ret = __wlan_hdd_cfg80211_dump_survey(wiphy, dev, idx, survey);
13806 vos_ssr_unprotect(__func__);
13807
13808 return ret;
13809}
13810
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013811/*
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053013812 * FUNCTION: __wlan_hdd_cfg80211_resume_wlan
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013813 * this is called when cfg80211 driver resume
13814 * driver updates latest sched_scan scan result(if any) to cfg80211 database
13815 */
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053013816int __wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013817{
13818 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
13819 hdd_adapter_t *pAdapter;
13820 hdd_adapter_list_node_t *pAdapterNode, *pNext;
13821 VOS_STATUS status = VOS_STATUS_SUCCESS;
13822
13823 ENTER();
13824
13825 if ( NULL == pHddCtx )
13826 {
13827 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
13828 "%s: HddCtx validation failed", __func__);
13829 return 0;
13830 }
13831
13832 if (pHddCtx->isLogpInProgress)
13833 {
13834 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13835 "%s: LOGP in Progress. Ignore!!!", __func__);
13836 return 0;
13837 }
13838
Mihir Shete18156292014-03-11 15:38:30 +053013839 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013840 {
13841 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13842 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
13843 return 0;
13844 }
13845
13846 spin_lock(&pHddCtx->schedScan_lock);
13847 pHddCtx->isWiphySuspended = FALSE;
13848 if (TRUE != pHddCtx->isSchedScanUpdatePending)
13849 {
13850 spin_unlock(&pHddCtx->schedScan_lock);
13851 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13852 "%s: Return resume is not due to PNO indication", __func__);
13853 return 0;
13854 }
13855 // Reset flag to avoid updatating cfg80211 data old results again
13856 pHddCtx->isSchedScanUpdatePending = FALSE;
13857 spin_unlock(&pHddCtx->schedScan_lock);
13858
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053013859
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013860 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
13861
13862 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
13863 {
13864 pAdapter = pAdapterNode->pAdapter;
13865 if ( (NULL != pAdapter) &&
13866 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) )
13867 {
13868 if (0 != wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter))
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053013869 {
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013870 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
13871 "%s: NO SCAN result", __func__);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053013872 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013873 else
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053013874 {
13875 /* Acquire wakelock to handle the case where APP's tries to
13876 * suspend immediately after updating the scan results. Whis
13877 * results in app's is in suspended state and not able to
13878 * process the connect request to AP
13879 */
13880 hdd_prevent_suspend_timeout(2000);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013881 cfg80211_sched_scan_results(pHddCtx->wiphy);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053013882 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013883
13884 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13885 "%s : cfg80211 scan result database updated", __func__);
13886
13887 return 0;
13888
13889 }
13890 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
13891 pAdapterNode = pNext;
13892 }
13893
13894 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13895 "%s: Failed to find Adapter", __func__);
13896 return 0;
13897}
13898
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053013899int wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
13900{
13901 int ret;
13902
13903 vos_ssr_protect(__func__);
13904 ret = __wlan_hdd_cfg80211_resume_wlan(wiphy);
13905 vos_ssr_unprotect(__func__);
13906
13907 return ret;
13908}
13909
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013910/*
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053013911 * FUNCTION: __wlan_hdd_cfg80211_suspend_wlan
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013912 * this is called when cfg80211 driver suspends
13913 */
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053013914int __wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053013915 struct cfg80211_wowlan *wow)
13916{
13917 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
13918
13919 ENTER();
13920 if (NULL == pHddCtx)
13921 {
13922 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
13923 "%s: HddCtx validation failed", __func__);
13924 return 0;
13925 }
13926
13927 pHddCtx->isWiphySuspended = TRUE;
13928
13929 EXIT();
13930
13931 return 0;
13932}
13933
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053013934int wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
13935 struct cfg80211_wowlan *wow)
13936{
13937 int ret;
13938
13939 vos_ssr_protect(__func__);
13940 ret = __wlan_hdd_cfg80211_suspend_wlan(wiphy, wow);
13941 vos_ssr_unprotect(__func__);
13942
13943 return ret;
13944}
Jeff Johnson295189b2012-06-20 16:38:30 -070013945/* cfg80211_ops */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013946static struct cfg80211_ops wlan_hdd_cfg80211_ops =
Jeff Johnson295189b2012-06-20 16:38:30 -070013947{
13948 .add_virtual_intf = wlan_hdd_add_virtual_intf,
13949 .del_virtual_intf = wlan_hdd_del_virtual_intf,
13950 .change_virtual_intf = wlan_hdd_cfg80211_change_iface,
13951 .change_station = wlan_hdd_change_station,
13952#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
13953 .add_beacon = wlan_hdd_cfg80211_add_beacon,
13954 .del_beacon = wlan_hdd_cfg80211_del_beacon,
13955 .set_beacon = wlan_hdd_cfg80211_set_beacon,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013956#else
13957 .start_ap = wlan_hdd_cfg80211_start_ap,
13958 .change_beacon = wlan_hdd_cfg80211_change_beacon,
13959 .stop_ap = wlan_hdd_cfg80211_stop_ap,
Jeff Johnson295189b2012-06-20 16:38:30 -070013960#endif
13961 .change_bss = wlan_hdd_cfg80211_change_bss,
13962 .add_key = wlan_hdd_cfg80211_add_key,
13963 .get_key = wlan_hdd_cfg80211_get_key,
13964 .del_key = wlan_hdd_cfg80211_del_key,
13965 .set_default_key = wlan_hdd_cfg80211_set_default_key,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080013966#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
Jeff Johnson295189b2012-06-20 16:38:30 -070013967 .set_channel = wlan_hdd_cfg80211_set_channel,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080013968#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013969 .scan = wlan_hdd_cfg80211_scan,
13970 .connect = wlan_hdd_cfg80211_connect,
13971 .disconnect = wlan_hdd_cfg80211_disconnect,
13972 .join_ibss = wlan_hdd_cfg80211_join_ibss,
13973 .leave_ibss = wlan_hdd_cfg80211_leave_ibss,
13974 .set_wiphy_params = wlan_hdd_cfg80211_set_wiphy_params,
13975 .set_tx_power = wlan_hdd_cfg80211_set_txpower,
13976 .get_tx_power = wlan_hdd_cfg80211_get_txpower,
Jeff Johnson295189b2012-06-20 16:38:30 -070013977 .remain_on_channel = wlan_hdd_cfg80211_remain_on_channel,
13978 .cancel_remain_on_channel = wlan_hdd_cfg80211_cancel_remain_on_channel,
DARAM SUDHA39eede62014-02-12 11:16:40 +053013979 .mgmt_tx = wlan_hdd_mgmt_tx,
Jeff Johnson295189b2012-06-20 16:38:30 -070013980#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13981 .mgmt_tx_cancel_wait = wlan_hdd_cfg80211_mgmt_tx_cancel_wait,
13982 .set_default_mgmt_key = wlan_hdd_set_default_mgmt_key,
13983 .set_txq_params = wlan_hdd_set_txq_params,
13984#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013985 .get_station = wlan_hdd_cfg80211_get_station,
13986 .set_power_mgmt = wlan_hdd_cfg80211_set_power_mgmt,
13987 .del_station = wlan_hdd_cfg80211_del_station,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013988 .add_station = wlan_hdd_cfg80211_add_station,
13989#ifdef FEATURE_WLAN_LFR
13990 .set_pmksa = wlan_hdd_cfg80211_set_pmksa,
13991 .del_pmksa = wlan_hdd_cfg80211_del_pmksa,
13992 .flush_pmksa = wlan_hdd_cfg80211_flush_pmksa,
13993#endif
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013994#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
13995 .update_ft_ies = wlan_hdd_cfg80211_update_ft_ies,
13996#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080013997#ifdef FEATURE_WLAN_TDLS
13998 .tdls_mgmt = wlan_hdd_cfg80211_tdls_mgmt,
13999 .tdls_oper = wlan_hdd_cfg80211_tdls_oper,
14000#endif
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053014001#ifdef WLAN_FEATURE_GTK_OFFLOAD
14002 .set_rekey_data = wlan_hdd_cfg80211_set_rekey_data,
14003#endif /* WLAN_FEATURE_GTK_OFFLOAD */
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014004#ifdef FEATURE_WLAN_SCAN_PNO
14005 .sched_scan_start = wlan_hdd_cfg80211_sched_scan_start,
14006 .sched_scan_stop = wlan_hdd_cfg80211_sched_scan_stop,
14007#endif /*FEATURE_WLAN_SCAN_PNO */
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014008 .resume = wlan_hdd_cfg80211_resume_wlan,
14009 .suspend = wlan_hdd_cfg80211_suspend_wlan,
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053014010 .set_mac_acl = wlan_hdd_cfg80211_set_mac_acl,
Leo Chang9056f462013-08-01 19:21:11 -070014011#ifdef WLAN_NL80211_TESTMODE
14012 .testmode_cmd = wlan_hdd_cfg80211_testmode,
14013#endif
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053014014 .dump_survey = wlan_hdd_cfg80211_dump_survey,
Jeff Johnson295189b2012-06-20 16:38:30 -070014015};
14016