blob: a2d4c497b2a0374a74f8fe0ed5540ebf1e2077c9 [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
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530146static const u32 hdd_cipher_suites[] =
Jeff Johnson295189b2012-06-20 16:38:30 -0700147{
148 WLAN_CIPHER_SUITE_WEP40,
149 WLAN_CIPHER_SUITE_WEP104,
150 WLAN_CIPHER_SUITE_TKIP,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800151#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -0700152#define WLAN_CIPHER_SUITE_KRK 0x004096ff /* use for KRK */
153 WLAN_CIPHER_SUITE_KRK,
154 WLAN_CIPHER_SUITE_CCMP,
155#else
156 WLAN_CIPHER_SUITE_CCMP,
157#endif
158#ifdef FEATURE_WLAN_WAPI
159 WLAN_CIPHER_SUITE_SMS4,
160#endif
Chet Lanctot186b5732013-03-18 10:26:30 -0700161#ifdef WLAN_FEATURE_11W
162 WLAN_CIPHER_SUITE_AES_CMAC,
163#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700164};
165
166static inline int is_broadcast_ether_addr(const u8 *addr)
167{
168 return ((addr[0] == 0xff) && (addr[1] == 0xff) && (addr[2] == 0xff) &&
169 (addr[3] == 0xff) && (addr[4] == 0xff) && (addr[5] == 0xff));
170}
171
172static struct ieee80211_channel hdd_channels_2_4_GHZ[] =
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530173{
Jeff Johnson295189b2012-06-20 16:38:30 -0700174 HDD2GHZCHAN(2412, 1, 0) ,
175 HDD2GHZCHAN(2417, 2, 0) ,
176 HDD2GHZCHAN(2422, 3, 0) ,
177 HDD2GHZCHAN(2427, 4, 0) ,
178 HDD2GHZCHAN(2432, 5, 0) ,
179 HDD2GHZCHAN(2437, 6, 0) ,
180 HDD2GHZCHAN(2442, 7, 0) ,
181 HDD2GHZCHAN(2447, 8, 0) ,
182 HDD2GHZCHAN(2452, 9, 0) ,
183 HDD2GHZCHAN(2457, 10, 0) ,
184 HDD2GHZCHAN(2462, 11, 0) ,
185 HDD2GHZCHAN(2467, 12, 0) ,
186 HDD2GHZCHAN(2472, 13, 0) ,
187 HDD2GHZCHAN(2484, 14, 0) ,
188};
189
Jeff Johnson295189b2012-06-20 16:38:30 -0700190static struct ieee80211_channel hdd_social_channels_2_4_GHZ[] =
191{
192 HDD2GHZCHAN(2412, 1, 0) ,
193 HDD2GHZCHAN(2437, 6, 0) ,
194 HDD2GHZCHAN(2462, 11, 0) ,
195};
Jeff Johnson295189b2012-06-20 16:38:30 -0700196
197static struct ieee80211_channel hdd_channels_5_GHZ[] =
198{
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -0700199 HDD5GHZCHAN(4920, 240, 0) ,
200 HDD5GHZCHAN(4940, 244, 0) ,
201 HDD5GHZCHAN(4960, 248, 0) ,
202 HDD5GHZCHAN(4980, 252, 0) ,
203 HDD5GHZCHAN(5040, 208, 0) ,
204 HDD5GHZCHAN(5060, 212, 0) ,
205 HDD5GHZCHAN(5080, 216, 0) ,
Jeff Johnson295189b2012-06-20 16:38:30 -0700206 HDD5GHZCHAN(5180, 36, 0) ,
207 HDD5GHZCHAN(5200, 40, 0) ,
208 HDD5GHZCHAN(5220, 44, 0) ,
209 HDD5GHZCHAN(5240, 48, 0) ,
210 HDD5GHZCHAN(5260, 52, 0) ,
211 HDD5GHZCHAN(5280, 56, 0) ,
212 HDD5GHZCHAN(5300, 60, 0) ,
213 HDD5GHZCHAN(5320, 64, 0) ,
214 HDD5GHZCHAN(5500,100, 0) ,
215 HDD5GHZCHAN(5520,104, 0) ,
216 HDD5GHZCHAN(5540,108, 0) ,
217 HDD5GHZCHAN(5560,112, 0) ,
218 HDD5GHZCHAN(5580,116, 0) ,
219 HDD5GHZCHAN(5600,120, 0) ,
220 HDD5GHZCHAN(5620,124, 0) ,
221 HDD5GHZCHAN(5640,128, 0) ,
222 HDD5GHZCHAN(5660,132, 0) ,
223 HDD5GHZCHAN(5680,136, 0) ,
224 HDD5GHZCHAN(5700,140, 0) ,
Leo Chang80de3c22013-11-26 10:52:12 -0800225#ifdef FEATURE_WLAN_CH144
226 HDD5GHZCHAN(5720,144, 0) ,
227#endif /* FEATURE_WLAN_CH144 */
Jeff Johnson295189b2012-06-20 16:38:30 -0700228 HDD5GHZCHAN(5745,149, 0) ,
229 HDD5GHZCHAN(5765,153, 0) ,
230 HDD5GHZCHAN(5785,157, 0) ,
231 HDD5GHZCHAN(5805,161, 0) ,
232 HDD5GHZCHAN(5825,165, 0) ,
233};
234
235static struct ieee80211_rate g_mode_rates[] =
236{
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530237 HDD_G_MODE_RATETAB(10, 0x1, 0),
238 HDD_G_MODE_RATETAB(20, 0x2, 0),
239 HDD_G_MODE_RATETAB(55, 0x4, 0),
240 HDD_G_MODE_RATETAB(110, 0x8, 0),
241 HDD_G_MODE_RATETAB(60, 0x10, 0),
242 HDD_G_MODE_RATETAB(90, 0x20, 0),
243 HDD_G_MODE_RATETAB(120, 0x40, 0),
244 HDD_G_MODE_RATETAB(180, 0x80, 0),
245 HDD_G_MODE_RATETAB(240, 0x100, 0),
246 HDD_G_MODE_RATETAB(360, 0x200, 0),
247 HDD_G_MODE_RATETAB(480, 0x400, 0),
Jeff Johnson295189b2012-06-20 16:38:30 -0700248 HDD_G_MODE_RATETAB(540, 0x800, 0),
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530249};
Jeff Johnson295189b2012-06-20 16:38:30 -0700250
251static struct ieee80211_rate a_mode_rates[] =
252{
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530253 HDD_G_MODE_RATETAB(60, 0x10, 0),
254 HDD_G_MODE_RATETAB(90, 0x20, 0),
255 HDD_G_MODE_RATETAB(120, 0x40, 0),
256 HDD_G_MODE_RATETAB(180, 0x80, 0),
257 HDD_G_MODE_RATETAB(240, 0x100, 0),
258 HDD_G_MODE_RATETAB(360, 0x200, 0),
259 HDD_G_MODE_RATETAB(480, 0x400, 0),
Jeff Johnson295189b2012-06-20 16:38:30 -0700260 HDD_G_MODE_RATETAB(540, 0x800, 0),
261};
262
263static struct ieee80211_supported_band wlan_hdd_band_2_4_GHZ =
264{
265 .channels = hdd_channels_2_4_GHZ,
266 .n_channels = ARRAY_SIZE(hdd_channels_2_4_GHZ),
267 .band = IEEE80211_BAND_2GHZ,
268 .bitrates = g_mode_rates,
269 .n_bitrates = g_mode_rates_size,
270 .ht_cap.ht_supported = 1,
271 .ht_cap.cap = IEEE80211_HT_CAP_SGI_20
272 | IEEE80211_HT_CAP_GRN_FLD
273 | IEEE80211_HT_CAP_DSSSCCK40
274 | IEEE80211_HT_CAP_LSIG_TXOP_PROT,
275 .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
276 .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
277 .ht_cap.mcs.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
278 .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ),
279 .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
280};
281
Jeff Johnson295189b2012-06-20 16:38:30 -0700282static struct ieee80211_supported_band wlan_hdd_band_p2p_2_4_GHZ =
283{
284 .channels = hdd_social_channels_2_4_GHZ,
285 .n_channels = ARRAY_SIZE(hdd_social_channels_2_4_GHZ),
286 .band = IEEE80211_BAND_2GHZ,
287 .bitrates = g_mode_rates,
288 .n_bitrates = g_mode_rates_size,
289 .ht_cap.ht_supported = 1,
290 .ht_cap.cap = IEEE80211_HT_CAP_SGI_20
291 | IEEE80211_HT_CAP_GRN_FLD
292 | IEEE80211_HT_CAP_DSSSCCK40
293 | IEEE80211_HT_CAP_LSIG_TXOP_PROT,
294 .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
295 .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
296 .ht_cap.mcs.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
297 .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ),
298 .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
299};
Jeff Johnson295189b2012-06-20 16:38:30 -0700300
301static struct ieee80211_supported_band wlan_hdd_band_5_GHZ =
302{
303 .channels = hdd_channels_5_GHZ,
304 .n_channels = ARRAY_SIZE(hdd_channels_5_GHZ),
305 .band = IEEE80211_BAND_5GHZ,
306 .bitrates = a_mode_rates,
307 .n_bitrates = a_mode_rates_size,
308 .ht_cap.ht_supported = 1,
309 .ht_cap.cap = IEEE80211_HT_CAP_SGI_20
310 | IEEE80211_HT_CAP_GRN_FLD
311 | IEEE80211_HT_CAP_DSSSCCK40
312 | IEEE80211_HT_CAP_LSIG_TXOP_PROT
313 | IEEE80211_HT_CAP_SGI_40
314 | IEEE80211_HT_CAP_SUP_WIDTH_20_40,
315 .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
316 .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
317 .ht_cap.mcs.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
318 .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ),
319 .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
320};
321
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530322/* This structure contain information what kind of frame are expected in
Jeff Johnson295189b2012-06-20 16:38:30 -0700323 TX/RX direction for each kind of interface */
324static const struct ieee80211_txrx_stypes
325wlan_hdd_txrx_stypes[NUM_NL80211_IFTYPES] = {
326 [NL80211_IFTYPE_STATION] = {
327 .tx = 0xffff,
328 .rx = BIT(SIR_MAC_MGMT_ACTION) |
329 BIT(SIR_MAC_MGMT_PROBE_REQ),
330 },
331 [NL80211_IFTYPE_AP] = {
332 .tx = 0xffff,
333 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
334 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
335 BIT(SIR_MAC_MGMT_PROBE_REQ) |
336 BIT(SIR_MAC_MGMT_DISASSOC) |
337 BIT(SIR_MAC_MGMT_AUTH) |
338 BIT(SIR_MAC_MGMT_DEAUTH) |
339 BIT(SIR_MAC_MGMT_ACTION),
340 },
Jeff Johnsonbc006202013-04-29 14:05:30 -0700341 [NL80211_IFTYPE_ADHOC] = {
342 .tx = 0xffff,
343 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
344 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
345 BIT(SIR_MAC_MGMT_PROBE_REQ) |
346 BIT(SIR_MAC_MGMT_DISASSOC) |
347 BIT(SIR_MAC_MGMT_AUTH) |
348 BIT(SIR_MAC_MGMT_DEAUTH) |
349 BIT(SIR_MAC_MGMT_ACTION),
350 },
Jeff Johnson295189b2012-06-20 16:38:30 -0700351 [NL80211_IFTYPE_P2P_CLIENT] = {
352 .tx = 0xffff,
353 .rx = BIT(SIR_MAC_MGMT_ACTION) |
354 BIT(SIR_MAC_MGMT_PROBE_REQ),
355 },
356 [NL80211_IFTYPE_P2P_GO] = {
357 /* This is also same as for SoftAP */
358 .tx = 0xffff,
359 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
360 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
361 BIT(SIR_MAC_MGMT_PROBE_REQ) |
362 BIT(SIR_MAC_MGMT_DISASSOC) |
363 BIT(SIR_MAC_MGMT_AUTH) |
364 BIT(SIR_MAC_MGMT_DEAUTH) |
365 BIT(SIR_MAC_MGMT_ACTION),
366 },
Jeff Johnson295189b2012-06-20 16:38:30 -0700367};
368
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800369#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800370static const struct ieee80211_iface_limit
371wlan_hdd_iface_limit[] = {
372 {
Sunil Ravia72c3992013-01-31 06:12:22 -0800373 /* max = 3 ; Our driver create two interfaces during driver init
374 * wlan0 and p2p0 interfaces. p2p0 is considered as station
375 * interface until a group is formed. In JB architecture, once the
376 * group is formed, interface type of p2p0 is changed to P2P GO or
377 * Client.
378 * When supplicant remove the group, it first issue a set interface
379 * cmd to change the mode back to Station. In JB this works fine as
380 * we advertize two station type interface during driver init.
381 * Some vendors create separate interface for P2P GO/Client,
382 * after group formation(Third one). But while group remove
383 * supplicant first tries to change the mode(3rd interface) to STATION
384 * But as we advertized only two sta type interfaces nl80211 was
385 * returning error for the third one which was leading to failure in
386 * delete interface. Ideally while removing the group, supplicant
387 * should not try to change the 3rd interface mode to Station type.
388 * Till we get a fix in wpa_supplicant, we advertize max STA
389 * interface type to 3
390 */
391 .max = 3,
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800392 .types = BIT(NL80211_IFTYPE_STATION),
393 },
394 {
395 .max = 1,
Jeff Johnsonbc006202013-04-29 14:05:30 -0700396 .types = BIT(NL80211_IFTYPE_ADHOC) | BIT(NL80211_IFTYPE_AP),
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800397 },
398 {
399 .max = 1,
400 .types = BIT(NL80211_IFTYPE_P2P_GO) |
401 BIT(NL80211_IFTYPE_P2P_CLIENT),
402 },
403};
404
405/* By default, only single channel concurrency is allowed */
406static struct ieee80211_iface_combination
407wlan_hdd_iface_combination = {
408 .limits = wlan_hdd_iface_limit,
409 .num_different_channels = 1,
Sunil Ravia72c3992013-01-31 06:12:22 -0800410 /*
411 * max = WLAN_MAX_INTERFACES ; JellyBean architecture creates wlan0
412 * and p2p0 interfaces during driver init
413 * Some vendors create separate interface for P2P operations.
414 * wlan0: STA interface
415 * p2p0: P2P Device interface, action frames goes
416 * through this interface.
417 * p2p-xx: P2P interface, After GO negotiation this interface is
418 * created for p2p operations(GO/CLIENT interface).
419 */
420 .max_interfaces = WLAN_MAX_INTERFACES,
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800421 .n_limits = ARRAY_SIZE(wlan_hdd_iface_limit),
422 .beacon_int_infra_match = false,
423};
424#endif
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800425
Jeff Johnson295189b2012-06-20 16:38:30 -0700426static struct cfg80211_ops wlan_hdd_cfg80211_ops;
427
428/* Data rate 100KBPS based on IE Index */
429struct index_data_rate_type
430{
431 v_U8_t beacon_rate_index;
432 v_U16_t supported_rate[4];
433};
434
435/* 11B, 11G Rate table include Basic rate and Extended rate
436 The IDX field is the rate index
437 The HI field is the rate when RSSI is strong or being ignored
438 (in this case we report actual rate)
439 The MID field is the rate when RSSI is moderate
440 (in this case we cap 11b rates at 5.5 and 11g rates at 24)
441 The LO field is the rate when RSSI is low
442 (in this case we don't report rates, actual current rate used)
443 */
444static const struct
445{
446 v_U8_t beacon_rate_index;
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -0700447 v_U16_t supported_rate[4];
Jeff Johnson295189b2012-06-20 16:38:30 -0700448} supported_data_rate[] =
449{
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -0700450/* IDX HI HM LM LO (RSSI-based index */
451 {2, { 10, 10, 10, 0}},
452 {4, { 20, 20, 10, 0}},
453 {11, { 55, 20, 10, 0}},
454 {12, { 60, 55, 20, 0}},
455 {18, { 90, 55, 20, 0}},
456 {22, {110, 55, 20, 0}},
457 {24, {120, 90, 60, 0}},
458 {36, {180, 120, 60, 0}},
459 {44, {220, 180, 60, 0}},
460 {48, {240, 180, 90, 0}},
461 {66, {330, 180, 90, 0}},
462 {72, {360, 240, 90, 0}},
463 {96, {480, 240, 120, 0}},
464 {108, {540, 240, 120, 0}}
Jeff Johnson295189b2012-06-20 16:38:30 -0700465};
466
467/* MCS Based rate table */
468static struct index_data_rate_type supported_mcs_rate[] =
469{
470/* MCS L20 L40 S20 S40 */
471 {0, {65, 135, 72, 150}},
472 {1, {130, 270, 144, 300}},
473 {2, {195, 405, 217, 450}},
474 {3, {260, 540, 289, 600}},
475 {4, {390, 810, 433, 900}},
476 {5, {520, 1080, 578, 1200}},
477 {6, {585, 1215, 650, 1350}},
478 {7, {650, 1350, 722, 1500}}
479};
480
Leo Chang6f8870f2013-03-26 18:11:36 -0700481#ifdef WLAN_FEATURE_11AC
482
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530483#define DATA_RATE_11AC_MCS_MASK 0x03
Leo Chang6f8870f2013-03-26 18:11:36 -0700484
485struct index_vht_data_rate_type
486{
487 v_U8_t beacon_rate_index;
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530488 v_U16_t supported_VHT80_rate[2];
489 v_U16_t supported_VHT40_rate[2];
490 v_U16_t supported_VHT20_rate[2];
Leo Chang6f8870f2013-03-26 18:11:36 -0700491};
492
493typedef enum
494{
495 DATA_RATE_11AC_MAX_MCS_7,
496 DATA_RATE_11AC_MAX_MCS_8,
497 DATA_RATE_11AC_MAX_MCS_9,
498 DATA_RATE_11AC_MAX_MCS_NA
499} eDataRate11ACMaxMcs;
500
501/* MCS Based VHT rate table */
502static struct index_vht_data_rate_type supported_vht_mcs_rate[] =
503{
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530504/* MCS L80 S80 L40 S40 L20 S40*/
505 {0, {293, 325}, {135, 150}, {65, 72}},
506 {1, {585, 650}, {270, 300}, {130, 144}},
507 {2, {878, 975}, {405, 450}, {195, 217}},
508 {3, {1170, 1300}, {540, 600}, {260, 289}},
509 {4, {1755, 1950}, {810, 900}, {390, 433}},
510 {5, {2340, 2600}, {1080, 1200}, {520, 578}},
511 {6, {2633, 2925}, {1215, 1350}, {585, 650}},
512 {7, {2925, 3250}, {1350, 1500}, {650, 722}},
513 {8, {3510, 3900}, {1620, 1800}, {780, 867}},
514 {9, {3900, 4333}, {1800, 2000}, {780, 867}}
Leo Chang6f8870f2013-03-26 18:11:36 -0700515};
516#endif /* WLAN_FEATURE_11AC */
517
Jeff Johnson295189b2012-06-20 16:38:30 -0700518extern struct net_device_ops net_ops_struct;
519
Leo Chang9056f462013-08-01 19:21:11 -0700520#ifdef WLAN_NL80211_TESTMODE
521enum wlan_hdd_tm_attr
522{
523 WLAN_HDD_TM_ATTR_INVALID = 0,
524 WLAN_HDD_TM_ATTR_CMD = 1,
525 WLAN_HDD_TM_ATTR_DATA = 2,
526 WLAN_HDD_TM_ATTR_TYPE = 3,
527 /* keep last */
528 WLAN_HDD_TM_ATTR_AFTER_LAST,
529 WLAN_HDD_TM_ATTR_MAX = WLAN_HDD_TM_ATTR_AFTER_LAST - 1,
530};
531
532enum wlan_hdd_tm_cmd
533{
534 WLAN_HDD_TM_CMD_WLAN_HB = 1,
535};
536
537#define WLAN_HDD_TM_DATA_MAX_LEN 5000
538
539static const struct nla_policy wlan_hdd_tm_policy[WLAN_HDD_TM_ATTR_MAX + 1] =
540{
541 [WLAN_HDD_TM_ATTR_CMD] = { .type = NLA_U32 },
542 [WLAN_HDD_TM_ATTR_DATA] = { .type = NLA_BINARY,
543 .len = WLAN_HDD_TM_DATA_MAX_LEN },
544};
545#endif /* WLAN_NL80211_TESTMODE */
546
Rajesh Chauhan98a31f82014-01-06 20:15:25 -0800547#ifdef FEATURE_WLAN_CH_AVOID
548/*
549 * FUNCTION: wlan_hdd_send_avoid_freq_event
550 * This is called when wlan driver needs to send vendor specific
551 * avoid frequency range event to userspace
552 */
553int wlan_hdd_send_avoid_freq_event(hdd_context_t *pHddCtx,
554 tHddAvoidFreqList *pAvoidFreqList)
555{
556 struct sk_buff *vendor_event;
557
558 ENTER();
559
560 if (!pHddCtx)
561 {
562 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
563 "%s: HDD context is null", __func__);
564 return -1;
565 }
566
567 if (!pAvoidFreqList)
568 {
569 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
570 "%s: pAvoidFreqList is null", __func__);
571 return -1;
572 }
573
574 vendor_event = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
575 sizeof(tHddAvoidFreqList),
576 QCOM_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY_INDEX,
577 GFP_KERNEL);
578 if (!vendor_event)
579 {
580 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
581 "%s: cfg80211_vendor_event_alloc failed", __func__);
582 return -1;
583 }
584
585 memcpy(skb_put(vendor_event, sizeof(tHddAvoidFreqList)),
586 (void *)pAvoidFreqList, sizeof(tHddAvoidFreqList));
587
588 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
589
590 EXIT();
591 return 0;
592}
593#endif /* FEATURE_WLAN_CH_AVOID */
594
595/* vendor specific events */
596static const struct nl80211_vendor_cmd_info wlan_hdd_cfg80211_vendor_events[] =
597{
598#ifdef FEATURE_WLAN_CH_AVOID
599 {
600 .vendor_id = QCOM_NL80211_VENDOR_ID,
601 .subcmd = QCOM_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY
602 },
603#endif /* FEATURE_WLAN_CH_AVOID */
604};
605
Jeff Johnson295189b2012-06-20 16:38:30 -0700606/*
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +0530607 * FUNCTION: wlan_hdd_cfg80211_wiphy_alloc
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530608 * This function is called by hdd_wlan_startup()
609 * during initialization.
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +0530610 * This function is used to allocate wiphy structure.
Jeff Johnson295189b2012-06-20 16:38:30 -0700611 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +0530612struct wiphy *wlan_hdd_cfg80211_wiphy_alloc(int priv_size)
Jeff Johnson295189b2012-06-20 16:38:30 -0700613{
614 struct wiphy *wiphy;
615 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530616 /*
617 * Create wiphy device
Jeff Johnson295189b2012-06-20 16:38:30 -0700618 */
619 wiphy = wiphy_new(&wlan_hdd_cfg80211_ops, priv_size);
620
621 if (!wiphy)
622 {
623 /* Print error and jump into err label and free the memory */
624 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wiphy init failed", __func__);
625 return NULL;
626 }
627
628 return wiphy;
629}
630
631/*
632 * FUNCTION: wlan_hdd_cfg80211_update_band
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530633 * This function is called from the supplicant through a
Jeff Johnson295189b2012-06-20 16:38:30 -0700634 * private ioctl to change the band value
635 */
636int wlan_hdd_cfg80211_update_band(struct wiphy *wiphy, eCsrBand eBand)
637{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +0530638 int i, j;
639 eNVChannelEnabledType channelEnabledState;
640
Jeff Johnsone7245742012-09-05 17:12:55 -0700641 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +0530642
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +0530643 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
Jeff Johnson295189b2012-06-20 16:38:30 -0700644 {
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +0530645
646 if (NULL == wiphy->bands[i])
647 {
648 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[i] is NULL, i = %d",
649 __func__, i);
650 continue;
651 }
652
653 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
654 {
655 struct ieee80211_supported_band *band = wiphy->bands[i];
656
657 channelEnabledState = vos_nv_getChannelEnabledState(
658 band->channels[j].hw_value);
659
660 if (IEEE80211_BAND_2GHZ == i && eCSR_BAND_5G == eBand) // 5G only
661 {
662 // Enable Social channels for P2P
663 if (WLAN_HDD_IS_SOCIAL_CHANNEL(band->channels[j].center_freq) &&
664 NV_CHANNEL_ENABLE == channelEnabledState)
665 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
666 else
667 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
668 continue;
669 }
670 else if (IEEE80211_BAND_5GHZ == i && eCSR_BAND_24 == eBand) // 2G only
671 {
672 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
673 continue;
674 }
675
676 if (NV_CHANNEL_DISABLE == channelEnabledState ||
677 NV_CHANNEL_INVALID == channelEnabledState)
678 {
679 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
680 }
681 else if (NV_CHANNEL_DFS == channelEnabledState)
682 {
683 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
684 band->channels[j].flags |= IEEE80211_CHAN_RADAR;
685 }
686 else
687 {
688 band->channels[j].flags &= ~(IEEE80211_CHAN_DISABLED
689 |IEEE80211_CHAN_RADAR);
690 }
691 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700692 }
693 return 0;
694}
695/*
696 * FUNCTION: wlan_hdd_cfg80211_init
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530697 * This function is called by hdd_wlan_startup()
698 * during initialization.
Jeff Johnson295189b2012-06-20 16:38:30 -0700699 * This function is used to initialize and register wiphy structure.
700 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +0530701int wlan_hdd_cfg80211_init(struct device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -0700702 struct wiphy *wiphy,
703 hdd_config_t *pCfg
704 )
705{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +0530706 int i, j;
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +0530707 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
708
Jeff Johnsone7245742012-09-05 17:12:55 -0700709 ENTER();
710
Jeff Johnson295189b2012-06-20 16:38:30 -0700711 /* Now bind the underlying wlan device with wiphy */
712 set_wiphy_dev(wiphy, dev);
713
714 wiphy->mgmt_stypes = wlan_hdd_txrx_stypes;
Amar Singhalfddc28c2013-09-05 13:03:40 -0700715
Kiet Lam6c583332013-10-14 05:37:09 +0530716#ifndef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -0700717 /* the flag for the other case would be initialzed in
718 vos_init_wiphy_from_nv_bin */
Amar Singhal0a402232013-10-11 20:57:16 -0700719 wiphy->flags |= WIPHY_FLAG_STRICT_REGULATORY;
Kiet Lam6c583332013-10-14 05:37:09 +0530720#endif
Amar Singhala49cbc52013-10-08 18:37:44 -0700721
Amar Singhalfddc28c2013-09-05 13:03:40 -0700722 /* This will disable updating of NL channels from passive to
723 * active if a beacon is received on passive channel. */
724 wiphy->flags |= WIPHY_FLAG_DISABLE_BEACON_HINTS;
Amar Singhalf0073192013-09-20 12:34:56 -0700725
Amar Singhalfddc28c2013-09-05 13:03:40 -0700726
Amar Singhala49cbc52013-10-08 18:37:44 -0700727
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700728#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -0700729 wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME
730 | WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD
731 | WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL
Jeff Johnsone7245742012-09-05 17:12:55 -0700732 | WIPHY_FLAG_OFFCHAN_TX;
Kiet Lam6c583332013-10-14 05:37:09 +0530733 wiphy->country_ie_pref = NL80211_COUNTRY_IE_IGNORE_CORE;
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700734#endif
Amar Singhala49cbc52013-10-08 18:37:44 -0700735
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800736#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowda640728a2013-03-28 12:21:54 -0700737 if (pCfg->isFastTransitionEnabled
James Zmuda77fb5ae2013-01-29 08:00:17 -0800738#ifdef FEATURE_WLAN_LFR
Srinivas Girigowda640728a2013-03-28 12:21:54 -0700739 || pCfg->isFastRoamIniFeatureEnabled
740#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800741#ifdef FEATURE_WLAN_ESE
742 || pCfg->isEseIniFeatureEnabled
Srinivas Girigowda640728a2013-03-28 12:21:54 -0700743#endif
744 )
745 {
746 wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM;
747 }
James Zmuda77fb5ae2013-01-29 08:00:17 -0800748#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -0800749#ifdef FEATURE_WLAN_TDLS
750 wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS
751 | WIPHY_FLAG_TDLS_EXTERNAL_SETUP;
752#endif
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +0530753#ifdef FEATURE_WLAN_SCAN_PNO
Hardik Kantilal Patel3dfd8792013-11-13 20:34:57 +0530754 if (pCfg->configPNOScanSupport)
755 {
756 wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN;
757 wiphy->max_sched_scan_ssids = SIR_PNO_MAX_SUPP_NETWORKS;
758 wiphy->max_match_sets = SIR_PNO_MAX_SUPP_NETWORKS;
759 wiphy->max_sched_scan_ie_len = SIR_MAC_MAX_IE_LENGTH;
760 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +0530761#endif/*FEATURE_WLAN_SCAN_PNO*/
Mohit Khanna698ba2a2012-12-04 15:08:18 -0800762
Amar Singhalfddc28c2013-09-05 13:03:40 -0700763#ifdef CONFIG_ENABLE_LINUX_REG
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -0700764 /* even with WIPHY_FLAG_CUSTOM_REGULATORY,
765 driver can still register regulatory callback and
Amar Singhalfddc28c2013-09-05 13:03:40 -0700766 it will get regulatory settings in wiphy->band[], but
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -0700767 driver need to determine what to do with both
768 regulatory settings */
Amar Singhalfddc28c2013-09-05 13:03:40 -0700769
770 wiphy->reg_notifier = wlan_hdd_linux_reg_notifier;
Amar Singhala49cbc52013-10-08 18:37:44 -0700771#else
772 wiphy->reg_notifier = wlan_hdd_crda_reg_notifier;
Amar Singhalfddc28c2013-09-05 13:03:40 -0700773#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700774
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530775 wiphy->max_scan_ssids = MAX_SCAN_SSID;
776
Madan Mohan Koyyalamudi6815b162013-07-19 17:17:46 +0530777 wiphy->max_scan_ie_len = SIR_MAC_MAX_IE_LENGTH;
Jeff Johnson295189b2012-06-20 16:38:30 -0700778
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +0530779 wiphy->max_acl_mac_addrs = MAX_ACL_MAC_ADDRESS;
780
Jeff Johnson295189b2012-06-20 16:38:30 -0700781 /* Supports STATION & AD-HOC modes right now */
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530782 wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -0700783 | BIT(NL80211_IFTYPE_ADHOC)
Jeff Johnson295189b2012-06-20 16:38:30 -0700784 | BIT(NL80211_IFTYPE_P2P_CLIENT)
785 | BIT(NL80211_IFTYPE_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -0700786 | BIT(NL80211_IFTYPE_AP);
787
Rashmi Ramannabd3feb72014-02-25 16:14:48 +0530788 if( pCfg->advertiseConcurrentOperation )
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800789 {
Rashmi Ramannabd3feb72014-02-25 16:14:48 +0530790#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
791 if( pCfg->enableMCC )
792 {
793 /* Currently, supports up to two channels */
794 wlan_hdd_iface_combination.num_different_channels = 2;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800795
Rashmi Ramannabd3feb72014-02-25 16:14:48 +0530796 if( !pCfg->allowMCCGODiffBI )
797 wlan_hdd_iface_combination.beacon_int_infra_match = true;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800798
Rashmi Ramannabd3feb72014-02-25 16:14:48 +0530799 }
800 wiphy->iface_combinations = &wlan_hdd_iface_combination;
801 wiphy->n_iface_combinations = 1;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800802#endif
Rashmi Ramannabd3feb72014-02-25 16:14:48 +0530803 }
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800804
Jeff Johnson295189b2012-06-20 16:38:30 -0700805 /* Before registering we need to update the ht capabilitied based
806 * on ini values*/
807 if( !pCfg->ShortGI20MhzEnable )
808 {
809 wlan_hdd_band_2_4_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
810 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
811 wlan_hdd_band_p2p_2_4_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
812 }
813
814 if( !pCfg->ShortGI40MhzEnable )
815 {
816 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_40;
817 }
818
819 if( !pCfg->nChannelBondingMode5GHz )
820 {
821 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
822 }
823
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +0530824 wiphy->bands[IEEE80211_BAND_2GHZ] = &wlan_hdd_band_2_4_GHZ;
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +0530825 if (true == hdd_is_5g_supported(pHddCtx))
826 {
827 wiphy->bands[IEEE80211_BAND_5GHZ] = &wlan_hdd_band_5_GHZ;
828 }
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +0530829
830 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
831 {
832
833 if (NULL == wiphy->bands[i])
834 {
835 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[i] is NULL, i = %d",
836 __func__, i);
837 continue;
838 }
839
840 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
841 {
842 struct ieee80211_supported_band *band = wiphy->bands[i];
843
844 if (IEEE80211_BAND_2GHZ == i && eCSR_BAND_5G == pCfg->nBandCapability) // 5G only
845 {
846 // Enable social channels for P2P
847 if (WLAN_HDD_IS_SOCIAL_CHANNEL(band->channels[j].center_freq))
848 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
849 else
850 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
851 continue;
852 }
853 else if (IEEE80211_BAND_5GHZ == i && eCSR_BAND_24 == pCfg->nBandCapability) // 2G only
854 {
855 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
856 continue;
857 }
858 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700859 }
860 /*Initialise the supported cipher suite details*/
861 wiphy->cipher_suites = hdd_cipher_suites;
862 wiphy->n_cipher_suites = ARRAY_SIZE(hdd_cipher_suites);
863
864 /*signal strength in mBm (100*dBm) */
865 wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
866
867#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Jeff Johnson295189b2012-06-20 16:38:30 -0700868 wiphy->max_remain_on_channel_duration = 1000;
869#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700870
Rajesh Chauhan98a31f82014-01-06 20:15:25 -0800871 wiphy->n_vendor_commands = 0;
872 wiphy->vendor_events = wlan_hdd_cfg80211_vendor_events;
873 wiphy->n_vendor_events = ARRAY_SIZE(wlan_hdd_cfg80211_vendor_events);
874
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +0530875 EXIT();
876 return 0;
877}
878
879/* In this function we are registering wiphy. */
880int wlan_hdd_cfg80211_register(struct wiphy *wiphy)
881{
882 ENTER();
883 /* Register our wiphy dev with cfg80211 */
Jeff Johnson295189b2012-06-20 16:38:30 -0700884 if (0 > wiphy_register(wiphy))
885 {
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +0530886 /* print error */
Jeff Johnson295189b2012-06-20 16:38:30 -0700887 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
888 return -EIO;
889 }
890
891 EXIT();
892 return 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530893}
Jeff Johnson295189b2012-06-20 16:38:30 -0700894
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +0530895/* In this function we are updating channel list when,
896 regulatory domain is FCC and country code is US.
897 Here In FCC standard 5GHz UNII-1 Bands are indoor only.
898 As per FCC smart phone is not a indoor device.
899 GO should not opeate on indoor channels */
900void wlan_hdd_cfg80211_update_reg_info(struct wiphy *wiphy)
901{
902 int j;
903 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
904 tANI_U8 defaultCountryCode[3] = SME_INVALID_COUNTRY_CODE;
905 //Default counrtycode from NV at the time of wiphy initialization.
906 if (eHAL_STATUS_SUCCESS != sme_GetDefaultCountryCodeFrmNv(pHddCtx->hHal,
907 &defaultCountryCode[0]))
908 {
Jeff Johnson0299d0a2013-10-30 12:37:43 -0700909 hddLog(LOGE, FL("Failed to get default country code from NV"));
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +0530910 }
911 if ((defaultCountryCode[0]== 'U') && (defaultCountryCode[1]=='S'))
912 {
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +0530913 if (NULL == wiphy->bands[IEEE80211_BAND_5GHZ])
914 {
915 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[IEEE80211_BAND_5GHZ] is NULL",__func__ );
916 return;
917 }
918 for (j = 0; j < wiphy->bands[IEEE80211_BAND_5GHZ]->n_channels; j++)
919 {
920 struct ieee80211_supported_band *band = wiphy->bands[IEEE80211_BAND_5GHZ];
921 // Mark UNII -1 band channel as passive
922 if (WLAN_HDD_CHANNEL_IN_UNII_1_BAND(band->channels[j].center_freq))
923 band->channels[j].flags |= IEEE80211_CHAN_PASSIVE_SCAN;
924 }
925 }
926}
927
Jeff Johnson295189b2012-06-20 16:38:30 -0700928/* In this function we will do all post VOS start initialization.
929 In this function we will register for all frame in which supplicant
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530930 is interested.
Jeff Johnson295189b2012-06-20 16:38:30 -0700931*/
932void wlan_hdd_cfg80211_post_voss_start(hdd_adapter_t* pAdapter)
933{
Jeff Johnson295189b2012-06-20 16:38:30 -0700934 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
935 /* Register for all P2P action, public action etc frames */
936 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
937
Jeff Johnsone7245742012-09-05 17:12:55 -0700938 ENTER();
939
Jeff Johnson295189b2012-06-20 16:38:30 -0700940 /* Right now we are registering these frame when driver is getting
941 initialized. Once we will move to 2.6.37 kernel, in which we have
942 frame register ops, we will move this code as a part of that */
943 /* GAS Initial Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530944 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Jeff Johnson295189b2012-06-20 16:38:30 -0700945 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
946
947 /* GAS Initial Response */
948 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
949 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530950
Jeff Johnson295189b2012-06-20 16:38:30 -0700951 /* GAS Comeback Request */
952 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
953 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
954
955 /* GAS Comeback Response */
956 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
957 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
958
959 /* P2P Public Action */
960 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530961 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -0700962 P2P_PUBLIC_ACTION_FRAME_SIZE );
963
964 /* P2P Action */
965 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
966 (v_U8_t*)P2P_ACTION_FRAME,
967 P2P_ACTION_FRAME_SIZE );
Chet Lanctot186b5732013-03-18 10:26:30 -0700968
Gopichand Nakkalae3d56e72013-04-21 23:33:32 +0530969 /* WNM BSS Transition Request frame */
970 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
971 (v_U8_t*)WNM_BSS_ACTION_FRAME,
972 WNM_BSS_ACTION_FRAME_SIZE );
Leela Venkata Kiran Kumar Reddy Chiralae8e62c82013-10-29 18:23:26 -0700973
974 /* WNM-Notification */
975 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
976 (v_U8_t*)WNM_NOTIFICATION_FRAME,
977 WNM_NOTIFICATION_FRAME_SIZE );
Jeff Johnson295189b2012-06-20 16:38:30 -0700978}
979
980void wlan_hdd_cfg80211_pre_voss_stop(hdd_adapter_t* pAdapter)
981{
Jeff Johnson295189b2012-06-20 16:38:30 -0700982 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
983 /* Register for all P2P action, public action etc frames */
984 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
985
Jeff Johnsone7245742012-09-05 17:12:55 -0700986 ENTER();
987
Jeff Johnson295189b2012-06-20 16:38:30 -0700988 /* Right now we are registering these frame when driver is getting
989 initialized. Once we will move to 2.6.37 kernel, in which we have
990 frame register ops, we will move this code as a part of that */
991 /* GAS Initial Request */
992
993 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
994 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
995
996 /* GAS Initial Response */
997 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
998 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530999
Jeff Johnson295189b2012-06-20 16:38:30 -07001000 /* GAS Comeback Request */
1001 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
1002 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
1003
1004 /* GAS Comeback Response */
1005 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
1006 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
1007
1008 /* P2P Public Action */
1009 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301010 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -07001011 P2P_PUBLIC_ACTION_FRAME_SIZE );
1012
1013 /* P2P Action */
1014 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
1015 (v_U8_t*)P2P_ACTION_FRAME,
1016 P2P_ACTION_FRAME_SIZE );
Leela Venkata Kiran Kumar Reddy Chiralae8e62c82013-10-29 18:23:26 -07001017 /* WNM-Notification */
1018 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
1019 (v_U8_t*)WNM_NOTIFICATION_FRAME,
1020 WNM_NOTIFICATION_FRAME_SIZE );
Jeff Johnson295189b2012-06-20 16:38:30 -07001021}
1022
1023#ifdef FEATURE_WLAN_WAPI
1024void wlan_hdd_cfg80211_set_key_wapi(hdd_adapter_t* pAdapter, u8 key_index,
1025 const u8 *mac_addr, u8 *key , int key_Len)
1026{
1027 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
1028 tCsrRoamSetKey setKey;
1029 v_BOOL_t isConnected = TRUE;
1030 int status = 0;
1031 v_U32_t roamId= 0xFF;
1032 tANI_U8 *pKeyPtr = NULL;
1033 int n = 0;
1034
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05301035 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s(%d)",
1036 __func__, hdd_device_modetoString(pAdapter->device_mode),
1037 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07001038
Gopichand Nakkalae7480202013-02-11 15:24:22 +05301039 vos_mem_zero(&setKey, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -07001040 setKey.keyId = key_index; // Store Key ID
1041 setKey.encType = eCSR_ENCRYPT_TYPE_WPI; // SET WAPI Encryption
1042 setKey.keyDirection = eSIR_TX_RX; // Key Directionn both TX and RX
1043 setKey.paeRole = 0 ; // the PAE role
1044 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
1045 {
1046 vos_set_macaddr_broadcast( (v_MACADDR_t *)setKey.peerMac );
1047 }
1048 else
1049 {
1050 isConnected = hdd_connIsConnected(pHddStaCtx);
1051 vos_mem_copy(setKey.peerMac,&pHddStaCtx->conn_info.bssId,WNI_CFG_BSSID_LEN);
1052 }
1053 setKey.keyLength = key_Len;
1054 pKeyPtr = setKey.Key;
1055 memcpy( pKeyPtr, key, key_Len);
1056
Arif Hussain6d2a3322013-11-17 19:50:10 -08001057 hddLog(VOS_TRACE_LEVEL_INFO,"%s: WAPI KEY LENGTH:0x%04x",
Jeff Johnson295189b2012-06-20 16:38:30 -07001058 __func__, key_Len);
1059 for (n = 0 ; n < key_Len; n++)
1060 hddLog(VOS_TRACE_LEVEL_INFO, "%s WAPI KEY Data[%d]:%02x ",
1061 __func__,n,setKey.Key[n]);
1062
1063 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
1064 if ( isConnected )
1065 {
1066 status= sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
1067 pAdapter->sessionId, &setKey, &roamId );
1068 }
1069 if ( status != 0 )
1070 {
1071 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1072 "[%4d] sme_RoamSetKey returned ERROR status= %d",
1073 __LINE__, status );
1074 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
1075 }
1076}
1077#endif /* FEATURE_WLAN_WAPI*/
1078
1079#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301080int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07001081 beacon_data_t **ppBeacon,
1082 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001083#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301084int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001085 beacon_data_t **ppBeacon,
1086 struct cfg80211_beacon_data *params,
1087 int dtim_period)
1088#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301089{
Jeff Johnson295189b2012-06-20 16:38:30 -07001090 int size;
1091 beacon_data_t *beacon = NULL;
1092 beacon_data_t *old = NULL;
1093 int head_len,tail_len;
1094
Jeff Johnsone7245742012-09-05 17:12:55 -07001095 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07001096 if (params->head && !params->head_len)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05301097 {
1098 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1099 FL("head_len is NULL"));
Jeff Johnson295189b2012-06-20 16:38:30 -07001100 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05301101 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001102
1103 old = pAdapter->sessionCtx.ap.beacon;
1104
1105 if (!params->head && !old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05301106 {
1107 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1108 FL("session(%d) old and new heads points to NULL"),
1109 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07001110 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05301111 }
1112
1113 if (params->tail && !params->tail_len)
1114 {
1115 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1116 FL("tail_len is zero but tail is not NULL"));
1117 return -EINVAL;
1118 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001119
Jeff Johnson295189b2012-06-20 16:38:30 -07001120#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,38))
1121 /* Kernel 3.0 is not updating dtim_period for set beacon */
1122 if (!params->dtim_period)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05301123 {
1124 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1125 FL("dtim period is 0"));
Jeff Johnson295189b2012-06-20 16:38:30 -07001126 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05301127 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001128#endif
1129
1130 if(params->head)
1131 head_len = params->head_len;
1132 else
1133 head_len = old->head_len;
1134
1135 if(params->tail || !old)
1136 tail_len = params->tail_len;
1137 else
1138 tail_len = old->tail_len;
1139
1140 size = sizeof(beacon_data_t) + head_len + tail_len;
1141
1142 beacon = kzalloc(size, GFP_KERNEL);
1143
1144 if( beacon == NULL )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05301145 {
1146 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1147 FL("Mem allocation for beacon failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -07001148 return -ENOMEM;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05301149 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001150
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001151#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07001152 if(params->dtim_period || !old )
1153 beacon->dtim_period = params->dtim_period;
1154 else
1155 beacon->dtim_period = old->dtim_period;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001156#else
1157 if(dtim_period || !old )
1158 beacon->dtim_period = dtim_period;
1159 else
1160 beacon->dtim_period = old->dtim_period;
1161#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301162
Jeff Johnson295189b2012-06-20 16:38:30 -07001163 beacon->head = ((u8 *) beacon) + sizeof(beacon_data_t);
1164 beacon->tail = beacon->head + head_len;
1165 beacon->head_len = head_len;
1166 beacon->tail_len = tail_len;
1167
1168 if(params->head) {
1169 memcpy (beacon->head,params->head,beacon->head_len);
1170 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301171 else {
Jeff Johnson295189b2012-06-20 16:38:30 -07001172 if(old)
1173 memcpy (beacon->head,old->head,beacon->head_len);
1174 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301175
Jeff Johnson295189b2012-06-20 16:38:30 -07001176 if(params->tail) {
1177 memcpy (beacon->tail,params->tail,beacon->tail_len);
1178 }
1179 else {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301180 if(old)
Jeff Johnson295189b2012-06-20 16:38:30 -07001181 memcpy (beacon->tail,old->tail,beacon->tail_len);
1182 }
1183
1184 *ppBeacon = beacon;
1185
1186 kfree(old);
1187
1188 return 0;
1189
1190}
Jeff Johnson295189b2012-06-20 16:38:30 -07001191
1192v_U8_t* wlan_hdd_cfg80211_get_ie_ptr(v_U8_t *pIes, int length, v_U8_t eid)
1193{
1194 int left = length;
1195 v_U8_t *ptr = pIes;
1196 v_U8_t elem_id,elem_len;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301197
Jeff Johnson295189b2012-06-20 16:38:30 -07001198 while(left >= 2)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301199 {
Jeff Johnson295189b2012-06-20 16:38:30 -07001200 elem_id = ptr[0];
1201 elem_len = ptr[1];
1202 left -= 2;
1203 if(elem_len > left)
1204 {
1205 hddLog(VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07001206 FL("****Invalid IEs eid = %d elem_len=%d left=%d*****"),
Jeff Johnson295189b2012-06-20 16:38:30 -07001207 eid,elem_len,left);
1208 return NULL;
1209 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301210 if (elem_id == eid)
Jeff Johnson295189b2012-06-20 16:38:30 -07001211 {
1212 return ptr;
1213 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301214
Jeff Johnson295189b2012-06-20 16:38:30 -07001215 left -= elem_len;
1216 ptr += (elem_len + 2);
1217 }
1218 return NULL;
1219}
1220
Jeff Johnson295189b2012-06-20 16:38:30 -07001221/* Check if rate is 11g rate or not */
1222static int wlan_hdd_rate_is_11g(u8 rate)
1223{
Sanjay Devnani28322e22013-06-21 16:13:40 -07001224 static const u8 gRateArray[8] = {12, 18, 24, 36, 48, 72, 96, 108}; /* actual rate * 2 */
Jeff Johnson295189b2012-06-20 16:38:30 -07001225 u8 i;
1226 for (i = 0; i < 8; i++)
1227 {
1228 if(rate == gRateArray[i])
1229 return TRUE;
1230 }
1231 return FALSE;
1232}
1233
1234/* Check for 11g rate and set proper 11g only mode */
1235static void wlan_hdd_check_11gmode(u8 *pIe, u8* require_ht,
1236 u8* pCheckRatesfor11g, eSapPhyMode* pSapHw_mode)
1237{
1238 u8 i, num_rates = pIe[0];
1239
1240 pIe += 1;
1241 for ( i = 0; i < num_rates; i++)
1242 {
1243 if( *pCheckRatesfor11g && (TRUE == wlan_hdd_rate_is_11g(pIe[i] & RATE_MASK)))
1244 {
1245 /* If rate set have 11g rate than change the mode to 11G */
1246 *pSapHw_mode = eSAP_DOT11_MODE_11g;
1247 if (pIe[i] & BASIC_RATE_MASK)
1248 {
1249 /* If we have 11g rate as basic rate, it means mode
1250 is 11g only mode.
1251 */
1252 *pSapHw_mode = eSAP_DOT11_MODE_11g_ONLY;
1253 *pCheckRatesfor11g = FALSE;
1254 }
1255 }
1256 else if((BASIC_RATE_MASK | WLAN_BSS_MEMBERSHIP_SELECTOR_HT_PHY) == pIe[i])
1257 {
1258 *require_ht = TRUE;
1259 }
1260 }
1261 return;
1262}
1263
1264static void wlan_hdd_set_sapHwmode(hdd_adapter_t *pHostapdAdapter)
1265{
1266 tsap_Config_t *pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
1267 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
1268 struct ieee80211_mgmt *pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
1269 u8 checkRatesfor11g = TRUE;
1270 u8 require_ht = FALSE;
1271 u8 *pIe=NULL;
1272
1273 pConfig->SapHw_mode= eSAP_DOT11_MODE_11b;
1274
1275 pIe = wlan_hdd_cfg80211_get_ie_ptr(&pMgmt_frame->u.beacon.variable[0],
1276 pBeacon->head_len, WLAN_EID_SUPP_RATES);
1277 if (pIe != NULL)
1278 {
1279 pIe += 1;
1280 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
1281 &pConfig->SapHw_mode);
1282 }
1283
1284 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
1285 WLAN_EID_EXT_SUPP_RATES);
1286 if (pIe != NULL)
1287 {
1288
1289 pIe += 1;
1290 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
1291 &pConfig->SapHw_mode);
1292 }
1293
1294 if( pConfig->channel > 14 )
1295 {
1296 pConfig->SapHw_mode= eSAP_DOT11_MODE_11a;
1297 }
1298
1299 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
1300 WLAN_EID_HT_CAPABILITY);
1301
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301302 if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07001303 {
1304 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n;
1305 if(require_ht)
1306 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n_ONLY;
1307 }
1308}
1309
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05301310static int wlan_hdd_add_ie(hdd_adapter_t* pHostapdAdapter, v_U8_t *genie,
1311 v_U8_t *total_ielen, v_U8_t *oui, v_U8_t oui_size)
1312{
Arif Hussaine7f3ea52013-09-12 21:56:36 -07001313 v_U16_t ielen = 0;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05301314 v_U8_t *pIe = NULL;
1315 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
1316
1317 pIe = wlan_hdd_get_vendor_oui_ie_ptr(oui, oui_size,
1318 pBeacon->tail, pBeacon->tail_len);
1319
1320 if (pIe)
1321 {
1322 ielen = pIe[1] + 2;
1323 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
1324 {
1325 vos_mem_copy(&genie[*total_ielen], pIe, ielen);
1326 }
1327 else
1328 {
1329 hddLog( VOS_TRACE_LEVEL_ERROR, "**Ie Length is too big***");
1330 return -EINVAL;
1331 }
1332 *total_ielen += ielen;
1333 }
1334 return 0;
1335}
1336
Arif Hussaine7f3ea52013-09-12 21:56:36 -07001337static void wlan_hdd_add_hostapd_conf_vsie(hdd_adapter_t* pHostapdAdapter,
1338 v_U8_t *genie, v_U8_t *total_ielen)
1339{
1340 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
1341 int left = pBeacon->tail_len;
1342 v_U8_t *ptr = pBeacon->tail;
1343 v_U8_t elem_id, elem_len;
1344 v_U16_t ielen = 0;
1345
1346 if ( NULL == ptr || 0 == left )
1347 return;
1348
1349 while (left >= 2)
1350 {
1351 elem_id = ptr[0];
1352 elem_len = ptr[1];
1353 left -= 2;
1354 if (elem_len > left)
1355 {
1356 hddLog( VOS_TRACE_LEVEL_ERROR,
1357 "****Invalid IEs eid = %d elem_len=%d left=%d*****",
1358 elem_id, elem_len, left);
1359 return;
1360 }
1361 if (IE_EID_VENDOR == elem_id)
1362 {
1363 /* skipping the VSIE's which we don't want to include or
1364 * it will be included by existing code
1365 */
1366 if ((memcmp( &ptr[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) != 0 ) &&
1367#ifdef WLAN_FEATURE_WFD
1368 (memcmp( &ptr[2], WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE) != 0) &&
1369#endif
1370 (memcmp( &ptr[2], WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
1371 (memcmp( &ptr[2], BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
1372 (memcmp( &ptr[2], "\x00\x50\xf2\x02", WPA_OUI_TYPE_SIZE) != 0) &&
1373 (memcmp( &ptr[2], WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
1374 (memcmp( &ptr[2], P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE) != 0))
1375 {
1376 ielen = ptr[1] + 2;
1377 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
1378 {
1379 vos_mem_copy(&genie[*total_ielen], ptr, ielen);
1380 *total_ielen += ielen;
1381 }
1382 else
1383 {
1384 hddLog( VOS_TRACE_LEVEL_ERROR,
1385 "IE Length is too big "
1386 "IEs eid=%d elem_len=%d total_ie_lent=%d",
1387 elem_id, elem_len, *total_ielen);
1388 }
1389 }
1390 }
1391
1392 left -= elem_len;
1393 ptr += (elem_len + 2);
1394 }
1395 return;
1396}
1397
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001398#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07001399static int wlan_hdd_cfg80211_update_apies(hdd_adapter_t* pHostapdAdapter,
1400 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001401#else
1402static int wlan_hdd_cfg80211_update_apies(hdd_adapter_t* pHostapdAdapter,
1403 struct cfg80211_beacon_data *params)
1404#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07001405{
1406 v_U8_t *genie;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05301407 v_U8_t total_ielen = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07001408 v_U8_t addIE[1] = {0};
Jeff Johnsone7245742012-09-05 17:12:55 -07001409 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07001410
1411 genie = vos_mem_malloc(MAX_GENIE_LEN);
1412
1413 if(genie == NULL) {
1414
1415 return -ENOMEM;
1416 }
1417
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05301418 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
1419 &total_ielen, WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07001420 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05301421 hddLog(LOGE,
1422 FL("Adding WPS IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05301423 ret = -EINVAL;
1424 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001425 }
1426
1427#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05301428 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
1429 &total_ielen, WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE))
1430 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05301431 hddLog(LOGE,
1432 FL("Adding WFD IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05301433 ret = -EINVAL;
1434 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001435 }
1436#endif
1437
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05301438 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
1439 &total_ielen, P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07001440 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05301441 hddLog(LOGE,
1442 FL("Adding P2P IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05301443 ret = -EINVAL;
1444 goto done;
1445 }
1446
1447 if (WLAN_HDD_SOFTAP == pHostapdAdapter->device_mode)
1448 {
Arif Hussaine7f3ea52013-09-12 21:56:36 -07001449 wlan_hdd_add_hostapd_conf_vsie(pHostapdAdapter, genie, &total_ielen);
Jeff Johnson295189b2012-06-20 16:38:30 -07001450 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001451
1452 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1453 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, genie, total_ielen, NULL,
1454 eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
1455 {
1456 hddLog(LOGE,
1457 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001458 ret = -EINVAL;
1459 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001460 }
1461
1462 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1463 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
1464 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
1465 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
1466 ==eHAL_STATUS_FAILURE)
1467 {
1468 hddLog(LOGE,
1469 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001470 ret = -EINVAL;
1471 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001472 }
1473
1474 // Added for ProResp IE
1475 if ( (params->proberesp_ies != NULL) && (params->proberesp_ies_len != 0) )
1476 {
1477 u16 rem_probe_resp_ie_len = params->proberesp_ies_len;
1478 u8 probe_rsp_ie_len[3] = {0};
1479 u8 counter = 0;
1480 /* Check Probe Resp Length if it is greater then 255 then Store
1481 Probe Resp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1 &
1482 WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are not able
1483 Store More then 255 bytes into One Variable.
1484 */
1485 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
1486 {
1487 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
1488 {
1489 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
1490 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
1491 }
1492 else
1493 {
1494 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
1495 rem_probe_resp_ie_len = 0;
1496 }
1497 }
1498
1499 rem_probe_resp_ie_len = 0;
1500
1501 if (probe_rsp_ie_len[0] > 0)
1502 {
1503 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1504 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
1505 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
1506 probe_rsp_ie_len[0], NULL,
1507 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
1508 {
1509 hddLog(LOGE,
1510 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001511 ret = -EINVAL;
1512 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001513 }
1514 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
1515 }
1516
1517 if (probe_rsp_ie_len[1] > 0)
1518 {
1519 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1520 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
1521 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
1522 probe_rsp_ie_len[1], NULL,
1523 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
1524 {
1525 hddLog(LOGE,
1526 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001527 ret = -EINVAL;
1528 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001529 }
1530 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
1531 }
1532
1533 if (probe_rsp_ie_len[2] > 0)
1534 {
1535 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1536 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
1537 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
1538 probe_rsp_ie_len[2], NULL,
1539 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
1540 {
1541 hddLog(LOGE,
1542 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001543 ret = -EINVAL;
1544 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001545 }
1546 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
1547 }
1548
1549 if (probe_rsp_ie_len[1] == 0 )
1550 {
1551 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1552 WNI_CFG_PROBE_RSP_ADDNIE_DATA2, (tANI_U8*)addIE, 0, NULL,
1553 eANI_BOOLEAN_FALSE) )
1554 {
1555 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08001556 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07001557 }
1558 }
1559
1560 if (probe_rsp_ie_len[2] == 0 )
1561 {
1562 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1563 WNI_CFG_PROBE_RSP_ADDNIE_DATA3, (tANI_U8*)addIE, 0, NULL,
1564 eANI_BOOLEAN_FALSE) )
1565 {
1566 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08001567 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07001568 }
1569 }
1570
1571 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1572 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
1573 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
1574 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
1575 == eHAL_STATUS_FAILURE)
1576 {
1577 hddLog(LOGE,
1578 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001579 ret = -EINVAL;
1580 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001581 }
1582 }
1583 else
1584 {
1585 // Reset WNI_CFG_PROBE_RSP Flags
1586 wlan_hdd_reset_prob_rspies(pHostapdAdapter);
1587
1588 hddLog(VOS_TRACE_LEVEL_INFO,
1589 "%s: No Probe Response IE received in set beacon",
1590 __func__);
1591 }
1592
1593 // Added for AssocResp IE
1594 if ( (params->assocresp_ies != NULL) && (params->assocresp_ies_len != 0) )
1595 {
1596 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1597 WNI_CFG_ASSOC_RSP_ADDNIE_DATA, (tANI_U8*)params->assocresp_ies,
1598 params->assocresp_ies_len, NULL,
1599 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
1600 {
1601 hddLog(LOGE,
1602 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001603 ret = -EINVAL;
1604 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001605 }
1606
1607 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1608 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 1, NULL,
1609 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
1610 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
1611 == eHAL_STATUS_FAILURE)
1612 {
1613 hddLog(LOGE,
1614 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001615 ret = -EINVAL;
1616 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001617 }
1618 }
1619 else
1620 {
1621 hddLog(VOS_TRACE_LEVEL_INFO,
1622 "%s: No Assoc Response IE received in set beacon",
1623 __func__);
1624
1625 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1626 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
1627 eANI_BOOLEAN_FALSE) )
1628 {
1629 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08001630 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07001631 }
1632 }
1633
Jeff Johnsone7245742012-09-05 17:12:55 -07001634done:
Jeff Johnson295189b2012-06-20 16:38:30 -07001635 vos_mem_free(genie);
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05301636 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07001637}
Jeff Johnson295189b2012-06-20 16:38:30 -07001638
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301639/*
Jeff Johnson295189b2012-06-20 16:38:30 -07001640 * FUNCTION: wlan_hdd_validate_operation_channel
1641 * called by wlan_hdd_cfg80211_start_bss() and
1642 * wlan_hdd_cfg80211_set_channel()
1643 * This function validates whether given channel is part of valid
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301644 * channel list.
1645 */
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07001646VOS_STATUS wlan_hdd_validate_operation_channel(hdd_adapter_t *pAdapter,int channel)
Jeff Johnson295189b2012-06-20 16:38:30 -07001647{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301648
Jeff Johnson295189b2012-06-20 16:38:30 -07001649 v_U32_t num_ch = 0;
1650 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN];
1651 u32 indx = 0;
1652 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05301653 v_U8_t fValidChannel = FALSE, count = 0;
1654 hdd_config_t *hdd_pConfig_ini= (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301655
Jeff Johnson295189b2012-06-20 16:38:30 -07001656 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
1657
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05301658 if ( hdd_pConfig_ini->sapAllowAllChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -07001659 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05301660 /* Validate the channel */
1661 for (count = RF_CHAN_1 ; count <= RF_CHAN_165 ; count++)
Jeff Johnson295189b2012-06-20 16:38:30 -07001662 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05301663 if ( channel == rfChannels[count].channelNum )
1664 {
1665 fValidChannel = TRUE;
1666 break;
1667 }
1668 }
1669 if (fValidChannel != TRUE)
1670 {
1671 hddLog(VOS_TRACE_LEVEL_ERROR,
1672 "%s: Invalid Channel [%d]", __func__, channel);
1673 return VOS_STATUS_E_FAILURE;
Jeff Johnson295189b2012-06-20 16:38:30 -07001674 }
1675 }
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05301676 else
Jeff Johnson295189b2012-06-20 16:38:30 -07001677 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05301678 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
1679 valid_ch, &num_ch))
1680 {
1681 hddLog(VOS_TRACE_LEVEL_ERROR,
1682 "%s: failed to get valid channel list", __func__);
1683 return VOS_STATUS_E_FAILURE;
1684 }
1685 for (indx = 0; indx < num_ch; indx++)
1686 {
1687 if (channel == valid_ch[indx])
1688 {
1689 break;
1690 }
1691 }
1692
Rashmi Ramanna3b59e122014-04-10 14:45:13 +05301693 if (indx >= num_ch)
1694 {
1695 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
1696 {
1697 eCsrBand band;
1698 unsigned int freq;
1699
1700 sme_GetFreqBand(hHal, &band);
1701
1702 if (eCSR_BAND_5G == band)
1703 {
1704#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
1705 if (channel <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
1706 {
1707 freq = ieee80211_channel_to_frequency(channel,
1708 IEEE80211_BAND_2GHZ);
1709 }
1710 else
1711 {
1712 freq = ieee80211_channel_to_frequency(channel,
1713 IEEE80211_BAND_5GHZ);
1714 }
1715#else
1716 freq = ieee80211_channel_to_frequency(channel);
1717#endif
1718 if(WLAN_HDD_IS_SOCIAL_CHANNEL(freq))
1719 return VOS_STATUS_SUCCESS;
1720 }
1721 }
1722
1723 hddLog(VOS_TRACE_LEVEL_ERROR,
1724 "%s: Invalid Channel [%d]", __func__, channel);
1725 return VOS_STATUS_E_FAILURE;
1726 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001727 }
Rashmi Ramanna3b59e122014-04-10 14:45:13 +05301728
Jeff Johnson295189b2012-06-20 16:38:30 -07001729 return VOS_STATUS_SUCCESS;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301730
Jeff Johnson295189b2012-06-20 16:38:30 -07001731}
1732
Viral Modi3a32cc52013-02-08 11:14:52 -08001733/**
1734 * FUNCTION: wlan_hdd_cfg80211_set_channel
1735 * This function is used to set the channel number
1736 */
1737static int wlan_hdd_cfg80211_set_channel( struct wiphy *wiphy, struct net_device *dev,
1738 struct ieee80211_channel *chan,
1739 enum nl80211_channel_type channel_type
1740 )
1741{
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05301742 hdd_adapter_t *pAdapter = NULL;
Viral Modi3a32cc52013-02-08 11:14:52 -08001743 v_U32_t num_ch = 0;
Jeff Johnson4416a782013-03-25 14:17:50 -07001744 int channel = 0;
Viral Modi3a32cc52013-02-08 11:14:52 -08001745 int freq = chan->center_freq; /* freq is in MHZ */
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05301746 hdd_context_t *pHddCtx;
1747 int status;
Viral Modi3a32cc52013-02-08 11:14:52 -08001748
1749 ENTER();
1750
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05301751
Viral Modi3a32cc52013-02-08 11:14:52 -08001752 if( NULL == dev )
1753 {
1754 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08001755 "%s: Called with dev = NULL.", __func__);
Viral Modi3a32cc52013-02-08 11:14:52 -08001756 return -ENODEV;
1757 }
1758 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
1759
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05301760 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
1761 TRACE_CODE_HDD_CFG80211_SET_CHANNEL, pAdapter->sessionId,
1762 channel_type ));
Viral Modi3a32cc52013-02-08 11:14:52 -08001763 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05301764 "%s: device_mode = %s (%d) freq = %d", __func__,
1765 hdd_device_modetoString(pAdapter->device_mode),
1766 pAdapter->device_mode, chan->center_freq);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05301767
1768 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1769 status = wlan_hdd_validate_context(pHddCtx);
1770
1771 if (0 != status)
Viral Modi3a32cc52013-02-08 11:14:52 -08001772 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05301773 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1774 "%s: HDD context is not valid", __func__);
1775 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -08001776 }
1777
1778 /*
1779 * Do freq to chan conversion
1780 * TODO: for 11a
1781 */
1782
1783 channel = ieee80211_frequency_to_channel(freq);
1784
1785 /* Check freq range */
1786 if ((WNI_CFG_CURRENT_CHANNEL_STAMIN > channel) ||
1787 (WNI_CFG_CURRENT_CHANNEL_STAMAX < channel))
1788 {
1789 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08001790 "%s: Channel [%d] is outside valid range from %d to %d",
Viral Modi3a32cc52013-02-08 11:14:52 -08001791 __func__, channel, WNI_CFG_CURRENT_CHANNEL_STAMIN,
1792 WNI_CFG_CURRENT_CHANNEL_STAMAX);
1793 return -EINVAL;
1794 }
1795
1796 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
1797
Gopichand Nakkala6ab19562013-03-07 13:59:42 +05301798 if ((WLAN_HDD_SOFTAP != pAdapter->device_mode) &&
1799 (WLAN_HDD_P2P_GO != pAdapter->device_mode))
Viral Modi3a32cc52013-02-08 11:14:52 -08001800 {
1801 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pAdapter,channel))
1802 {
1803 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08001804 "%s: Invalid Channel [%d]", __func__, channel);
Viral Modi3a32cc52013-02-08 11:14:52 -08001805 return -EINVAL;
1806 }
1807 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
1808 "%s: set channel to [%d] for device mode =%d",
1809 __func__, channel,pAdapter->device_mode);
1810 }
1811 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Viral Modi3a32cc52013-02-08 11:14:52 -08001812 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Viral Modi3a32cc52013-02-08 11:14:52 -08001813 )
1814 {
1815 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
1816 tCsrRoamProfile * pRoamProfile = &pWextState->roamProfile;
1817 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
1818
1819 if (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState)
1820 {
1821 /* Link is up then return cant set channel*/
1822 hddLog( VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08001823 "%s: IBSS Associated, can't set the channel", __func__);
Viral Modi3a32cc52013-02-08 11:14:52 -08001824 return -EINVAL;
1825 }
1826
1827 num_ch = pRoamProfile->ChannelInfo.numOfChannels = 1;
1828 pHddStaCtx->conn_info.operationChannel = channel;
1829 pRoamProfile->ChannelInfo.ChannelList =
1830 &pHddStaCtx->conn_info.operationChannel;
1831 }
1832 else if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Viral Modi3a32cc52013-02-08 11:14:52 -08001833 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Viral Modi3a32cc52013-02-08 11:14:52 -08001834 )
1835 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05301836 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
1837 {
1838 if(VOS_STATUS_SUCCESS !=
1839 wlan_hdd_validate_operation_channel(pAdapter,channel))
1840 {
1841 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08001842 "%s: Invalid Channel [%d]", __func__, channel);
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05301843 return -EINVAL;
1844 }
1845 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
1846 }
1847 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
Viral Modi3a32cc52013-02-08 11:14:52 -08001848 {
1849 hdd_config_t *cfg_param = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
1850
1851 /* If auto channel selection is configured as enable/ 1 then ignore
1852 channel set by supplicant
1853 */
1854 if ( cfg_param->apAutoChannelSelection )
1855 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05301856 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel =
1857 AUTO_CHANNEL_SELECT;
Viral Modi3a32cc52013-02-08 11:14:52 -08001858 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05301859 "%s: set channel to auto channel (0) for device mode =%s (%d)",
1860 __func__, hdd_device_modetoString(pAdapter->device_mode),
1861 pAdapter->device_mode);
Viral Modi3a32cc52013-02-08 11:14:52 -08001862 }
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05301863 else
1864 {
1865 if(VOS_STATUS_SUCCESS !=
1866 wlan_hdd_validate_operation_channel(pAdapter,channel))
1867 {
1868 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08001869 "%s: Invalid Channel [%d]", __func__, channel);
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05301870 return -EINVAL;
1871 }
1872 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
1873 }
Viral Modi3a32cc52013-02-08 11:14:52 -08001874 }
1875 }
1876 else
1877 {
1878 hddLog(VOS_TRACE_LEVEL_FATAL,
1879 "%s: Invalid device mode failed to set valid channel", __func__);
1880 return -EINVAL;
1881 }
1882 EXIT();
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05301883 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -08001884}
1885
Jeff Johnson295189b2012-06-20 16:38:30 -07001886#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
1887static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
1888 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001889#else
1890static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
1891 struct cfg80211_beacon_data *params,
1892 const u8 *ssid, size_t ssid_len,
1893 enum nl80211_hidden_ssid hidden_ssid)
1894#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07001895{
1896 tsap_Config_t *pConfig;
1897 beacon_data_t *pBeacon = NULL;
1898 struct ieee80211_mgmt *pMgmt_frame;
1899 v_U8_t *pIe=NULL;
1900 v_U16_t capab_info;
1901 eCsrAuthType RSNAuthType;
1902 eCsrEncryptionType RSNEncryptType;
1903 eCsrEncryptionType mcRSNEncryptType;
1904 int status = VOS_STATUS_SUCCESS;
1905 tpWLAN_SAPEventCB pSapEventCallback;
1906 hdd_hostapd_state_t *pHostapdState;
1907 v_U8_t wpaRsnIEdata[(SIR_MAC_MAX_IE_LENGTH * 2)+4]; //Max ie length 255 * 2(WPA+RSN) + 2 bytes (vendor specific ID) * 2
1908 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05301909 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07001910 struct qc_mac_acl_entry *acl_entry = NULL;
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05301911 hdd_config_t *iniConfig;
Jeff Johnson295189b2012-06-20 16:38:30 -07001912 v_SINT_t i;
Madan Mohan Koyyalamudi543172b2012-12-05 16:40:18 -08001913 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
Chet Lanctot8cecea22014-02-11 19:09:36 -08001914 v_BOOL_t MFPCapable;
1915 v_BOOL_t MFPRequired;
Abhishek Singhf0ac1752014-03-05 17:47:09 +05301916 eHddDot11Mode sapDot11Mode =
1917 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->sapDot11Mode;
Jeff Johnson295189b2012-06-20 16:38:30 -07001918
1919 ENTER();
1920
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05301921 iniConfig = pHddCtx->cfg_ini;
1922
Jeff Johnson295189b2012-06-20 16:38:30 -07001923 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter);
1924
1925 pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
1926
1927 pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
1928
1929 pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
1930
1931 pConfig->beacon_int = pMgmt_frame->u.beacon.beacon_int;
1932
1933 //channel is already set in the set_channel Call back
1934 //pConfig->channel = pCommitConfig->channel;
1935
1936 /*Protection parameter to enable or disable*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301937 pConfig->protEnabled =
Jeff Johnson295189b2012-06-20 16:38:30 -07001938 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtEnabled;
1939
1940 pConfig->dtim_period = pBeacon->dtim_period;
1941
Arif Hussain6d2a3322013-11-17 19:50:10 -08001942 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"****pConfig->dtim_period=%d***",
Jeff Johnson295189b2012-06-20 16:38:30 -07001943 pConfig->dtim_period);
1944
1945
Madan Mohan Koyyalamudie0ca11f2012-11-27 15:57:52 -08001946 if (pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson32d95a32012-09-10 13:15:23 -07001947 {
1948 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -07001949 WLAN_EID_COUNTRY);
Kiet Lam083504c2013-11-25 14:17:45 +05301950 if(memcmp(pHddCtx->cfg_ini->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0)
1951 {
1952 tANI_BOOLEAN restartNeeded;
1953 pConfig->ieee80211d = 1;
1954 vos_mem_copy(pConfig->countryCode, pHddCtx->cfg_ini->apCntryCode, 3);
1955 sme_setRegInfo(hHal, pConfig->countryCode);
1956 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
1957 }
1958 else if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07001959 {
Jeff Johnson32d95a32012-09-10 13:15:23 -07001960 tANI_BOOLEAN restartNeeded;
Jeff Johnson32d95a32012-09-10 13:15:23 -07001961 pConfig->ieee80211d = 1;
1962 vos_mem_copy(pConfig->countryCode, &pIe[2], 3);
1963 sme_setRegInfo(hHal, pConfig->countryCode);
1964 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
Jeff Johnson295189b2012-06-20 16:38:30 -07001965 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07001966 else
1967 {
1968 pConfig->ieee80211d = 0;
1969 }
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05301970 /*
1971 * If auto channel is configured i.e. channel is 0,
1972 * so skip channel validation.
1973 */
1974 if( AUTO_CHANNEL_SELECT != pConfig->channel )
1975 {
1976 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pHostapdAdapter,pConfig->channel))
1977 {
1978 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08001979 "%s: Invalid Channel [%d]", __func__, pConfig->channel);
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05301980 return -EINVAL;
1981 }
1982 }
1983 else
1984 {
1985 if(1 != pHddCtx->is_dynamic_channel_range_set)
1986 {
1987 hdd_config_t *hdd_pConfig= (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini;
1988 WLANSAP_SetChannelRange(hHal, hdd_pConfig->apStartChannelNum,
1989 hdd_pConfig->apEndChannelNum,hdd_pConfig->apOperatingBand);
1990 }
1991 pHddCtx->is_dynamic_channel_range_set = 0;
1992 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001993 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07001994 else
Jeff Johnson295189b2012-06-20 16:38:30 -07001995 {
1996 pConfig->ieee80211d = 0;
1997 }
1998 pConfig->authType = eSAP_AUTO_SWITCH;
1999
2000 capab_info = pMgmt_frame->u.beacon.capab_info;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302001
2002 pConfig->privacy = (pMgmt_frame->u.beacon.capab_info &
Jeff Johnson295189b2012-06-20 16:38:30 -07002003 WLAN_CAPABILITY_PRIVACY) ? VOS_TRUE : VOS_FALSE;
2004
2005 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uPrivacy = pConfig->privacy;
2006
2007 /*Set wps station to configured*/
2008 pIe = wlan_hdd_get_wps_ie_ptr(pBeacon->tail, pBeacon->tail_len);
2009
2010 if(pIe)
2011 {
2012 if(pIe[1] < (2 + WPS_OUI_TYPE_SIZE))
2013 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08002014 hddLog( VOS_TRACE_LEVEL_ERROR, "**Wps Ie Length is too small***");
Jeff Johnson295189b2012-06-20 16:38:30 -07002015 return -EINVAL;
2016 }
2017 else if(memcmp(&pIe[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) == 0)
2018 {
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07002019 hddLog( VOS_TRACE_LEVEL_INFO, "** WPS IE(len %d) ***", (pIe[1]+2));
Jeff Johnson295189b2012-06-20 16:38:30 -07002020 /* Check 15 bit of WPS IE as it contain information for wps state
2021 * WPS state
2022 */
2023 if(SAP_WPS_ENABLED_UNCONFIGURED == pIe[15])
2024 {
2025 pConfig->wps_state = SAP_WPS_ENABLED_UNCONFIGURED;
2026 } else if(SAP_WPS_ENABLED_CONFIGURED == pIe[15])
2027 {
2028 pConfig->wps_state = SAP_WPS_ENABLED_CONFIGURED;
2029 }
2030 }
2031 }
2032 else
2033 {
2034 pConfig->wps_state = SAP_WPS_DISABLED;
2035 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302036 pConfig->fwdWPSPBCProbeReq = 1; // Forward WPS PBC probe request frame up
Jeff Johnson295189b2012-06-20 16:38:30 -07002037
2038 pConfig->RSNWPAReqIELength = 0;
2039 pConfig->pRSNWPAReqIE = NULL;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302040 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -07002041 WLAN_EID_RSN);
2042 if(pIe && pIe[1])
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302043 {
Jeff Johnson295189b2012-06-20 16:38:30 -07002044 pConfig->RSNWPAReqIELength = pIe[1] + 2;
2045 memcpy(&wpaRsnIEdata[0], pIe, pConfig->RSNWPAReqIELength);
2046 pConfig->pRSNWPAReqIE = &wpaRsnIEdata[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302047 /* The actual processing may eventually be more extensive than
2048 * this. Right now, just consume any PMKIDs that are sent in
Jeff Johnson295189b2012-06-20 16:38:30 -07002049 * by the app.
2050 * */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302051 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -07002052 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
2053 &RSNEncryptType,
2054 &mcRSNEncryptType,
2055 &RSNAuthType,
Chet Lanctot8cecea22014-02-11 19:09:36 -08002056 &MFPCapable,
2057 &MFPRequired,
Jeff Johnson295189b2012-06-20 16:38:30 -07002058 pConfig->pRSNWPAReqIE[1]+2,
2059 pConfig->pRSNWPAReqIE );
2060
2061 if( VOS_STATUS_SUCCESS == status )
2062 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302063 /* Now copy over all the security attributes you have
2064 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -07002065 * */
2066 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
2067 pConfig->mcRSNEncryptType = mcRSNEncryptType;
2068 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
2069 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05302070 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -08002071 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -07002072 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
2073 }
2074 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302075
Jeff Johnson295189b2012-06-20 16:38:30 -07002076 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE,
2077 pBeacon->tail, pBeacon->tail_len);
2078
2079 if(pIe && pIe[1] && (pIe[0] == DOT11F_EID_WPA))
2080 {
2081 if (pConfig->pRSNWPAReqIE)
2082 {
2083 /*Mixed mode WPA/WPA2*/
2084 memcpy((&wpaRsnIEdata[0] + pConfig->RSNWPAReqIELength), pIe, pIe[1] + 2);
2085 pConfig->RSNWPAReqIELength += pIe[1] + 2;
2086 }
2087 else
2088 {
2089 pConfig->RSNWPAReqIELength = pIe[1] + 2;
2090 memcpy(&wpaRsnIEdata[0], pIe, pConfig->RSNWPAReqIELength);
2091 pConfig->pRSNWPAReqIE = &wpaRsnIEdata[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302092 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -07002093 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
2094 &RSNEncryptType,
2095 &mcRSNEncryptType,
2096 &RSNAuthType,
Chet Lanctot8cecea22014-02-11 19:09:36 -08002097 &MFPCapable,
2098 &MFPRequired,
Jeff Johnson295189b2012-06-20 16:38:30 -07002099 pConfig->pRSNWPAReqIE[1]+2,
2100 pConfig->pRSNWPAReqIE );
2101
2102 if( VOS_STATUS_SUCCESS == status )
2103 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302104 /* Now copy over all the security attributes you have
2105 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -07002106 * */
2107 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
2108 pConfig->mcRSNEncryptType = mcRSNEncryptType;
2109 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
2110 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05302111 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -08002112 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -07002113 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
2114 }
2115 }
2116 }
2117
Jeff Johnson4416a782013-03-25 14:17:50 -07002118 if (pConfig->RSNWPAReqIELength > sizeof wpaRsnIEdata) {
2119 hddLog( VOS_TRACE_LEVEL_ERROR, "**RSNWPAReqIELength is too large***");
2120 return -EINVAL;
2121 }
2122
Jeff Johnson295189b2012-06-20 16:38:30 -07002123 pConfig->SSIDinfo.ssidHidden = VOS_FALSE;
2124
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002125#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07002126 if (params->ssid != NULL)
2127 {
2128 memcpy(pConfig->SSIDinfo.ssid.ssId, params->ssid, params->ssid_len);
2129 pConfig->SSIDinfo.ssid.length = params->ssid_len;
2130 if (params->hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
2131 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
2132 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002133#else
2134 if (ssid != NULL)
2135 {
2136 memcpy(pConfig->SSIDinfo.ssid.ssId, ssid, ssid_len);
2137 pConfig->SSIDinfo.ssid.length = ssid_len;
2138 if (hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
2139 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
2140 }
2141#endif
2142
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302143 vos_mem_copy(pConfig->self_macaddr.bytes,
Jeff Johnson295189b2012-06-20 16:38:30 -07002144 pHostapdAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302145
Jeff Johnson295189b2012-06-20 16:38:30 -07002146 /* default value */
2147 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
2148 pConfig->num_accept_mac = 0;
2149 pConfig->num_deny_mac = 0;
2150
2151 pIe = wlan_hdd_get_vendor_oui_ie_ptr(BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
2152 pBeacon->tail, pBeacon->tail_len);
2153
2154 /* pIe for black list is following form:
2155 type : 1 byte
2156 length : 1 byte
2157 OUI : 4 bytes
2158 acl type : 1 byte
2159 no of mac addr in black list: 1 byte
2160 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302161 */
2162 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07002163 {
2164 pConfig->SapMacaddr_acl = pIe[6];
2165 pConfig->num_deny_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -08002166 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no deny mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07002167 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05302168 if (pConfig->num_deny_mac > MAX_ACL_MAC_ADDRESS)
2169 pConfig->num_deny_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07002170 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
2171 for (i = 0; i < pConfig->num_deny_mac; i++)
2172 {
2173 vos_mem_copy(&pConfig->deny_mac[i], acl_entry->addr, sizeof(qcmacaddr));
2174 acl_entry++;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302175 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002176 }
2177 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
2178 pBeacon->tail, pBeacon->tail_len);
2179
2180 /* pIe for white list is following form:
2181 type : 1 byte
2182 length : 1 byte
2183 OUI : 4 bytes
2184 acl type : 1 byte
2185 no of mac addr in white list: 1 byte
2186 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302187 */
2188 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07002189 {
2190 pConfig->SapMacaddr_acl = pIe[6];
2191 pConfig->num_accept_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -08002192 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no accept mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07002193 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05302194 if (pConfig->num_accept_mac > MAX_ACL_MAC_ADDRESS)
2195 pConfig->num_accept_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07002196 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
2197 for (i = 0; i < pConfig->num_accept_mac; i++)
2198 {
2199 vos_mem_copy(&pConfig->accept_mac[i], acl_entry->addr, sizeof(qcmacaddr));
2200 acl_entry++;
2201 }
2202 }
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05302203
Jeff Johnson295189b2012-06-20 16:38:30 -07002204 wlan_hdd_set_sapHwmode(pHostapdAdapter);
2205
Jeff Johnsone7245742012-09-05 17:12:55 -07002206#ifdef WLAN_FEATURE_11AC
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -08002207 /* Overwrite the hostapd setting for HW mode only for 11ac.
Kiet Lam0f320422013-11-21 19:29:17 +05302208 * This is valid only if mode is set to 11n in hostapd, either AUTO or
2209 * 11ac in .ini and 11ac is supported by both host and firmware.
2210 * Otherwise, leave whatever is set in hostapd (a OR b OR g OR n mode)
2211 */
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -08002212 if( ((pConfig->SapHw_mode == eSAP_DOT11_MODE_11n) ||
2213 (pConfig->SapHw_mode == eSAP_DOT11_MODE_11n_ONLY)) &&
Abhishek Singhf0ac1752014-03-05 17:47:09 +05302214 (( sapDot11Mode == eHDD_DOT11_MODE_AUTO ) ||
2215 ( sapDot11Mode == eHDD_DOT11_MODE_11ac ) ||
2216 ( sapDot11Mode == eHDD_DOT11_MODE_11ac_ONLY ) ) &&
2217 (sme_IsFeatureSupportedByDriver(DOT11AC)) &&
2218 (sme_IsFeatureSupportedByFW(DOT11AC)) )
Jeff Johnsone7245742012-09-05 17:12:55 -07002219 {
Siddharth Bhalf42f8592014-05-15 13:39:07 +05302220 v_U32_t operatingBand = 0;
Jeff Johnsone7245742012-09-05 17:12:55 -07002221 pConfig->SapHw_mode = eSAP_DOT11_MODE_11ac;
Siddharth Bhalf42f8592014-05-15 13:39:07 +05302222 ccmCfgGetInt(hHal, WNI_CFG_SAP_CHANNEL_SELECT_OPERATING_BAND, &operatingBand);
Ravi Joshi83bfaa12013-05-28 22:12:08 -07002223
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05302224 /* If ACS disable and selected channel <= 14
2225 * OR
2226 * ACS enabled and ACS operating band is choosen as 2.4
2227 * AND
2228 * VHT in 2.4G Disabled
2229 * THEN
2230 * Fallback to 11N mode
2231 */
2232 if (((AUTO_CHANNEL_SELECT != pConfig->channel && pConfig->channel <= SIR_11B_CHANNEL_END)
2233 || (AUTO_CHANNEL_SELECT == pConfig->channel &&
Siddharth Bhalf42f8592014-05-15 13:39:07 +05302234 operatingBand == RF_SUBBAND_2_4_GHZ)) &&
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05302235 iniConfig->enableVhtFor24GHzBand == FALSE)
Ravi Joshi83bfaa12013-05-28 22:12:08 -07002236 {
Siddharth Bhalf42f8592014-05-15 13:39:07 +05302237 hddLog(LOGW, FL("Setting hwmode to 11n, operatingBand = %d, Channel = %d"),
2238 operatingBand, pConfig->channel);
Ravi Joshi83bfaa12013-05-28 22:12:08 -07002239 pConfig->SapHw_mode = eSAP_DOT11_MODE_11n;
2240 }
Jeff Johnsone7245742012-09-05 17:12:55 -07002241 }
2242#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302243
Ravi Joshiaeb7d9e2013-05-02 12:28:14 -07002244 if ( AUTO_CHANNEL_SELECT != pConfig->channel )
2245 {
2246 sme_SelectCBMode(hHal,
2247 sapConvertSapPhyModeToCsrPhyMode(pConfig->SapHw_mode),
2248 pConfig->channel);
2249 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002250 // ht_capab is not what the name conveys,this is used for protection bitmap
2251 pConfig->ht_capab =
2252 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtection;
2253
2254 if ( 0 != wlan_hdd_cfg80211_update_apies(pHostapdAdapter, params) )
2255 {
2256 hddLog(LOGE, FL("SAP Not able to set AP IEs"));
2257 return -EINVAL;
2258 }
2259
2260 //Uapsd Enabled Bit
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302261 pConfig->UapsdEnable =
Jeff Johnson295189b2012-06-20 16:38:30 -07002262 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apUapsdEnabled;
2263 //Enable OBSS protection
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302264 pConfig->obssProtEnabled =
2265 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apOBSSProtEnabled;
Jeff Johnson295189b2012-06-20 16:38:30 -07002266
Chet Lanctot8cecea22014-02-11 19:09:36 -08002267#ifdef WLAN_FEATURE_11W
2268 pConfig->mfpCapable = MFPCapable;
2269 pConfig->mfpRequired = MFPRequired;
2270 hddLog(LOGW, FL("Soft AP MFP capable %d, MFP required %d\n"),
2271 pConfig->mfpCapable, pConfig->mfpRequired);
2272#endif
2273
Arif Hussain6d2a3322013-11-17 19:50:10 -08002274 hddLog(LOGW, FL("SOftAP macaddress : "MAC_ADDRESS_STR),
Jeff Johnson295189b2012-06-20 16:38:30 -07002275 MAC_ADDR_ARRAY(pHostapdAdapter->macAddressCurrent.bytes));
Arif Hussain6d2a3322013-11-17 19:50:10 -08002276 hddLog(LOGW,FL("ssid =%s, beaconint=%d, channel=%d"),
2277 pConfig->SSIDinfo.ssid.ssId, (int)pConfig->beacon_int,
2278 (int)pConfig->channel);
2279 hddLog(LOGW,FL("hw_mode=%x, privacy=%d, authType=%d"),
2280 pConfig->SapHw_mode, pConfig->privacy,
2281 pConfig->authType);
2282 hddLog(LOGW,FL("RSN/WPALen=%d, Uapsd = %d"),
2283 (int)pConfig->RSNWPAReqIELength, pConfig->UapsdEnable);
2284 hddLog(LOGW,FL("ProtEnabled = %d, OBSSProtEnabled = %d"),
2285 pConfig->protEnabled, pConfig->obssProtEnabled);
Jeff Johnson295189b2012-06-20 16:38:30 -07002286
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302287 if(test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -07002288 {
2289 //Bss already started. just return.
2290 //TODO Probably it should update some beacon params.
2291 hddLog( LOGE, "Bss Already started...Ignore the request");
2292 EXIT();
2293 return 0;
2294 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302295
Jeff Johnson295189b2012-06-20 16:38:30 -07002296 pConfig->persona = pHostapdAdapter->device_mode;
2297
2298 pSapEventCallback = hdd_hostapd_SAPEventCB;
2299 if(WLANSAP_StartBss(pVosContext, pSapEventCallback, pConfig,
2300 (v_PVOID_t)pHostapdAdapter->dev) != VOS_STATUS_SUCCESS)
2301 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08002302 hddLog(LOGE,FL("SAP Start Bss fail"));
Jeff Johnson295189b2012-06-20 16:38:30 -07002303 return -EINVAL;
2304 }
2305
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302306 hddLog(LOG1,
Jeff Johnson295189b2012-06-20 16:38:30 -07002307 FL("Waiting for Scan to complete(auto mode) and BSS to start"));
2308
2309 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302310
Jeff Johnson295189b2012-06-20 16:38:30 -07002311 if (!VOS_IS_STATUS_SUCCESS(status))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302312 {
2313 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08002314 ("ERROR: HDD vos wait for single_event failed!!"));
Tushnim Bhattacharyyaad37df12013-10-02 12:01:33 -07002315 smeGetCommandQStatus(hHal);
Jeff Johnson295189b2012-06-20 16:38:30 -07002316 VOS_ASSERT(0);
2317 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302318
Jeff Johnson295189b2012-06-20 16:38:30 -07002319 set_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags);
2320
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07002321#ifdef WLAN_FEATURE_P2P_DEBUG
2322 if (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO)
2323 {
2324 if(globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED)
2325 {
2326 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
2327 hddLog(LOGE,"[P2P State] From Go nego completed to "
Jeff Johnson1250df42012-12-10 14:31:52 -08002328 "Non-autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07002329 }
2330 else if(globalP2PConnectionStatus == P2P_NOT_ACTIVE)
2331 {
2332 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
2333 hddLog(LOGE,"[P2P State] From Inactive to "
Jeff Johnson1250df42012-12-10 14:31:52 -08002334 "Autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07002335 }
2336 }
2337#endif
2338
Jeff Johnson295189b2012-06-20 16:38:30 -07002339 pHostapdState->bCommit = TRUE;
2340 EXIT();
2341
2342 return 0;
2343}
2344
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002345#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302346static int wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy,
2347 struct net_device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -07002348 struct beacon_parameters *params)
2349{
2350 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302351 hdd_context_t *pHddCtx;
2352 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07002353
2354 ENTER();
2355
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302356 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2357 TRACE_CODE_HDD_CFG80211_ADD_BEACON,
2358 pAdapter->sessionId, params->interval));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05302359 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "device mode=%s (%d)",
2360 hdd_device_modetoString(pAdapter->device_mode),
2361 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07002362
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302363 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2364 status = wlan_hdd_validate_context(pHddCtx);
2365
2366 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002367 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302368 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2369 "%s: HDD context is not valid", __func__);
2370 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002371 }
2372
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302373 if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07002374 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07002375 )
2376 {
2377 beacon_data_t *old,*new;
2378
2379 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302380
Jeff Johnson295189b2012-06-20 16:38:30 -07002381 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302382 {
2383 hddLog(VOS_TRACE_LEVEL_WARN,
2384 FL("already beacon info added to session(%d)"),
2385 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07002386 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302387 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002388
2389 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
2390
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302391 if(status != VOS_STATUS_SUCCESS)
Jeff Johnson295189b2012-06-20 16:38:30 -07002392 {
2393 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08002394 "%s:Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002395 return -EINVAL;
2396 }
2397
2398 pAdapter->sessionCtx.ap.beacon = new;
2399
2400 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
2401 }
2402
2403 EXIT();
2404 return status;
2405}
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302406
2407static int wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07002408 struct net_device *dev,
2409 struct beacon_parameters *params)
2410{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302411 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302412 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302413 hdd_context_t *pHddCtx;
2414 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07002415
2416 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302417 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2418 TRACE_CODE_HDD_CFG80211_SET_BEACON,
2419 pAdapter->sessionId, pHddStaCtx->conn_info.authType));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05302420 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
2421 __func__, hdd_device_modetoString(pAdapter->device_mode),
2422 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07002423
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302424 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2425 status = wlan_hdd_validate_context(pHddCtx);
2426
2427 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002428 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302429 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2430 "%s: HDD context is not valid", __func__);
2431 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002432 }
2433
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302434 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07002435 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302436 )
Jeff Johnson295189b2012-06-20 16:38:30 -07002437 {
2438 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302439
Jeff Johnson295189b2012-06-20 16:38:30 -07002440 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302441
Jeff Johnson295189b2012-06-20 16:38:30 -07002442 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302443 {
2444 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2445 FL("session(%d) old and new heads points to NULL"),
2446 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07002447 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302448 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002449
2450 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
2451
2452 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302453 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08002454 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002455 return -EINVAL;
2456 }
2457
2458 pAdapter->sessionCtx.ap.beacon = new;
2459
2460 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
2461 }
2462
2463 EXIT();
2464 return status;
2465}
2466
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002467#endif //(LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
2468
2469#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07002470static int wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy,
2471 struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002472#else
2473static int wlan_hdd_cfg80211_stop_ap (struct wiphy *wiphy,
2474 struct net_device *dev)
2475#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07002476{
2477 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnsone7245742012-09-05 17:12:55 -07002478 hdd_context_t *pHddCtx = NULL;
2479 hdd_scaninfo_t *pScanInfo = NULL;
2480 hdd_adapter_t *staAdapter = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302481 VOS_STATUS status;
Jeff Johnson295189b2012-06-20 16:38:30 -07002482
2483 ENTER();
2484
2485 if (NULL == pAdapter)
2486 {
2487 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002488 "%s: HDD adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002489 return -ENODEV;
2490 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07002491
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302492 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2493 TRACE_CODE_HDD_CFG80211_STOP_AP,
2494 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302495 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2496 status = wlan_hdd_validate_context(pHddCtx);
2497
2498 if (0 != status)
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07002499 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302500 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2501 "%s: HDD context is not valid", __func__);
2502 return status;
Jeff Johnson4416a782013-03-25 14:17:50 -07002503 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07002504
2505 staAdapter = hdd_get_adapter(pAdapter->pHddCtx, WLAN_HDD_INFRA_STATION);
2506 if (NULL == staAdapter)
2507 {
2508 staAdapter = hdd_get_adapter(pAdapter->pHddCtx, WLAN_HDD_P2P_CLIENT);
2509 if (NULL == staAdapter)
2510 {
Rajesh Chauhan52d885b2013-11-01 10:54:25 -07002511 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
2512 "%s: HDD adapter context for STA/P2P-CLI is Null",
2513 __func__);
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07002514 }
2515 }
2516
2517 pScanInfo = &pHddCtx->scan_info;
2518
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05302519 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
2520 __func__, hdd_device_modetoString(pAdapter->device_mode),
2521 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07002522
Rajesh Chauhan52d885b2013-11-01 10:54:25 -07002523 if ((pScanInfo != NULL) && pScanInfo->mScanPending && staAdapter)
Jeff Johnsone7245742012-09-05 17:12:55 -07002524 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302525 long ret;
2526
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -08002527 INIT_COMPLETION(pScanInfo->abortscan_event_var);
Srinivas, Dasari138af4f2014-02-07 11:13:45 +05302528 hdd_abort_mac_scan(staAdapter->pHddCtx, pAdapter->sessionId,
2529 eCSR_SCAN_ABORT_DEFAULT);
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302530 ret = wait_for_completion_interruptible_timeout(
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -08002531 &pScanInfo->abortscan_event_var,
Jeff Johnsone7245742012-09-05 17:12:55 -07002532 msecs_to_jiffies(WLAN_WAIT_TIME_ABORTSCAN));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302533 if (ret <= 0)
Jeff Johnsone7245742012-09-05 17:12:55 -07002534 {
Rajesh Chauhan52d885b2013-11-01 10:54:25 -07002535 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302536 FL("Timeout occurred while waiting for abortscan %ld"),
2537 ret);
Yue Ma4f55ef32014-01-23 16:45:33 -08002538
2539 if (pHddCtx->isLogpInProgress)
2540 {
2541 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2542 "%s: LOGP in Progress. Ignore!!!", __func__);
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302543
2544 VOS_ASSERT(pScanInfo->mScanPending);
Yue Ma4f55ef32014-01-23 16:45:33 -08002545 return -EAGAIN;
2546 }
Jeff Johnsone7245742012-09-05 17:12:55 -07002547 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -07002548 }
2549 }
2550
Arun Kumar Khandavallia3bd8002014-01-17 16:21:19 +05302551 hdd_hostapd_stop(dev);
2552
Jeff Johnson295189b2012-06-20 16:38:30 -07002553 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07002554 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07002555 )
2556 {
2557 beacon_data_t *old;
2558
2559 old = pAdapter->sessionCtx.ap.beacon;
2560
2561 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302562 {
2563 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2564 FL("session(%d) beacon data points to NULL"),
2565 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07002566 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302567 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002568
Jeff Johnson295189b2012-06-20 16:38:30 -07002569 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07002570
2571 mutex_lock(&pHddCtx->sap_lock);
2572 if(test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
2573 {
Jeff Johnson4416a782013-03-25 14:17:50 -07002574 if ( VOS_STATUS_SUCCESS == (status = WLANSAP_StopBss(pHddCtx->pvosContext) ) )
Jeff Johnson295189b2012-06-20 16:38:30 -07002575 {
2576 hdd_hostapd_state_t *pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
2577
2578 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
2579
2580 if (!VOS_IS_STATUS_SUCCESS(status))
2581 {
2582 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08002583 ("ERROR: HDD vos wait for single_event failed!!"));
Jeff Johnson295189b2012-06-20 16:38:30 -07002584 VOS_ASSERT(0);
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302585 }
2586 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002587 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
2588 }
2589 mutex_unlock(&pHddCtx->sap_lock);
2590
2591 if(status != VOS_STATUS_SUCCESS)
2592 {
2593 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08002594 "%s:Error!!! Stopping the BSS",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002595 return -EINVAL;
2596 }
2597
Jeff Johnson4416a782013-03-25 14:17:50 -07002598 if (ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -07002599 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 0,NULL, eANI_BOOLEAN_FALSE)
2600 ==eHAL_STATUS_FAILURE)
2601 {
2602 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08002603 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07002604 }
2605
Jeff Johnson4416a782013-03-25 14:17:50 -07002606 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -07002607 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
2608 eANI_BOOLEAN_FALSE) )
2609 {
2610 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08002611 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07002612 }
2613
2614 // Reset WNI_CFG_PROBE_RSP Flags
2615 wlan_hdd_reset_prob_rspies(pAdapter);
2616
2617 pAdapter->sessionCtx.ap.beacon = NULL;
2618 kfree(old);
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07002619#ifdef WLAN_FEATURE_P2P_DEBUG
2620 if((pAdapter->device_mode == WLAN_HDD_P2P_GO) &&
2621 (globalP2PConnectionStatus == P2P_GO_COMPLETED_STATE))
2622 {
2623 hddLog(LOGE,"[P2P State] From GO completed to Inactive state "
2624 "GO got removed");
2625 globalP2PConnectionStatus = P2P_NOT_ACTIVE;
2626 }
2627#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07002628 }
2629 EXIT();
2630 return status;
2631}
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002632
2633#if (LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
2634
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302635static int wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
2636 struct net_device *dev,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002637 struct cfg80211_ap_settings *params)
2638{
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302639 hdd_adapter_t *pAdapter;
2640 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302641 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002642
2643 ENTER();
2644
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302645 if (NULL == dev)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07002646 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302647 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302648 "%s: Device is Null", __func__);
2649 return -ENODEV;
2650 }
2651
2652 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2653 if (NULL == pAdapter)
2654 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302655 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302656 "%s: HDD adapter is Null", __func__);
2657 return -ENODEV;
2658 }
2659
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302660 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2661 TRACE_CODE_HDD_CFG80211_START_AP, pAdapter->sessionId,
2662 params-> beacon_interval));
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302663 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
2664 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302665 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302666 "%s: HDD adapter magic is invalid", __func__);
2667 return -ENODEV;
2668 }
2669
2670 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302671 status = wlan_hdd_validate_context(pHddCtx);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302672
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302673 if (0 != status)
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302674 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302675 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2676 "%s: HDD context is not valid", __func__);
2677 return status;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302678 }
2679
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05302680 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device mode = %s (%d)",
2681 __func__, hdd_device_modetoString(pAdapter->device_mode),
2682 pAdapter->device_mode);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302683
2684 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002685 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002686 )
2687 {
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302688 beacon_data_t *old, *new;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002689
2690 old = pAdapter->sessionCtx.ap.beacon;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302691
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002692 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302693 {
2694 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
2695 FL("already beacon info added to session(%d)"),
2696 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002697 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302698 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002699
2700 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter, &new, &params->beacon, params->dtim_period);
2701
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302702 if (status != 0)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002703 {
2704 hddLog(VOS_TRACE_LEVEL_FATAL,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302705 "%s:Error!!! Allocating the new beacon", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002706 return -EINVAL;
2707 }
2708 pAdapter->sessionCtx.ap.beacon = new;
Viral Modi3a32cc52013-02-08 11:14:52 -08002709#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
Yue Maf49ba872013-08-19 12:04:25 -07002710 wlan_hdd_cfg80211_set_channel(wiphy, dev,
2711#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
2712 params->channel, params->channel_type);
2713#else
2714 params->chandef.chan, cfg80211_get_chandef_type(&(params->chandef)));
2715#endif
Viral Modi3a32cc52013-02-08 11:14:52 -08002716#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002717 status = wlan_hdd_cfg80211_start_bss(pAdapter, &params->beacon, params->ssid,
2718 params->ssid_len, params->hidden_ssid);
2719 }
2720
2721 EXIT();
2722 return status;
2723}
2724
2725
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302726static int wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002727 struct net_device *dev,
2728 struct cfg80211_beacon_data *params)
2729{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302730 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302731 hdd_context_t *pHddCtx;
2732 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002733
2734 ENTER();
2735
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302736 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2737 TRACE_CODE_HDD_CFG80211_CHANGE_BEACON,
2738 pAdapter->sessionId, pAdapter->device_mode));
Arif Hussain6d2a3322013-11-17 19:50:10 -08002739 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002740 __func__, pAdapter->device_mode);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302741
2742 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2743 status = wlan_hdd_validate_context(pHddCtx);
2744
2745 if (0 != status)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07002746 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302747 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2748 "%s: HDD context is not valid", __func__);
2749 return status;
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07002750 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002751
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302752 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002753 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302754 )
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002755 {
2756 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302757
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002758 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302759
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002760 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302761 {
2762 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2763 FL("session(%d) beacon data points to NULL"),
2764 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002765 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302766 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002767
2768 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter, &new, params, 0);
2769
2770 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302771 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08002772 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002773 return -EINVAL;
2774 }
2775
2776 pAdapter->sessionCtx.ap.beacon = new;
2777
2778 status = wlan_hdd_cfg80211_start_bss(pAdapter, params, NULL, 0, 0);
2779 }
2780
2781 EXIT();
2782 return status;
2783}
2784
2785#endif //(LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
2786
Jeff Johnson295189b2012-06-20 16:38:30 -07002787
2788static int wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
2789 struct net_device *dev,
2790 struct bss_parameters *params)
2791{
2792 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2793
2794 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302795
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302796 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2797 TRACE_CODE_HDD_CFG80211_CHANGE_BSS,
2798 pAdapter->sessionId, params->ap_isolate));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05302799 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
2800 __func__, hdd_device_modetoString(pAdapter->device_mode),
2801 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07002802
2803 if((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07002804 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302805 )
Jeff Johnson295189b2012-06-20 16:38:30 -07002806 {
2807 /* ap_isolate == -1 means that in change bss, upper layer doesn't
2808 * want to update this parameter */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302809 if (-1 != params->ap_isolate)
Jeff Johnson295189b2012-06-20 16:38:30 -07002810 {
2811 pAdapter->sessionCtx.ap.apDisableIntraBssFwd = !!params->ap_isolate;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302812 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002813 }
2814
2815 EXIT();
2816 return 0;
2817}
2818
Kiet Lam10841362013-11-01 11:36:50 +05302819/* FUNCTION: wlan_hdd_change_country_code_cd
2820* to wait for contry code completion
2821*/
2822void* wlan_hdd_change_country_code_cb(void *pAdapter)
2823{
2824 hdd_adapter_t *call_back_pAdapter = pAdapter;
2825 complete(&call_back_pAdapter->change_country_code);
2826 return NULL;
2827}
2828
Jeff Johnson295189b2012-06-20 16:38:30 -07002829/*
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +05302830 * FUNCTION: __wlan_hdd_cfg80211_change_iface
Jeff Johnson295189b2012-06-20 16:38:30 -07002831 * This function is used to set the interface type (INFRASTRUCTURE/ADHOC)
2832 */
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +05302833int __wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07002834 struct net_device *ndev,
2835 enum nl80211_iftype type,
2836 u32 *flags,
2837 struct vif_params *params
2838 )
2839{
2840 struct wireless_dev *wdev;
2841 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Rajesh Chauhana0516c62014-01-30 16:11:18 -08002842 hdd_context_t *pHddCtx;
Mohit Khanna0f232092012-09-11 14:46:08 -07002843 hdd_adapter_t *pP2pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07002844 tCsrRoamProfile *pRoamProfile = NULL;
2845 eCsrRoamBssType LastBSSType;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302846 hdd_config_t *pConfig = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07002847 eMib_dot11DesiredBssType connectedBssType;
2848 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302849 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07002850
2851 ENTER();
2852
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302853 if (!pAdapter)
Rajesh Chauhana0516c62014-01-30 16:11:18 -08002854 {
2855 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2856 "%s: Adapter context is null", __func__);
2857 return VOS_STATUS_E_FAILURE;
2858 }
2859
2860 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2861 if (!pHddCtx)
2862 {
2863 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2864 "%s: HDD context is null", __func__);
2865 return VOS_STATUS_E_FAILURE;
2866 }
2867
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302868 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2869 TRACE_CODE_HDD_CFG80211_CHANGE_IFACE,
2870 pAdapter->sessionId, type));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302871 status = wlan_hdd_validate_context(pHddCtx);
2872
2873 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -07002874 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302875 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2876 "%s: HDD context is not valid", __func__);
2877 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -07002878 }
2879
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05302880 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
2881 __func__, hdd_device_modetoString(pAdapter->device_mode),
2882 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07002883
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302884 pConfig = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -07002885 wdev = ndev->ieee80211_ptr;
2886
2887#ifdef WLAN_BTAMP_FEATURE
2888 if((NL80211_IFTYPE_P2P_CLIENT == type)||
2889 (NL80211_IFTYPE_ADHOC == type)||
2890 (NL80211_IFTYPE_AP == type)||
2891 (NL80211_IFTYPE_P2P_GO == type))
2892 {
2893 pHddCtx->isAmpAllowed = VOS_FALSE;
2894 // stop AMP traffic
2895 status = WLANBAP_StopAmp();
2896 if(VOS_STATUS_SUCCESS != status )
2897 {
2898 pHddCtx->isAmpAllowed = VOS_TRUE;
2899 hddLog(VOS_TRACE_LEVEL_FATAL,
2900 "%s: Failed to stop AMP", __func__);
2901 return -EINVAL;
2902 }
2903 }
2904#endif //WLAN_BTAMP_FEATURE
2905 /* Reset the current device mode bit mask*/
2906 wlan_hdd_clear_concurrency_mode(pHddCtx, pAdapter->device_mode);
2907
2908 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -07002909 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnsone7245742012-09-05 17:12:55 -07002910 || (pAdapter->device_mode == WLAN_HDD_P2P_DEVICE)
Jeff Johnson295189b2012-06-20 16:38:30 -07002911 )
2912 {
2913 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -08002914 if (!pWextState)
2915 {
2916 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2917 "%s: pWextState is null", __func__);
2918 return VOS_STATUS_E_FAILURE;
2919 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002920 pRoamProfile = &pWextState->roamProfile;
2921 LastBSSType = pRoamProfile->BSSType;
2922
2923 switch (type)
2924 {
2925 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -07002926 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -07002927 hddLog(VOS_TRACE_LEVEL_INFO,
2928 "%s: setting interface Type to INFRASTRUCTURE", __func__);
2929 pRoamProfile->BSSType = eCSR_BSS_TYPE_INFRASTRUCTURE;
Jeff Johnsone7245742012-09-05 17:12:55 -07002930#ifdef WLAN_FEATURE_11AC
2931 if(pConfig->dot11Mode == eHDD_DOT11_MODE_AUTO)
2932 {
2933 pConfig->dot11Mode = eHDD_DOT11_MODE_11ac;
2934 }
2935#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302936 pRoamProfile->phyMode =
Jeff Johnsone7245742012-09-05 17:12:55 -07002937 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07002938 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08002939 //Check for sub-string p2p to confirm its a p2p interface
2940 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302941 {
Gopichand Nakkala864d3552012-12-31 16:08:51 -08002942 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
2943 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
2944 }
2945 else
2946 {
2947 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -07002948 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -08002949 }
Madan Mohan Koyyalamudi81746922013-07-17 14:38:51 +05302950#ifdef FEATURE_WLAN_TDLS
2951 /* The open adapter for the p2p shall skip initializations in
2952 * tdls_init if the device mode is WLAN_HDD_P2P_DEVICE, for
2953 * TDLS is supported only on WLAN_HDD_P2P_CLIENT. Hence invoke
2954 * tdls_init when the change_iface sets the device mode to
2955 * WLAN_HDD_P2P_CLIENT.
2956 */
2957
2958 if ( pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
2959 {
2960 if (0 != wlan_hdd_tdls_init (pAdapter))
2961 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302962 hddLog(VOS_TRACE_LEVEL_ERROR,
2963 "%s: tdls initialization failed", __func__);
Madan Mohan Koyyalamudi81746922013-07-17 14:38:51 +05302964 return -EINVAL;
2965 }
2966 }
2967#endif
2968
Jeff Johnson295189b2012-06-20 16:38:30 -07002969 break;
2970 case NL80211_IFTYPE_ADHOC:
2971 hddLog(VOS_TRACE_LEVEL_INFO,
2972 "%s: setting interface Type to ADHOC", __func__);
2973 pRoamProfile->BSSType = eCSR_BSS_TYPE_START_IBSS;
2974 pRoamProfile->phyMode =
2975 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Shailender Karmuchia734f332013-04-19 14:02:48 -07002976 pAdapter->device_mode = WLAN_HDD_IBSS;
Jeff Johnson295189b2012-06-20 16:38:30 -07002977 wdev->iftype = type;
2978 break;
2979
2980 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -07002981 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07002982 {
2983 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
2984 "%s: setting interface Type to %s", __func__,
2985 (type == NL80211_IFTYPE_AP) ? "SoftAP" : "P2pGo");
2986
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08002987 //Cancel any remain on channel for GO mode
2988 if (NL80211_IFTYPE_P2P_GO == type)
2989 {
2990 wlan_hdd_cancel_existing_remain_on_channel(pAdapter);
2991 }
Mohit Khanna0f232092012-09-11 14:46:08 -07002992 if (NL80211_IFTYPE_AP == type)
2993 {
2994 /* As Loading WLAN Driver one interface being created for p2p device
2995 * address. This will take one HW STA and the max number of clients
2996 * that can connect to softAP will be reduced by one. so while changing
2997 * the interface type to NL80211_IFTYPE_AP (SoftAP) remove p2p0
2998 * interface as it is not required in SoftAP mode.
2999 */
3000
3001 // Get P2P Adapter
3002 pP2pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_DEVICE);
3003
3004 if (pP2pAdapter)
3005 {
3006 hdd_stop_adapter(pHddCtx, pP2pAdapter);
3007 hdd_deinit_adapter(pHddCtx, pP2pAdapter);
3008 hdd_close_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
3009 }
3010 }
Swaroop Goltia2e32212014-04-09 23:37:33 +05303011 //Disable IMPS & BMPS for SAP/GO
3012 if(VOS_STATUS_E_FAILURE ==
3013 hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_P2P_GO))
3014 {
3015 //Fail to Exit BMPS
3016 VOS_ASSERT(0);
3017 }
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05303018#ifdef FEATURE_WLAN_TDLS
Mohit Khanna0f232092012-09-11 14:46:08 -07003019
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05303020 /* A Mutex Lock is introduced while changing the mode to
3021 * protect the concurrent access for the Adapters by TDLS
3022 * module.
3023 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05303024 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05303025#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07003026 //De-init the adapter.
3027 hdd_stop_adapter( pHddCtx, pAdapter );
3028 hdd_deinit_adapter( pHddCtx, pAdapter );
3029 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
Jeff Johnson295189b2012-06-20 16:38:30 -07003030 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
3031 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05303032#ifdef FEATURE_WLAN_TDLS
3033 mutex_unlock(&pHddCtx->tdls_lock);
3034#endif
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -07003035 if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) &&
3036 (pConfig->apRandomBssidEnabled))
3037 {
3038 /* To meet Android requirements create a randomized
3039 MAC address of the form 02:1A:11:Fx:xx:xx */
3040 get_random_bytes(&ndev->dev_addr[3], 3);
3041 ndev->dev_addr[0] = 0x02;
3042 ndev->dev_addr[1] = 0x1A;
3043 ndev->dev_addr[2] = 0x11;
3044 ndev->dev_addr[3] |= 0xF0;
3045 memcpy(pAdapter->macAddressCurrent.bytes, ndev->dev_addr,
3046 VOS_MAC_ADDR_SIZE);
Arif Hussain24bafea2013-11-15 15:10:03 -08003047 pr_info("wlan: Generated HotSpot BSSID " MAC_ADDRESS_STR"\n",
3048 MAC_ADDR_ARRAY(ndev->dev_addr));
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -07003049 }
3050
Jeff Johnson295189b2012-06-20 16:38:30 -07003051 hdd_set_ap_ops( pAdapter->dev );
3052
Kiet Lam10841362013-11-01 11:36:50 +05303053 /* This is for only SAP mode where users can
3054 * control country through ini.
3055 * P2P GO follows station country code
3056 * acquired during the STA scanning. */
3057 if((NL80211_IFTYPE_AP == type) &&
3058 (memcmp(pConfig->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0))
3059 {
3060 int status = 0;
3061 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_INFO,
3062 "%s: setting country code from INI ", __func__);
3063 init_completion(&pAdapter->change_country_code);
3064 status = (int)sme_ChangeCountryCode(pHddCtx->hHal,
3065 (void *)(tSmeChangeCountryCallback)
3066 wlan_hdd_change_country_code_cb,
3067 pConfig->apCntryCode, pAdapter,
3068 pHddCtx->pvosContext,
Abhishek Singha306a442013-11-07 18:39:01 +05303069 eSIR_FALSE,
3070 eSIR_TRUE);
Kiet Lam10841362013-11-01 11:36:50 +05303071 if (eHAL_STATUS_SUCCESS == status)
3072 {
3073 /* Wait for completion */
c_hpothu6ff1c3c2013-10-01 19:01:57 +05303074 ret = wait_for_completion_interruptible_timeout(
Kiet Lam10841362013-11-01 11:36:50 +05303075 &pAdapter->change_country_code,
3076 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05303077 if (ret <= 0)
Kiet Lam10841362013-11-01 11:36:50 +05303078 {
3079 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05303080 FL("SME Timed out while setting country code %ld"),
3081 ret);
Yue Ma4f55ef32014-01-23 16:45:33 -08003082
3083 if (pHddCtx->isLogpInProgress)
3084 {
3085 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3086 "%s: LOGP in Progress. Ignore!!!", __func__);
3087 return -EAGAIN;
3088 }
Kiet Lam10841362013-11-01 11:36:50 +05303089 }
3090 }
3091 else
3092 {
3093 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08003094 "%s: SME Change Country code failed",__func__);
Kiet Lam10841362013-11-01 11:36:50 +05303095 return -EINVAL;
3096 }
3097 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003098 status = hdd_init_ap_mode(pAdapter);
3099 if(status != VOS_STATUS_SUCCESS)
3100 {
3101 hddLog(VOS_TRACE_LEVEL_FATAL,
3102 "%s: Error initializing the ap mode", __func__);
3103 return -EINVAL;
3104 }
3105 hdd_set_conparam(1);
3106
Jeff Johnson295189b2012-06-20 16:38:30 -07003107 /*interface type changed update in wiphy structure*/
3108 if(wdev)
3109 {
3110 wdev->iftype = type;
3111 pHddCtx->change_iface = type;
3112 }
3113 else
3114 {
3115 hddLog(VOS_TRACE_LEVEL_ERROR,
3116 "%s: ERROR !!!! Wireless dev is NULL", __func__);
3117 return -EINVAL;
3118 }
3119 goto done;
3120 }
3121
3122 default:
3123 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
3124 __func__);
3125 return -EOPNOTSUPP;
3126 }
3127 }
3128 else if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07003129 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07003130 )
3131 {
3132 switch(type)
3133 {
3134 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -07003135 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -07003136 case NL80211_IFTYPE_ADHOC:
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05303137#ifdef FEATURE_WLAN_TDLS
3138
3139 /* A Mutex Lock is introduced while changing the mode to
3140 * protect the concurrent access for the Adapters by TDLS
3141 * module.
3142 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05303143 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05303144#endif
Jeff Johnson32d95a32012-09-10 13:15:23 -07003145 hdd_stop_adapter( pHddCtx, pAdapter );
3146 hdd_deinit_adapter( pHddCtx, pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07003147 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08003148 //Check for sub-string p2p to confirm its a p2p interface
3149 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala864d3552012-12-31 16:08:51 -08003150 {
3151 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
3152 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
3153 }
3154 else
3155 {
3156 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -07003157 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -08003158 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003159 hdd_set_conparam(0);
3160 pHddCtx->change_iface = type;
Jeff Johnson295189b2012-06-20 16:38:30 -07003161 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
3162 hdd_set_station_ops( pAdapter->dev );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05303163#ifdef FEATURE_WLAN_TDLS
3164 mutex_unlock(&pHddCtx->tdls_lock);
3165#endif
Sunil Dutt66485cb2013-12-19 19:05:03 +05303166 status = hdd_init_station_mode( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07003167 if( VOS_STATUS_SUCCESS != status )
3168 return -EOPNOTSUPP;
Jeff Johnsone7245742012-09-05 17:12:55 -07003169 /* In case of JB, for P2P-GO, only change interface will be called,
3170 * This is the right place to enable back bmps_imps()
3171 */
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05303172 if (pHddCtx->hdd_wlan_suspended)
3173 {
3174 hdd_set_pwrparams(pHddCtx);
3175 }
Jeff Johnsone7245742012-09-05 17:12:55 -07003176 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07003177 goto done;
3178 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -07003179 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07003180 wdev->iftype = type;
Jeff Johnson295189b2012-06-20 16:38:30 -07003181 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
3182 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Jeff Johnson295189b2012-06-20 16:38:30 -07003183 goto done;
3184 default:
3185 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
3186 __func__);
3187 return -EOPNOTSUPP;
3188
3189 }
3190
3191 }
3192 else
3193 {
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05303194 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: unsupported device mode(%s (%d))",
3195 __func__, hdd_device_modetoString(pAdapter->device_mode),
3196 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07003197 return -EOPNOTSUPP;
3198 }
3199
3200
3201 if(pRoamProfile)
3202 {
3203 if ( LastBSSType != pRoamProfile->BSSType )
3204 {
3205 /*interface type changed update in wiphy structure*/
3206 wdev->iftype = type;
3207
3208 /*the BSS mode changed, We need to issue disconnect
3209 if connected or in IBSS disconnect state*/
3210 if ( hdd_connGetConnectedBssType(
3211 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), &connectedBssType ) ||
3212 ( eCSR_BSS_TYPE_START_IBSS == LastBSSType ) )
3213 {
3214 /*need to issue a disconnect to CSR.*/
3215 INIT_COMPLETION(pAdapter->disconnect_comp_var);
3216 if( eHAL_STATUS_SUCCESS ==
3217 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
3218 pAdapter->sessionId,
3219 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
3220 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05303221 ret = wait_for_completion_interruptible_timeout(
3222 &pAdapter->disconnect_comp_var,
3223 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
3224 if (ret <= 0)
3225 {
3226 hddLog(VOS_TRACE_LEVEL_ERROR,
3227 FL("wait on disconnect_comp_var failed %ld"), ret);
3228 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003229 }
3230 }
3231 }
3232 }
3233
3234done:
3235 /*set bitmask based on updated value*/
3236 wlan_hdd_set_concurrency_mode(pHddCtx, pAdapter->device_mode);
Leo Chang6fe1f922013-06-07 19:21:24 -07003237
3238 /* Only STA mode support TM now
3239 * all other mode, TM feature should be disabled */
3240 if ( (pHddCtx->cfg_ini->thermalMitigationEnable) &&
3241 (~VOS_STA & pHddCtx->concurrency_mode) )
3242 {
3243 hddDevTmLevelChangedHandler(pHddCtx->parent_dev, 0);
3244 }
3245
Jeff Johnson295189b2012-06-20 16:38:30 -07003246#ifdef WLAN_BTAMP_FEATURE
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303247 if((NL80211_IFTYPE_STATION == type) && (pHddCtx->concurrency_mode <= 1) &&
Jeff Johnson295189b2012-06-20 16:38:30 -07003248 (pHddCtx->no_of_sessions[WLAN_HDD_INFRA_STATION] <=1))
3249 {
3250 //we are ok to do AMP
3251 pHddCtx->isAmpAllowed = VOS_TRUE;
3252 }
3253#endif //WLAN_BTAMP_FEATURE
3254 EXIT();
3255 return 0;
3256}
3257
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +05303258/*
3259 * FUNCTION: wlan_hdd_cfg80211_change_iface
3260 * wrapper function to protect the actual implementation from SSR.
3261 */
3262int wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
3263 struct net_device *ndev,
3264 enum nl80211_iftype type,
3265 u32 *flags,
3266 struct vif_params *params
3267 )
3268{
3269 int ret;
3270
3271 vos_ssr_protect(__func__);
3272 ret = __wlan_hdd_cfg80211_change_iface(wiphy, ndev, type, flags, params);
3273 vos_ssr_unprotect(__func__);
3274
3275 return ret;
3276}
3277
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003278#ifdef FEATURE_WLAN_TDLS
3279static int wlan_hdd_tdls_add_station(struct wiphy *wiphy,
3280 struct net_device *dev, u8 *mac, bool update, tCsrStaParams *StaParams)
3281{
3282 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3283 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3284 VOS_STATUS status;
Hoonki Lee5305c3a2013-04-29 23:28:59 -07003285 hddTdlsPeer_t *pTdlsPeer;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05303286 long ret;
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05303287 tANI_U16 numCurrTdlsPeers;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003288
3289 ENTER();
3290
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05303291 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003292 {
3293 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3294 "Invalid arguments");
3295 return -EINVAL;
3296 }
Hoonki Lee27511902013-03-14 18:19:06 -07003297
3298 if ((eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode) ||
3299 (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode))
3300 {
3301 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
3302 "%s: TDLS mode is disabled OR not enabled in FW."
3303 MAC_ADDRESS_STR " Request declined.",
3304 __func__, MAC_ADDR_ARRAY(mac));
3305 return -ENOTSUPP;
3306 }
3307
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003308 if (pHddCtx->isLogpInProgress)
3309 {
3310 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3311 "%s:LOGP in Progress. Ignore!!!", __func__);
Gopichand Nakkala05922802013-03-14 12:23:19 -07003312 wlan_hdd_tdls_set_link_status(pAdapter, mac, eTDLS_LINK_IDLE);
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003313 return -EBUSY;
3314 }
3315
Naresh Jayaram9c6f4462014-02-13 12:20:31 +05303316 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, mac);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07003317
3318 if ( NULL == pTdlsPeer ) {
3319 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
3320 "%s: " MAC_ADDRESS_STR " (update %d) not exist. return invalid",
3321 __func__, MAC_ADDR_ARRAY(mac), update);
3322 return -EINVAL;
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07003323 }
Hoonki Lee5305c3a2013-04-29 23:28:59 -07003324
3325 /* in add station, we accept existing valid staId if there is */
3326 if ((0 == update) &&
3327 ((pTdlsPeer->link_status >= eTDLS_LINK_CONNECTING) ||
3328 (TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003329 {
Hoonki Lee5305c3a2013-04-29 23:28:59 -07003330 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003331 "%s: " MAC_ADDRESS_STR
Hoonki Lee5305c3a2013-04-29 23:28:59 -07003332 " link_status %d. staId %d. add station ignored.",
3333 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, pTdlsPeer->staId);
3334 return 0;
3335 }
3336 /* in change station, we accept only when staId is valid */
3337 if ((1 == update) &&
3338 ((pTdlsPeer->link_status > eTDLS_LINK_CONNECTING) ||
3339 (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
3340 {
3341 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
3342 "%s: " MAC_ADDRESS_STR
3343 " link status %d. staId %d. change station %s.",
3344 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, pTdlsPeer->staId,
3345 (TDLS_STA_INDEX_VALID(pTdlsPeer->staId)) ? "ignored" : "declined");
3346 return (TDLS_STA_INDEX_VALID(pTdlsPeer->staId)) ? 0 : -EPERM;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003347 }
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07003348
3349 /* when others are on-going, we want to change link_status to idle */
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05303350 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, mac, TRUE))
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003351 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07003352 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3353 "%s: " MAC_ADDRESS_STR
3354 " TDLS setup is ongoing. Request declined.",
3355 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala05922802013-03-14 12:23:19 -07003356 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003357 }
3358
3359 /* first to check if we reached to maximum supported TDLS peer.
3360 TODO: for now, return -EPERM looks working fine,
3361 but need to check if any other errno fit into this category.*/
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05303362 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
3363 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003364 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07003365 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3366 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05303367 " TDLS Max peer already connected. Request declined."
3368 " Num of peers (%d), Max allowed (%d).",
3369 __func__, MAC_ADDR_ARRAY(mac), numCurrTdlsPeers,
3370 HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -07003371 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003372 }
3373 else
3374 {
3375 hddTdlsPeer_t *pTdlsPeer;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05303376 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, mac, TRUE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003377 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003378 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07003379 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3380 "%s: " MAC_ADDRESS_STR " already connected. Request declined.",
3381 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003382 return -EPERM;
3383 }
3384 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003385 if (0 == update)
3386 wlan_hdd_tdls_set_link_status(pAdapter, mac, eTDLS_LINK_CONNECTING);
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003387
Jeff Johnsond75fe012013-04-06 10:53:06 -07003388 /* debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05303389 if (NULL != StaParams)
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003390 {
3391 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
3392 "%s: TDLS Peer Parameters.", __func__);
Hoonki Lee66b75f32013-04-16 18:30:07 -07003393 if(StaParams->htcap_present)
3394 {
3395 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
3396 "ht_capa->cap_info: %0x", StaParams->HTCap.capInfo);
3397 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
3398 "ht_capa->extended_capabilities: %0x",
3399 StaParams->HTCap.extendedHtCapInfo);
3400 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003401 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
3402 "params->capability: %0x",StaParams->capability);
3403 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07003404 "params->ext_capab_len: %0x",StaParams->extn_capability[0]);
Hoonki Lee66b75f32013-04-16 18:30:07 -07003405 if(StaParams->vhtcap_present)
3406 {
3407 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
3408 "rxMcsMap %x rxHighest %x txMcsMap %x txHighest %x",
3409 StaParams->VHTCap.suppMcs.rxMcsMap, StaParams->VHTCap.suppMcs.rxHighest,
3410 StaParams->VHTCap.suppMcs.txMcsMap, StaParams->VHTCap.suppMcs.txHighest);
3411 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003412 {
3413 int i = 0;
Hoonki Lee5305c3a2013-04-29 23:28:59 -07003414 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "Supported rates:");
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003415 for (i = 0; i < sizeof(StaParams->supported_rates); i++)
3416 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
3417 "[%d]: %x ", i, StaParams->supported_rates[i]);
3418 }
Jeff Johnsond75fe012013-04-06 10:53:06 -07003419 } /* end debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05303420 else if ((1 == update) && (NULL == StaParams))
3421 {
3422 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3423 "%s : update is true, but staParams is NULL. Error!", __func__);
3424 return -EPERM;
3425 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003426
3427 INIT_COMPLETION(pAdapter->tdls_add_station_comp);
3428
3429 if (!update)
3430 {
3431 status = sme_AddTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
3432 pAdapter->sessionId, mac);
3433 }
3434 else
3435 {
3436 status = sme_ChangeTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
3437 pAdapter->sessionId, mac, StaParams);
3438 }
3439
c_hpothu6ff1c3c2013-10-01 19:01:57 +05303440 ret = wait_for_completion_interruptible_timeout(&pAdapter->tdls_add_station_comp,
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003441 msecs_to_jiffies(WAIT_TIME_TDLS_ADD_STA));
3442
c_hpothu6ff1c3c2013-10-01 19:01:57 +05303443 if (ret <= 0)
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003444 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07003445 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05303446 "%s: timeout waiting for tdls add station indication %ld",
3447 __func__, ret);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07003448 return -EPERM;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003449 }
c_hpothu6ff1c3c2013-10-01 19:01:57 +05303450
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003451 if ( eHAL_STATUS_SUCCESS != pAdapter->tdlsAddStaStatus)
3452 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07003453 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003454 "%s: Add Station is unsucessful", __func__);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07003455 return -EPERM;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003456 }
3457
3458 return 0;
Gopichand Nakkala05922802013-03-14 12:23:19 -07003459
3460error:
3461 wlan_hdd_tdls_set_link_status(pAdapter, mac, eTDLS_LINK_IDLE);
3462 return -EPERM;
3463
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003464}
3465#endif
3466
Jeff Johnson295189b2012-06-20 16:38:30 -07003467static int wlan_hdd_change_station(struct wiphy *wiphy,
3468 struct net_device *dev,
3469 u8 *mac,
3470 struct station_parameters *params)
3471{
3472 VOS_STATUS status = VOS_STATUS_SUCCESS;
3473 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Gopichand Nakkala29149562013-05-10 21:43:41 +05303474 hdd_context_t *pHddCtx;
3475 hdd_station_ctx_t *pHddStaCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07003476 v_MACADDR_t STAMacAddress;
Gopichand Nakkalab0856222013-03-12 22:39:05 -07003477#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003478 tCsrStaParams StaParams = {0};
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003479 tANI_U8 isBufSta = 0;
Naresh Jayaram3180aa42014-02-12 21:47:26 +05303480 tANI_U8 isOffChannelSupported = 0;
Gopichand Nakkalab0856222013-03-12 22:39:05 -07003481#endif
Jeff Johnsone7245742012-09-05 17:12:55 -07003482 ENTER();
3483
Gopichand Nakkala29149562013-05-10 21:43:41 +05303484 if ((NULL == pAdapter))
3485 {
3486 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
3487 "invalid adapter ");
3488 return -EINVAL;
3489 }
3490
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05303491 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
3492 TRACE_CODE_HDD_CHANGE_STATION,
3493 pAdapter->sessionId, params->listen_interval));
Gopichand Nakkala29149562013-05-10 21:43:41 +05303494 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
3495 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3496
3497 if ((NULL == pHddCtx) || (NULL == pHddStaCtx))
3498 {
3499 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
3500 "invalid HDD state or HDD station context");
3501 return -EINVAL;
3502 }
3503
3504 if (pHddCtx->isLogpInProgress)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07003505 {
3506 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3507 "%s:LOGP in Progress. Ignore!!!", __func__);
3508 return -EAGAIN;
3509 }
3510
Jeff Johnson295189b2012-06-20 16:38:30 -07003511 vos_mem_copy(STAMacAddress.bytes, mac, sizeof(v_MACADDR_t));
3512
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003513 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
3514 || (pAdapter->device_mode == WLAN_HDD_P2P_GO))
Jeff Johnson295189b2012-06-20 16:38:30 -07003515 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003516 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED))
Jeff Johnson295189b2012-06-20 16:38:30 -07003517 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303518 status = hdd_softap_change_STA_state( pAdapter, &STAMacAddress,
Jeff Johnson295189b2012-06-20 16:38:30 -07003519 WLANTL_STA_AUTHENTICATED);
3520
Gopichand Nakkala29149562013-05-10 21:43:41 +05303521 if (status != VOS_STATUS_SUCCESS)
3522 {
3523 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3524 "%s: Not able to change TL state to AUTHENTICATED", __func__);
3525 return -EINVAL;
3526 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003527 }
3528 }
Hoonki Leea6d49be2013-04-05 09:43:25 -07003529 else if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
3530 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)) {
Gopichand Nakkala29149562013-05-10 21:43:41 +05303531#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003532 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
3533 StaParams.capability = params->capability;
3534 StaParams.uapsd_queues = params->uapsd_queues;
3535 StaParams.max_sp = params->max_sp;
3536
Naresh Jayaram3180aa42014-02-12 21:47:26 +05303537 /* Convert (first channel , number of channels) tuple to
3538 * the total list of channels. This goes with the assumption
3539 * that if the first channel is < 14, then the next channels
3540 * are an incremental of 1 else an incremental of 4 till the number
3541 * of channels.
3542 */
3543 if (0 != params->supported_channels_len) {
3544 int i = 0,j = 0,k = 0, no_of_channels = 0 ;
3545 for ( i = 0 ; i < params->supported_channels_len ; i+=2)
3546 {
3547 int wifi_chan_index;
3548 StaParams.supported_channels[j] = params->supported_channels[i];
3549 wifi_chan_index =
3550 ((StaParams.supported_channels[j] <= HDD_CHANNEL_14 ) ? 1 : 4 );
3551 no_of_channels = params->supported_channels[i+1];
3552 for(k=1; k <= no_of_channels; k++)
3553 {
3554 StaParams.supported_channels[j+1] =
3555 StaParams.supported_channels[j] + wifi_chan_index;
3556 j+=1;
3557 }
3558 }
3559 StaParams.supported_channels_len = j;
3560 }
3561 vos_mem_copy(StaParams.supported_oper_classes,
3562 params->supported_oper_classes,
3563 params->supported_oper_classes_len);
3564 StaParams.supported_oper_classes_len =
3565 params->supported_oper_classes_len;
3566
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003567 if (0 != params->ext_capab_len)
3568 vos_mem_copy(StaParams.extn_capability, params->ext_capab,
3569 sizeof(StaParams.extn_capability));
3570
3571 if (NULL != params->ht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -07003572 {
3573 StaParams.htcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003574 vos_mem_copy(&StaParams.HTCap, params->ht_capa, sizeof(tSirHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -07003575 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003576
3577 StaParams.supported_rates_len = params->supported_rates_len;
3578
3579 /* Note : The Maximum sizeof supported_rates sent by the Supplicant is 32.
3580 * The supported_rates array , for all the structures propogating till Add Sta
3581 * to the firmware has to be modified , if the supplicant (ieee80211) is
3582 * modified to send more rates.
3583 */
3584
3585 /* To avoid Data Currption , set to max length to SIR_MAC_MAX_SUPP_RATES
3586 */
3587 if (StaParams.supported_rates_len > SIR_MAC_MAX_SUPP_RATES)
3588 StaParams.supported_rates_len = SIR_MAC_MAX_SUPP_RATES;
3589
3590 if (0 != StaParams.supported_rates_len) {
3591 int i = 0;
3592 vos_mem_copy(StaParams.supported_rates, params->supported_rates,
3593 StaParams.supported_rates_len);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07003594 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003595 "Supported Rates with Length %d", StaParams.supported_rates_len);
3596 for (i=0; i < StaParams.supported_rates_len; i++)
Hoonki Lee5305c3a2013-04-29 23:28:59 -07003597 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003598 "[%d]: %0x", i, StaParams.supported_rates[i]);
3599 }
3600
3601 if (NULL != params->vht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -07003602 {
3603 StaParams.vhtcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003604 vos_mem_copy(&StaParams.VHTCap, params->vht_capa, sizeof(tSirVHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -07003605 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003606
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003607 if (0 != params->ext_capab_len ) {
3608 /*Define A Macro : TODO Sunil*/
3609 if ((1<<4) & StaParams.extn_capability[3]) {
3610 isBufSta = 1;
3611 }
Naresh Jayaram3180aa42014-02-12 21:47:26 +05303612 /* TDLS Channel Switching Support */
3613 if ((1<<6) & StaParams.extn_capability[3]) {
3614 isOffChannelSupported = 1;
3615 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003616 }
Naresh Jayaram3180aa42014-02-12 21:47:26 +05303617 status = wlan_hdd_tdls_set_peer_caps( pAdapter, mac,
3618 &StaParams, isBufSta,
3619 isOffChannelSupported);
3620
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05303621 if (VOS_STATUS_SUCCESS != status) {
3622 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3623 "%s: wlan_hdd_tdls_set_peer_caps failed!", __func__);
3624 return -EINVAL;
3625 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003626 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 1, &StaParams);
3627
3628 if (VOS_STATUS_SUCCESS != status) {
3629 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3630 "%s: sme_ChangeTdlsPeerSta failed!", __func__);
3631 return -EINVAL;
3632 }
3633 }
Gopichand Nakkalab0856222013-03-12 22:39:05 -07003634#endif
Gopichand Nakkala6239acd2013-06-14 14:48:00 +05303635 }
Jeff Johnsone7245742012-09-05 17:12:55 -07003636 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07003637 return status;
3638}
3639
3640/*
Jeff Johnson295189b2012-06-20 16:38:30 -07003641 * FUNCTION: wlan_hdd_cfg80211_add_key
3642 * This function is used to initialize the key information
3643 */
3644#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003645static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07003646 struct net_device *ndev,
3647 u8 key_index, bool pairwise,
3648 const u8 *mac_addr,
3649 struct key_params *params
3650 )
3651#else
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003652static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07003653 struct net_device *ndev,
3654 u8 key_index, const u8 *mac_addr,
3655 struct key_params *params
3656 )
3657#endif
3658{
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003659 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -07003660 tCsrRoamSetKey setKey;
3661 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05303662 int status;
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003663 v_U32_t roamId= 0xFF;
3664 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07003665 hdd_hostapd_state_t *pHostapdState;
3666 VOS_STATUS vos_status;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07003667 eHalStatus halStatus;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05303668 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07003669
3670 ENTER();
3671
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05303672 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
3673 TRACE_CODE_HDD_CFG80211_ADD_KEY,
3674 pAdapter->sessionId, params->key_len));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05303675 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
3676 status = wlan_hdd_validate_context(pHddCtx);
3677
3678 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07003679 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05303680 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3681 "%s: HDD context is not valid", __func__);
3682 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07003683 }
3684
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05303685 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
3686 __func__, hdd_device_modetoString(pAdapter->device_mode),
3687 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07003688
3689 if (CSR_MAX_NUM_KEY <= key_index)
3690 {
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003691 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07003692 key_index);
3693
3694 return -EINVAL;
3695 }
3696
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003697 if (CSR_MAX_KEY_LEN < params->key_len)
3698 {
3699 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key length %d", __func__,
3700 params->key_len);
3701
3702 return -EINVAL;
3703 }
3704
3705 hddLog(VOS_TRACE_LEVEL_INFO,
3706 "%s: called with key index = %d & key length %d",
3707 __func__, key_index, params->key_len);
Jeff Johnson295189b2012-06-20 16:38:30 -07003708
3709 /*extract key idx, key len and key*/
3710 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
3711 setKey.keyId = key_index;
3712 setKey.keyLength = params->key_len;
3713 vos_mem_copy(&setKey.Key[0],params->key, params->key_len);
3714
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003715 switch (params->cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -07003716 {
3717 case WLAN_CIPHER_SUITE_WEP40:
3718 setKey.encType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
3719 break;
3720
3721 case WLAN_CIPHER_SUITE_WEP104:
3722 setKey.encType = eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
3723 break;
3724
3725 case WLAN_CIPHER_SUITE_TKIP:
3726 {
3727 u8 *pKey = &setKey.Key[0];
3728 setKey.encType = eCSR_ENCRYPT_TYPE_TKIP;
3729
3730 vos_mem_zero(pKey, CSR_MAX_KEY_LEN);
3731
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003732 /*Supplicant sends the 32bytes key in this order
Jeff Johnson295189b2012-06-20 16:38:30 -07003733
3734 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003735 | Tk1 |TX-MIC | RX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -07003736 |--------------|----------|----------|
3737 <---16bytes---><--8bytes--><--8bytes-->
3738
3739 */
3740 /*Sme expects the 32 bytes key to be in the below order
3741
3742 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003743 | Tk1 |RX-MIC | TX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -07003744 |--------------|----------|----------|
3745 <---16bytes---><--8bytes--><--8bytes-->
3746 */
3747 /* Copy the Temporal Key 1 (TK1) */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003748 vos_mem_copy(pKey, params->key, 16);
Jeff Johnson295189b2012-06-20 16:38:30 -07003749
3750 /*Copy the rx mic first*/
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003751 vos_mem_copy(&pKey[16], &params->key[24], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -07003752
3753 /*Copy the tx mic */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003754 vos_mem_copy(&pKey[24], &params->key[16], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -07003755
3756
3757 break;
3758 }
3759
3760 case WLAN_CIPHER_SUITE_CCMP:
3761 setKey.encType = eCSR_ENCRYPT_TYPE_AES;
3762 break;
3763
3764#ifdef FEATURE_WLAN_WAPI
3765 case WLAN_CIPHER_SUITE_SMS4:
3766 {
3767 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
3768 wlan_hdd_cfg80211_set_key_wapi(pAdapter, key_index, mac_addr,
3769 params->key, params->key_len);
3770 return 0;
3771 }
3772#endif
Chet Lanctot186b5732013-03-18 10:26:30 -07003773
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003774#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -07003775 case WLAN_CIPHER_SUITE_KRK:
3776 setKey.encType = eCSR_ENCRYPT_TYPE_KRK;
3777 break;
3778#endif
Chet Lanctot186b5732013-03-18 10:26:30 -07003779
3780#ifdef WLAN_FEATURE_11W
3781 case WLAN_CIPHER_SUITE_AES_CMAC:
3782 setKey.encType = eCSR_ENCRYPT_TYPE_AES_CMAC;
Chet Lanctot3b5158a2013-03-31 16:45:21 -07003783 break;
Chet Lanctot186b5732013-03-18 10:26:30 -07003784#endif
3785
Jeff Johnson295189b2012-06-20 16:38:30 -07003786 default:
Jeff Johnson0299d0a2013-10-30 12:37:43 -07003787 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unsupported cipher type %u",
Jeff Johnson295189b2012-06-20 16:38:30 -07003788 __func__, params->cipher);
3789 return -EOPNOTSUPP;
3790 }
3791
3792 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: encryption type %d",
3793 __func__, setKey.encType);
3794
Shailender Karmuchi642e9812013-05-30 14:34:49 -07003795 if (
Jeff Johnson295189b2012-06-20 16:38:30 -07003796#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
3797 (!pairwise)
3798#else
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003799 (!mac_addr || is_broadcast_ether_addr(mac_addr))
Jeff Johnson295189b2012-06-20 16:38:30 -07003800#endif
Shailender Karmuchi642e9812013-05-30 14:34:49 -07003801 )
3802 {
3803 /* set group key*/
3804 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3805 "%s- %d: setting Broadcast key",
3806 __func__, __LINE__);
3807 setKey.keyDirection = eSIR_RX_ONLY;
3808 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
3809 }
3810 else
3811 {
3812 /* set pairwise key*/
3813 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3814 "%s- %d: setting pairwise key",
3815 __func__, __LINE__);
3816 setKey.keyDirection = eSIR_TX_RX;
3817 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
3818 }
3819 if ((WLAN_HDD_IBSS == pAdapter->device_mode) && !pairwise)
3820 {
3821 setKey.keyDirection = eSIR_TX_RX;
3822 /*Set the group key*/
3823 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
3824 pAdapter->sessionId, &setKey, &roamId );
Jeff Johnson295189b2012-06-20 16:38:30 -07003825
Shailender Karmuchi642e9812013-05-30 14:34:49 -07003826 if ( 0 != status )
3827 {
3828 hddLog(VOS_TRACE_LEVEL_ERROR,
3829 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
3830 return -EINVAL;
3831 }
3832 /*Save the keys here and call sme_RoamSetKey for setting
3833 the PTK after peer joins the IBSS network*/
3834 vos_mem_copy(&pAdapter->sessionCtx.station.ibss_enc_key,
3835 &setKey, sizeof(tCsrRoamSetKey));
3836 return status;
3837 }
Gopichand Nakkala29149562013-05-10 21:43:41 +05303838 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP) ||
3839 (pAdapter->device_mode == WLAN_HDD_P2P_GO))
3840 {
Jeff Johnson295189b2012-06-20 16:38:30 -07003841 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003842 if( pHostapdState->bssState == BSS_START )
3843 {
c_hpothu7c55da62014-01-23 18:34:02 +05303844 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3845 vos_status = wlan_hdd_check_ula_done(pAdapter);
3846
3847 if ( vos_status != VOS_STATUS_SUCCESS )
3848 {
3849 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3850 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
3851 __LINE__, vos_status );
3852
3853 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
3854
3855 return -EINVAL;
3856 }
3857
Jeff Johnson295189b2012-06-20 16:38:30 -07003858 status = WLANSAP_SetKeySta( pVosContext, &setKey);
3859
3860 if ( status != eHAL_STATUS_SUCCESS )
3861 {
3862 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3863 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
3864 __LINE__, status );
3865 }
3866 }
3867
3868 /* Saving WEP keys */
3869 else if( eCSR_ENCRYPT_TYPE_WEP40_STATICKEY == setKey.encType ||
3870 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY == setKey.encType )
3871 {
3872 //Save the wep key in ap context. Issue setkey after the BSS is started.
3873 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
3874 vos_mem_copy(&pAPCtx->wepKey[key_index], &setKey, sizeof(tCsrRoamSetKey));
3875 }
3876 else
3877 {
3878 //Save the key in ap context. Issue setkey after the BSS is started.
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003879 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07003880 vos_mem_copy(&pAPCtx->groupKey, &setKey, sizeof(tCsrRoamSetKey));
3881 }
3882 }
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003883 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION) ||
3884 (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT) )
Jeff Johnson295189b2012-06-20 16:38:30 -07003885 {
3886 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
3887 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3888
Gopichand Nakkala3d295922013-05-07 16:19:14 +05303889#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
3890 if (!pairwise)
3891#else
3892 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
3893#endif
3894 {
3895 /* set group key*/
3896 if (pHddStaCtx->roam_info.deferKeyComplete)
3897 {
3898 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3899 "%s- %d: Perform Set key Complete",
3900 __func__, __LINE__);
3901 hdd_PerformRoamSetKeyComplete(pAdapter);
3902 }
3903 }
3904
Jeff Johnson295189b2012-06-20 16:38:30 -07003905 pWextState->roamProfile.Keys.KeyLength[key_index] = (u8)params->key_len;
3906
Venkata Prathyusha Kuntupalliee2ce712013-01-17 14:09:24 -08003907 pWextState->roamProfile.Keys.defaultIndex = key_index;
3908
3909
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003910 vos_mem_copy(&pWextState->roamProfile.Keys.KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -07003911 params->key, params->key_len);
3912
Gopichand Nakkala3d295922013-05-07 16:19:14 +05303913
Jeff Johnson295189b2012-06-20 16:38:30 -07003914 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
3915
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303916 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -07003917 "%s: set key for peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303918 __func__, setKey.peerMac[0], setKey.peerMac[1],
3919 setKey.peerMac[2], setKey.peerMac[3],
3920 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -07003921 setKey.keyDirection);
3922
3923 vos_status = wlan_hdd_check_ula_done(pAdapter);
3924
3925 if ( vos_status != VOS_STATUS_SUCCESS )
3926 {
3927 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3928 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
3929 __LINE__, vos_status );
3930
3931 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
3932
3933 return -EINVAL;
3934
3935 }
3936
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07003937#ifdef WLAN_FEATURE_VOWIFI_11R
Gopichand Nakkala3d295922013-05-07 16:19:14 +05303938 /* The supplicant may attempt to set the PTK once pre-authentication
3939 is done. Save the key in the UMAC and include it in the ADD BSS
3940 request */
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07003941 halStatus = sme_FTUpdateKey( WLAN_HDD_GET_HAL_CTX(pAdapter), &setKey);
Gopichand Nakkala3d295922013-05-07 16:19:14 +05303942 if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_SUCCESS )
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07003943 {
Gopichand Nakkala3d295922013-05-07 16:19:14 +05303944 hddLog(VOS_TRACE_LEVEL_INFO_MED,
3945 "%s: Update PreAuth Key success", __func__);
3946 return 0;
3947 }
3948 else if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_FAILED )
3949 {
3950 hddLog(VOS_TRACE_LEVEL_ERROR,
3951 "%s: Update PreAuth Key failed", __func__);
Gopichand Nakkalad7d13652013-02-15 01:48:00 +05303952 return -EINVAL;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07003953 }
3954#endif /* WLAN_FEATURE_VOWIFI_11R */
Jeff Johnson295189b2012-06-20 16:38:30 -07003955
3956 /* issue set key request to SME*/
3957 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
3958 pAdapter->sessionId, &setKey, &roamId );
3959
3960 if ( 0 != status )
3961 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303962 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07003963 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
3964 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
3965 return -EINVAL;
3966 }
3967
3968
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303969 /* in case of IBSS as there was no information available about WEP keys during
3970 * IBSS join, group key intialized with NULL key, so re-initialize group key
Jeff Johnson295189b2012-06-20 16:38:30 -07003971 * with correct value*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303972 if ( (eCSR_BSS_TYPE_START_IBSS == pWextState->roamProfile.BSSType) &&
3973 !( ( IW_AUTH_KEY_MGMT_802_1X
3974 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X))
Jeff Johnson295189b2012-06-20 16:38:30 -07003975 && (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType)
3976 )
3977 &&
3978 ( (WLAN_CIPHER_SUITE_WEP40 == params->cipher)
3979 || (WLAN_CIPHER_SUITE_WEP104 == params->cipher)
3980 )
3981 )
3982 {
3983 setKey.keyDirection = eSIR_RX_ONLY;
3984 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
3985
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303986 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -07003987 "%s: set key peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303988 __func__, setKey.peerMac[0], setKey.peerMac[1],
3989 setKey.peerMac[2], setKey.peerMac[3],
3990 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -07003991 setKey.keyDirection);
3992
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303993 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07003994 pAdapter->sessionId, &setKey, &roamId );
3995
3996 if ( 0 != status )
3997 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303998 hddLog(VOS_TRACE_LEVEL_ERROR,
3999 "%s: sme_RoamSetKey failed for group key (IBSS), returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07004000 __func__, status);
4001 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
4002 return -EINVAL;
4003 }
4004 }
4005 }
4006
4007 return 0;
4008}
4009
4010/*
4011 * FUNCTION: wlan_hdd_cfg80211_get_key
4012 * This function is used to get the key information
4013 */
4014#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304015static int wlan_hdd_cfg80211_get_key(
4016 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07004017 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304018 u8 key_index, bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -07004019 const u8 *mac_addr, void *cookie,
4020 void (*callback)(void *cookie, struct key_params*)
4021 )
4022#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304023static int wlan_hdd_cfg80211_get_key(
4024 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07004025 struct net_device *ndev,
4026 u8 key_index, const u8 *mac_addr, void *cookie,
4027 void (*callback)(void *cookie, struct key_params*)
4028 )
4029#endif
4030{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304031 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -07004032 hdd_wext_state_t *pWextState= WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
4033 tCsrRoamProfile *pRoamProfile = &(pWextState->roamProfile);
4034 struct key_params params;
4035
4036 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304037
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05304038 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
4039 __func__, hdd_device_modetoString(pAdapter->device_mode),
4040 pAdapter->device_mode);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304041
Jeff Johnson295189b2012-06-20 16:38:30 -07004042 memset(&params, 0, sizeof(params));
4043
4044 if (CSR_MAX_NUM_KEY <= key_index)
4045 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05304046 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid key index %d"), key_index);
Jeff Johnson295189b2012-06-20 16:38:30 -07004047 return -EINVAL;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304048 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004049
4050 switch(pRoamProfile->EncryptionType.encryptionType[0])
4051 {
4052 case eCSR_ENCRYPT_TYPE_NONE:
4053 params.cipher = IW_AUTH_CIPHER_NONE;
4054 break;
4055
4056 case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY:
4057 case eCSR_ENCRYPT_TYPE_WEP40:
4058 params.cipher = WLAN_CIPHER_SUITE_WEP40;
4059 break;
4060
4061 case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY:
4062 case eCSR_ENCRYPT_TYPE_WEP104:
4063 params.cipher = WLAN_CIPHER_SUITE_WEP104;
4064 break;
4065
4066 case eCSR_ENCRYPT_TYPE_TKIP:
4067 params.cipher = WLAN_CIPHER_SUITE_TKIP;
4068 break;
4069
4070 case eCSR_ENCRYPT_TYPE_AES:
4071 params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
4072 break;
4073
4074 default:
4075 params.cipher = IW_AUTH_CIPHER_NONE;
4076 break;
4077 }
4078
c_hpothuaaf19692014-05-17 17:01:48 +05304079 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
4080 TRACE_CODE_HDD_CFG80211_GET_KEY,
4081 pAdapter->sessionId, params.cipher));
4082
Jeff Johnson295189b2012-06-20 16:38:30 -07004083 params.key_len = pRoamProfile->Keys.KeyLength[key_index];
4084 params.seq_len = 0;
4085 params.seq = NULL;
4086 params.key = &pRoamProfile->Keys.KeyMaterial[key_index][0];
4087 callback(cookie, &params);
4088 return 0;
4089}
4090
4091/*
4092 * FUNCTION: wlan_hdd_cfg80211_del_key
4093 * This function is used to delete the key information
4094 */
4095#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304096static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07004097 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304098 u8 key_index,
4099 bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -07004100 const u8 *mac_addr
4101 )
4102#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304103static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07004104 struct net_device *ndev,
4105 u8 key_index,
4106 const u8 *mac_addr
4107 )
4108#endif
4109{
4110 int status = 0;
4111
4112 //This code needs to be revisited. There is sme_removeKey API, we should
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304113 //plan to use that. After the change to use correct index in setkey,
Jeff Johnson295189b2012-06-20 16:38:30 -07004114 //it is observed that this is invalidating peer
4115 //key index whenever re-key is done. This is affecting data link.
4116 //It should be ok to ignore del_key.
4117#if 0
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304118 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
4119 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07004120 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
4121 tCsrRoamSetKey setKey;
4122 v_U32_t roamId= 0xFF;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304123
Jeff Johnson295189b2012-06-20 16:38:30 -07004124 ENTER();
4125
4126 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device_mode = %d\n",
4127 __func__,pAdapter->device_mode);
4128
4129 if (CSR_MAX_NUM_KEY <= key_index)
4130 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304131 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07004132 key_index);
4133
4134 return -EINVAL;
4135 }
4136
4137 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
4138 setKey.keyId = key_index;
4139
4140 if (mac_addr)
4141 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
4142 else
4143 vos_mem_copy(setKey.peerMac, groupmacaddr, WNI_CFG_BSSID_LEN);
4144
4145 setKey.encType = eCSR_ENCRYPT_TYPE_NONE;
4146
4147 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07004148 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304149 )
4150 {
4151
4152 hdd_hostapd_state_t *pHostapdState =
Jeff Johnson295189b2012-06-20 16:38:30 -07004153 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
4154 if( pHostapdState->bssState == BSS_START)
4155 {
4156 status = WLANSAP_SetKeySta( pVosContext, &setKey);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304157
Jeff Johnson295189b2012-06-20 16:38:30 -07004158 if ( status != eHAL_STATUS_SUCCESS )
4159 {
4160 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4161 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
4162 __LINE__, status );
4163 }
4164 }
4165 }
4166 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304167 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnson295189b2012-06-20 16:38:30 -07004168 )
4169 {
4170 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4171
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304172 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
4173
4174 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -07004175 "%s: delete key for peerMac %2x:%2x:%2x:%2x:%2x:%2x",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304176 __func__, setKey.peerMac[0], setKey.peerMac[1],
4177 setKey.peerMac[2], setKey.peerMac[3],
Jeff Johnson295189b2012-06-20 16:38:30 -07004178 setKey.peerMac[4], setKey.peerMac[5]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304179 if(pAdapter->sessionCtx.station.conn_info.connState ==
4180 eConnectionState_Associated)
Jeff Johnson295189b2012-06-20 16:38:30 -07004181 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304182 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07004183 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304184
Jeff Johnson295189b2012-06-20 16:38:30 -07004185 if ( 0 != status )
4186 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304187 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07004188 "%s: sme_RoamSetKey failure, returned %d",
4189 __func__, status);
4190 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
4191 return -EINVAL;
4192 }
4193 }
4194 }
4195#endif
Jeff Johnsone7245742012-09-05 17:12:55 -07004196 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07004197 return status;
4198}
4199
4200/*
4201 * FUNCTION: wlan_hdd_cfg80211_set_default_key
4202 * This function is used to set the default tx key index
4203 */
4204#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
4205static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
4206 struct net_device *ndev,
4207 u8 key_index,
4208 bool unicast, bool multicast)
4209#else
4210static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
4211 struct net_device *ndev,
4212 u8 key_index)
4213#endif
4214{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304215 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05304216 int status;
Gopichand Nakkala29149562013-05-10 21:43:41 +05304217 hdd_wext_state_t *pWextState;
4218 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05304219 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07004220
4221 ENTER();
4222
Gopichand Nakkala29149562013-05-10 21:43:41 +05304223 if ((NULL == pAdapter))
4224 {
4225 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
4226 "invalid adapter");
4227 return -EINVAL;
4228 }
4229
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05304230 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
4231 TRACE_CODE_HDD_CFG80211_SET_DEFAULT_KEY,
4232 pAdapter->sessionId, key_index));
4233
Gopichand Nakkala29149562013-05-10 21:43:41 +05304234 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
4235 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4236
4237 if ((NULL == pWextState) || (NULL == pHddStaCtx))
4238 {
4239 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
4240 "invalid Wext state or HDD context");
4241 return -EINVAL;
4242 }
4243
Arif Hussain6d2a3322013-11-17 19:50:10 -08004244 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d key_index = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07004245 __func__,pAdapter->device_mode, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304246
Jeff Johnson295189b2012-06-20 16:38:30 -07004247 if (CSR_MAX_NUM_KEY <= key_index)
4248 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304249 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07004250 key_index);
4251
4252 return -EINVAL;
4253 }
4254
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05304255 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
4256 status = wlan_hdd_validate_context(pHddCtx);
4257
4258 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004259 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05304260 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4261 "%s: HDD context is not valid", __func__);
4262 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004263 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304264
Jeff Johnson295189b2012-06-20 16:38:30 -07004265 if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -07004266 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304267 )
Jeff Johnson295189b2012-06-20 16:38:30 -07004268 {
Gopichand Nakkala29149562013-05-10 21:43:41 +05304269 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
Arif Hussain6943f522013-11-04 20:10:10 -08004270 pHddStaCtx->conn_info.ucEncryptionType) &&
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304271 (eCSR_ENCRYPT_TYPE_AES !=
Arif Hussain6943f522013-11-04 20:10:10 -08004272 pHddStaCtx->conn_info.ucEncryptionType)
Jeff Johnson295189b2012-06-20 16:38:30 -07004273 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304274 {
4275 /* if default key index is not same as previous one,
Jeff Johnson295189b2012-06-20 16:38:30 -07004276 * then update the default key index */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304277
Jeff Johnson295189b2012-06-20 16:38:30 -07004278 tCsrRoamSetKey setKey;
4279 v_U32_t roamId= 0xFF;
4280 tCsrKeys *Keys = &pWextState->roamProfile.Keys;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304281
4282 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: default tx key index %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07004283 __func__, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304284
Jeff Johnson295189b2012-06-20 16:38:30 -07004285 Keys->defaultIndex = (u8)key_index;
4286 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
4287 setKey.keyId = key_index;
4288 setKey.keyLength = Keys->KeyLength[key_index];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304289
4290 vos_mem_copy(&setKey.Key[0],
4291 &Keys->KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -07004292 Keys->KeyLength[key_index]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304293
Gopichand Nakkala29149562013-05-10 21:43:41 +05304294 setKey.keyDirection = eSIR_TX_RX;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304295
4296 vos_mem_copy(setKey.peerMac,
Jeff Johnson295189b2012-06-20 16:38:30 -07004297 &pHddStaCtx->conn_info.bssId[0],
4298 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304299
Gopichand Nakkala29149562013-05-10 21:43:41 +05304300 if (Keys->KeyLength[key_index] == CSR_WEP40_KEY_LEN &&
4301 pWextState->roamProfile.EncryptionType.encryptionType[0] ==
4302 eCSR_ENCRYPT_TYPE_WEP104)
4303 {
4304 /*In the case of dynamic wep supplicant hardcodes DWEP type to eCSR_ENCRYPT_TYPE_WEP104
4305 even though ap is configured for WEP-40 encryption. In this canse the key length
4306 is 5 but the encryption type is 104 hence checking the key langht(5) and encryption
4307 type(104) and switching encryption type to 40*/
4308 pWextState->roamProfile.EncryptionType.encryptionType[0] =
4309 eCSR_ENCRYPT_TYPE_WEP40;
4310 pWextState->roamProfile.mcEncryptionType.encryptionType[0] =
4311 eCSR_ENCRYPT_TYPE_WEP40;
4312 }
4313
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304314 setKey.encType =
Jeff Johnson295189b2012-06-20 16:38:30 -07004315 pWextState->roamProfile.EncryptionType.encryptionType[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304316
Jeff Johnson295189b2012-06-20 16:38:30 -07004317 /* issue set key request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304318 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07004319 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304320
Jeff Johnson295189b2012-06-20 16:38:30 -07004321 if ( 0 != status )
4322 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304323 hddLog(VOS_TRACE_LEVEL_ERROR,
4324 "%s: sme_RoamSetKey failed, returned %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07004325 status);
4326 return -EINVAL;
4327 }
4328 }
4329 }
4330
4331 /* In SoftAp mode setting key direction for default mode */
4332 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
4333 {
4334 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
4335 pWextState->roamProfile.EncryptionType.encryptionType[0]) &&
4336 (eCSR_ENCRYPT_TYPE_AES !=
4337 pWextState->roamProfile.EncryptionType.encryptionType[0])
4338 )
4339 {
4340 /* Saving key direction for default key index to TX default */
4341 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
4342 pAPCtx->wepKey[key_index].keyDirection = eSIR_TX_DEFAULT;
4343 }
4344 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304345
Jeff Johnson295189b2012-06-20 16:38:30 -07004346 return status;
4347}
4348
Jeff Johnson295189b2012-06-20 16:38:30 -07004349/*
4350 * FUNCTION: wlan_hdd_cfg80211_inform_bss
4351 * This function is used to inform the BSS details to nl80211 interface.
4352 */
4353static struct cfg80211_bss* wlan_hdd_cfg80211_inform_bss(
4354 hdd_adapter_t *pAdapter, tCsrRoamConnectedProfile *roamProfile)
4355{
4356 struct net_device *dev = pAdapter->dev;
4357 struct wireless_dev *wdev = dev->ieee80211_ptr;
4358 struct wiphy *wiphy = wdev->wiphy;
4359 tSirBssDescription *pBssDesc = roamProfile->pBssDesc;
4360 int chan_no;
4361 int ie_length;
4362 const char *ie;
4363 unsigned int freq;
4364 struct ieee80211_channel *chan;
4365 int rssi = 0;
4366 struct cfg80211_bss *bss = NULL;
4367
4368 ENTER();
4369
4370 if( NULL == pBssDesc )
4371 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08004372 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pBssDesc is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004373 return bss;
4374 }
4375
4376 chan_no = pBssDesc->channelId;
4377 ie_length = GET_IE_LEN_IN_BSS_DESC( pBssDesc->length );
4378 ie = ((ie_length != 0) ? (const char *)&pBssDesc->ieFields: NULL);
4379
4380 if( NULL == ie )
4381 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08004382 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: IE of BSS descriptor is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004383 return bss;
4384 }
4385
4386#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
4387 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
4388 {
4389 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
4390 }
4391 else
4392 {
4393 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
4394 }
4395#else
4396 freq = ieee80211_channel_to_frequency(chan_no);
4397#endif
4398
4399 chan = __ieee80211_get_channel(wiphy, freq);
4400
Santhosh Kumar Padmaa45fdb12014-04-15 15:54:38 +05304401 if (!chan) {
4402 hddLog(VOS_TRACE_LEVEL_ERROR, "%s chan pointer is NULL", __func__);
4403 return NULL;
4404 }
4405
Jeff Johnson295189b2012-06-20 16:38:30 -07004406 bss = cfg80211_get_bss(wiphy, chan, pBssDesc->bssId,
4407 &roamProfile->SSID.ssId[0], roamProfile->SSID.length,
4408 WLAN_CAPABILITY_ESS, WLAN_CAPABILITY_ESS);
4409 if (bss == NULL)
4410 {
4411 rssi = (VOS_MIN ((pBssDesc->rssi + pBssDesc->sinr), 0))*100;
4412
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304413 return (cfg80211_inform_bss(wiphy, chan, pBssDesc->bssId,
4414 le64_to_cpu(*(__le64 *)pBssDesc->timeStamp),
Jeff Johnson295189b2012-06-20 16:38:30 -07004415 pBssDesc->capabilityInfo,
4416 pBssDesc->beaconInterval, ie, ie_length,
4417 rssi, GFP_KERNEL ));
4418}
4419 else
4420 {
4421 return bss;
4422 }
4423}
4424
4425
4426
4427/*
4428 * FUNCTION: wlan_hdd_cfg80211_inform_bss_frame
4429 * This function is used to inform the BSS details to nl80211 interface.
4430 */
4431struct cfg80211_bss*
4432wlan_hdd_cfg80211_inform_bss_frame( hdd_adapter_t *pAdapter,
4433 tSirBssDescription *bss_desc
4434 )
4435{
4436 /*
4437 cfg80211_inform_bss() is not updating ie field of bss entry, if entry
4438 already exists in bss data base of cfg80211 for that particular BSS ID.
4439 Using cfg80211_inform_bss_frame to update the bss entry instead of
4440 cfg80211_inform_bss, But this call expects mgmt packet as input. As of
4441 now there is no possibility to get the mgmt(probe response) frame from PE,
4442 converting bss_desc to ieee80211_mgmt(probe response) and passing to
4443 cfg80211_inform_bss_frame.
4444 */
4445 struct net_device *dev = pAdapter->dev;
4446 struct wireless_dev *wdev = dev->ieee80211_ptr;
4447 struct wiphy *wiphy = wdev->wiphy;
4448 int chan_no = bss_desc->channelId;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08004449#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
4450 qcom_ie_age *qie_age = NULL;
4451 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length ) + sizeof(qcom_ie_age);
4452#else
Jeff Johnson295189b2012-06-20 16:38:30 -07004453 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length );
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08004454#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07004455 const char *ie =
4456 ((ie_length != 0) ? (const char *)&bss_desc->ieFields: NULL);
4457 unsigned int freq;
4458 struct ieee80211_channel *chan;
Abhishek Singh1e2bfa32014-01-02 15:44:15 +05304459 struct ieee80211_mgmt *mgmt = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07004460 struct cfg80211_bss *bss_status = NULL;
4461 size_t frame_len = sizeof (struct ieee80211_mgmt) + ie_length;
4462 int rssi = 0;
Wilson Yangf80a0542013-10-07 13:02:37 -07004463 hdd_context_t *pHddCtx;
4464 int status;
Jeff Johnsone7245742012-09-05 17:12:55 -07004465#ifdef WLAN_OPEN_SOURCE
4466 struct timespec ts;
4467#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07004468
Wilson Yangf80a0542013-10-07 13:02:37 -07004469 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
4470 status = wlan_hdd_validate_context(pHddCtx);
4471
4472 /*bss_update is not allowed during wlan driver loading or unloading*/
Mihir Shete18156292014-03-11 15:38:30 +05304473 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Wilson Yangf80a0542013-10-07 13:02:37 -07004474 {
4475 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4476 "%s:Loading_unloading in Progress. Ignore!!!",__func__);
4477 return NULL;
4478 }
4479
4480
4481 if (0 != status)
4482 {
4483 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4484 "%s: HDD context is not valid", __func__);
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -07004485 return NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -07004486 }
4487
Abhishek Singh1e2bfa32014-01-02 15:44:15 +05304488 mgmt = kzalloc((sizeof (struct ieee80211_mgmt) + ie_length), GFP_KERNEL);
Wilson Yangf80a0542013-10-07 13:02:37 -07004489 if (!mgmt)
4490 {
4491 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4492 "%s: memory allocation failed ", __func__);
4493 return NULL;
4494 }
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -07004495
Jeff Johnson295189b2012-06-20 16:38:30 -07004496 memcpy(mgmt->bssid, bss_desc->bssId, ETH_ALEN);
Jeff Johnsone7245742012-09-05 17:12:55 -07004497
4498#ifdef WLAN_OPEN_SOURCE
4499 /* Android does not want the timestamp from the frame.
4500 Instead it wants a monotonic increasing value */
4501 get_monotonic_boottime(&ts);
4502 mgmt->u.probe_resp.timestamp =
4503 ((u64)ts.tv_sec * 1000000) + (ts.tv_nsec / 1000);
4504#else
4505 /* keep old behavior for non-open source (for now) */
Jeff Johnson295189b2012-06-20 16:38:30 -07004506 memcpy(&mgmt->u.probe_resp.timestamp, bss_desc->timeStamp,
4507 sizeof (bss_desc->timeStamp));
Jeff Johnsone7245742012-09-05 17:12:55 -07004508
4509#endif
4510
Jeff Johnson295189b2012-06-20 16:38:30 -07004511 mgmt->u.probe_resp.beacon_int = bss_desc->beaconInterval;
4512 mgmt->u.probe_resp.capab_info = bss_desc->capabilityInfo;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08004513
4514#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
4515 /* GPS Requirement: need age ie per entry. Using vendor specific. */
4516 /* Assuming this is the last IE, copy at the end */
4517 ie_length -=sizeof(qcom_ie_age);
4518 qie_age = (qcom_ie_age *)(mgmt->u.probe_resp.variable + ie_length);
4519 qie_age->element_id = QCOM_VENDOR_IE_ID;
4520 qie_age->len = QCOM_VENDOR_IE_AGE_LEN;
4521 qie_age->oui_1 = QCOM_OUI1;
4522 qie_age->oui_2 = QCOM_OUI2;
4523 qie_age->oui_3 = QCOM_OUI3;
4524 qie_age->type = QCOM_VENDOR_IE_AGE_TYPE;
4525 qie_age->age = vos_timer_get_system_ticks() - bss_desc->nReceivedTime;
4526#endif
4527
Jeff Johnson295189b2012-06-20 16:38:30 -07004528 memcpy(mgmt->u.probe_resp.variable, ie, ie_length);
Gopichand Nakkalad908ec82013-05-16 19:32:19 +05304529 if (bss_desc->fProbeRsp)
4530 {
4531 mgmt->frame_control |=
4532 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_RESP);
4533 }
4534 else
4535 {
4536 mgmt->frame_control |=
4537 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_BEACON);
4538 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004539
4540#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304541 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ) &&
Jeff Johnson295189b2012-06-20 16:38:30 -07004542 (wiphy->bands[IEEE80211_BAND_2GHZ] != NULL))
4543 {
4544 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
4545 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304546 else if ((chan_no > ARRAY_SIZE(hdd_channels_2_4_GHZ)) &&
Jeff Johnson295189b2012-06-20 16:38:30 -07004547 (wiphy->bands[IEEE80211_BAND_5GHZ] != NULL))
4548
4549 {
4550 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
4551 }
4552 else
4553 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05304554 hddLog(VOS_TRACE_LEVEL_ERROR, "%s Invalid chan_no:%d",
4555 __func__, chan_no);
Jeff Johnson295189b2012-06-20 16:38:30 -07004556 kfree(mgmt);
4557 return NULL;
4558 }
4559#else
4560 freq = ieee80211_channel_to_frequency(chan_no);
4561#endif
4562 chan = __ieee80211_get_channel(wiphy, freq);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -08004563 /*when the band is changed on the fly using the GUI, three things are done
4564 * 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)
4565 * as part of the scan abort, message willbe queued to PE and we proceed with flushing and changinh the band.
4566 * pe will stop the scanning further and report back the results what ever it had till now by calling the call back function.
4567 * if the time between update band and scandone call back is sufficent enough the band change reflects in SME, SME validates the channels
4568 * and discards the channels correponding to previous band and calls back with zero bss results.
4569 * 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
4570 * all the channels correponding to previous band.this is due to race condition.but those channels are invalid to the new band and so
4571 * this function __ieee80211_get_channel will return NULL.Each time we report scan result with this pointer null warning kernel trace is printed.
4572 * if the scan results contain large number of APs continuosly kernel warning trace is printed and it will lead to apps watch dog bark.
4573 * So drop the bss and continue to next bss.
4574 */
4575 if(chan == NULL)
4576 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05304577 hddLog(VOS_TRACE_LEVEL_ERROR, "%s chan pointer is NULL", __func__);
Chilam Ngc4244af2013-04-01 15:37:32 -07004578 kfree(mgmt);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -08004579 return NULL;
4580 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004581 /*To keep the rssi icon of the connected AP in the scan window
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304582 *and the rssi icon of the wireless networks in sync
Jeff Johnson295189b2012-06-20 16:38:30 -07004583 * */
4584 if (( eConnectionState_Associated ==
4585 pAdapter->sessionCtx.station.conn_info.connState ) &&
4586 ( VOS_TRUE == vos_mem_compare(bss_desc->bssId,
4587 pAdapter->sessionCtx.station.conn_info.bssId,
4588 WNI_CFG_BSSID_LEN)))
4589 {
4590 /* supplicant takes the signal strength in terms of mBm(100*dBm) */
4591 rssi = (pAdapter->rssi * 100);
4592 }
4593 else
4594 {
4595 rssi = (VOS_MIN ((bss_desc->rssi + bss_desc->sinr), 0))*100;
4596 }
4597
Nirav Shah20ac06f2013-12-12 18:14:06 +05304598 hddLog(VOS_TRACE_LEVEL_INFO, "%s: BSSID:" MAC_ADDRESS_STR " Channel:%d"
4599 "RSSI:%d", __func__, MAC_ADDR_ARRAY(mgmt->bssid),
4600 chan->center_freq, (int)(rssi/100));
4601
Jeff Johnson295189b2012-06-20 16:38:30 -07004602 bss_status = cfg80211_inform_bss_frame(wiphy, chan, mgmt,
4603 frame_len, rssi, GFP_KERNEL);
4604 kfree(mgmt);
4605 return bss_status;
4606}
4607
4608/*
4609 * FUNCTION: wlan_hdd_cfg80211_update_bss_db
4610 * This function is used to update the BSS data base of CFG8011
4611 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304612struct cfg80211_bss* wlan_hdd_cfg80211_update_bss_db( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07004613 tCsrRoamInfo *pRoamInfo
4614 )
4615{
4616 tCsrRoamConnectedProfile roamProfile;
4617 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
4618 struct cfg80211_bss *bss = NULL;
4619
4620 ENTER();
4621
4622 memset(&roamProfile, 0, sizeof(tCsrRoamConnectedProfile));
4623 sme_RoamGetConnectProfile(hHal, pAdapter->sessionId, &roamProfile);
4624
4625 if (NULL != roamProfile.pBssDesc)
4626 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304627 bss = wlan_hdd_cfg80211_inform_bss(pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07004628 &roamProfile);
4629
4630 if (NULL == bss)
4631 {
4632 hddLog(VOS_TRACE_LEVEL_INFO, "%s: cfg80211_inform_bss return NULL",
4633 __func__);
4634 }
4635
4636 sme_RoamFreeConnectProfile(hHal, &roamProfile);
4637 }
4638 else
4639 {
4640 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: roamProfile.pBssDesc is NULL",
4641 __func__);
4642 }
4643 return bss;
4644}
4645
4646/*
4647 * FUNCTION: wlan_hdd_cfg80211_update_bss
4648 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304649static int wlan_hdd_cfg80211_update_bss( struct wiphy *wiphy,
4650 hdd_adapter_t *pAdapter
Jeff Johnson295189b2012-06-20 16:38:30 -07004651 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304652{
Jeff Johnson295189b2012-06-20 16:38:30 -07004653 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
4654 tCsrScanResultInfo *pScanResult;
4655 eHalStatus status = 0;
4656 tScanResultHandle pResult;
4657 struct cfg80211_bss *bss_status = NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -07004658 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07004659
4660 ENTER();
4661
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05304662 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
4663 TRACE_CODE_HDD_CFG80211_UPDATE_BSS,
4664 NO_SESSION, pAdapter->sessionId));
4665
Wilson Yangf80a0542013-10-07 13:02:37 -07004666 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
4667
4668 if (pHddCtx->isLogpInProgress)
Jeff Johnson295189b2012-06-20 16:38:30 -07004669 {
Wilson Yangf80a0542013-10-07 13:02:37 -07004670 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
4671 "%s:LOGP in Progress. Ignore!!!",__func__);
4672 return -EAGAIN;
Jeff Johnson295189b2012-06-20 16:38:30 -07004673 }
4674
Wilson Yangf80a0542013-10-07 13:02:37 -07004675
4676 /*bss_update is not allowed during wlan driver loading or unloading*/
Mihir Shete18156292014-03-11 15:38:30 +05304677 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Wilson Yangf80a0542013-10-07 13:02:37 -07004678 {
4679 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4680 "%s:Loading_unloading in Progress. Ignore!!!",__func__);
4681 return VOS_STATUS_E_PERM;
4682 }
4683
4684
Jeff Johnson295189b2012-06-20 16:38:30 -07004685 /*
4686 * start getting scan results and populate cgf80211 BSS database
4687 */
4688 status = sme_ScanGetResult(hHal, pAdapter->sessionId, NULL, &pResult);
4689
4690 /* no scan results */
4691 if (NULL == pResult)
4692 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05304693 hddLog(VOS_TRACE_LEVEL_INFO, "%s: No scan result Status %d",
4694 __func__, status);
Jeff Johnson295189b2012-06-20 16:38:30 -07004695 return status;
4696 }
4697
4698 pScanResult = sme_ScanResultGetFirst(hHal, pResult);
4699
4700 while (pScanResult)
4701 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304702 /*
4703 * cfg80211_inform_bss() is not updating ie field of bss entry, if
4704 * entry already exists in bss data base of cfg80211 for that
4705 * particular BSS ID. Using cfg80211_inform_bss_frame to update the
4706 * bss entry instead of cfg80211_inform_bss, But this call expects
4707 * mgmt packet as input. As of now there is no possibility to get
4708 * the mgmt(probe response) frame from PE, converting bss_desc to
Jeff Johnson295189b2012-06-20 16:38:30 -07004709 * ieee80211_mgmt(probe response) and passing to c
4710 * fg80211_inform_bss_frame.
4711 * */
4712
4713 bss_status = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
4714 &pScanResult->BssDescriptor);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304715
Jeff Johnson295189b2012-06-20 16:38:30 -07004716
4717 if (NULL == bss_status)
4718 {
4719 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -08004720 "%s: NULL returned by cfg80211_inform_bss", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004721 }
4722 else
4723 {
Yue Maf49ba872013-08-19 12:04:25 -07004724 cfg80211_put_bss(
4725#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0))
4726 wiphy,
4727#endif
4728 bss_status);
Jeff Johnson295189b2012-06-20 16:38:30 -07004729 }
4730
4731 pScanResult = sme_ScanResultGetNext(hHal, pResult);
4732 }
4733
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304734 sme_ScanResultPurge(hHal, pResult);
Jeff Johnson295189b2012-06-20 16:38:30 -07004735
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304736 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07004737}
4738
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004739void
4740hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel)
4741{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304742 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussaina7c8e412013-11-20 11:06:42 -08004743 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(macAddr));
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004744} /****** end hddPrintMacAddr() ******/
4745
4746void
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07004747hddPrintPmkId(tANI_U8 *pmkId, tANI_U8 logLevel)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004748{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304749 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussain6d2a3322013-11-17 19:50:10 -08004750 "%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X",
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07004751 pmkId[0], pmkId[1], pmkId[2], pmkId[3], pmkId[4],
4752 pmkId[5], pmkId[6], pmkId[7], pmkId[8], pmkId[9], pmkId[10],
4753 pmkId[11], pmkId[12], pmkId[13], pmkId[14], pmkId[15]);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004754} /****** end hddPrintPmkId() ******/
4755
4756//hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel);
4757//hddPrintMacAddr(macAddr, VOS_TRACE_LEVEL_FATAL);
4758
4759//void sirDumpBuf(tpAniSirGlobal pMac, tANI_U8 modId, tANI_U32 level, tANI_U8 *buf, tANI_U32 size);
4760//sirDumpBuf(pMac, VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, pmkid, 16);
4761
4762#define dump_bssid(bssid) \
4763 { \
Jeff Johnsone7245742012-09-05 17:12:55 -07004764 hddLog(VOS_TRACE_LEVEL_INFO, "BSSID (MAC) address:\t"); \
4765 hddPrintMacAddr(bssid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004766 }
4767
4768#define dump_pmkid(pMac, pmkid) \
4769 { \
Jeff Johnsone7245742012-09-05 17:12:55 -07004770 hddLog(VOS_TRACE_LEVEL_INFO, "PMKSA-ID:\t"); \
4771 hddPrintPmkId(pmkid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004772 }
4773
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -07004774#if defined(FEATURE_WLAN_LFR) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004775/*
4776 * FUNCTION: wlan_hdd_cfg80211_pmksa_candidate_notify
4777 * This function is used to notify the supplicant of a new PMKSA candidate.
4778 */
4779int wlan_hdd_cfg80211_pmksa_candidate_notify(
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304780 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004781 int index, bool preauth )
4782{
Jeff Johnsone7245742012-09-05 17:12:55 -07004783#ifdef FEATURE_WLAN_OKC
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004784 struct net_device *dev = pAdapter->dev;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004785 hdd_context_t *pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004786
4787 ENTER();
Jeff Johnsone7245742012-09-05 17:12:55 -07004788 hddLog(VOS_TRACE_LEVEL_INFO, "%s is going to notify supplicant of:", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004789
4790 if( NULL == pRoamInfo )
4791 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08004792 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pRoamInfo is NULL", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004793 return -EINVAL;
4794 }
4795
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004796 if (eANI_BOOLEAN_TRUE == hdd_is_okc_mode_enabled(pHddCtx))
4797 {
4798 dump_bssid(pRoamInfo->bssid);
4799 cfg80211_pmksa_candidate_notify(dev, index,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004800 pRoamInfo->bssid, preauth, GFP_KERNEL);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004801 }
Jeff Johnsone7245742012-09-05 17:12:55 -07004802#endif /* FEATURE_WLAN_OKC */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304803 return 0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004804}
4805#endif //FEATURE_WLAN_LFR
4806
Yue Maef608272013-04-08 23:09:17 -07004807#ifdef FEATURE_WLAN_LFR_METRICS
4808/*
4809 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth
4810 * 802.11r/LFR metrics reporting function to report preauth initiation
4811 *
4812 */
4813#define MAX_LFR_METRICS_EVENT_LENGTH 100
4814VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth(hdd_adapter_t *pAdapter,
4815 tCsrRoamInfo *pRoamInfo)
4816{
4817 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
4818 union iwreq_data wrqu;
4819
4820 ENTER();
4821
4822 if (NULL == pAdapter)
4823 {
4824 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
4825 return VOS_STATUS_E_FAILURE;
4826 }
4827
4828 /* create the event */
4829 memset(&wrqu, 0, sizeof(wrqu));
4830 memset(metrics_notification, 0, sizeof(metrics_notification));
4831
4832 wrqu.data.pointer = metrics_notification;
4833 wrqu.data.length = scnprintf(metrics_notification,
4834 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_INIT "
4835 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
4836
4837 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
4838
4839 EXIT();
4840
4841 return VOS_STATUS_SUCCESS;
4842}
4843
4844/*
4845 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth_status
4846 * 802.11r/LFR metrics reporting function to report preauth completion
4847 * or failure
4848 */
4849VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth_status(
4850 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo, bool preauth_status)
4851{
4852 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
4853 union iwreq_data wrqu;
4854
4855 ENTER();
4856
4857 if (NULL == pAdapter)
4858 {
4859 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
4860 return VOS_STATUS_E_FAILURE;
4861 }
4862
4863 /* create the event */
4864 memset(&wrqu, 0, sizeof(wrqu));
4865 memset(metrics_notification, 0, sizeof(metrics_notification));
4866
4867 scnprintf(metrics_notification, sizeof(metrics_notification),
4868 "QCOM: LFR_PREAUTH_STATUS "MAC_ADDRESS_STR,
4869 MAC_ADDR_ARRAY(pRoamInfo->bssid));
4870
4871 if (1 == preauth_status)
4872 strncat(metrics_notification, " TRUE", 5);
4873 else
4874 strncat(metrics_notification, " FALSE", 6);
4875
4876 wrqu.data.pointer = metrics_notification;
4877 wrqu.data.length = strlen(metrics_notification);
4878
4879 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
4880
4881 EXIT();
4882
4883 return VOS_STATUS_SUCCESS;
4884}
4885
4886/*
4887 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_handover
4888 * 802.11r/LFR metrics reporting function to report handover initiation
4889 *
4890 */
4891VOS_STATUS wlan_hdd_cfg80211_roam_metrics_handover(hdd_adapter_t * pAdapter,
4892 tCsrRoamInfo *pRoamInfo)
4893{
4894 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
4895 union iwreq_data wrqu;
4896
4897 ENTER();
4898
4899 if (NULL == pAdapter)
4900 {
4901 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
4902 return VOS_STATUS_E_FAILURE;
4903 }
4904
4905 /* create the event */
4906 memset(&wrqu, 0, sizeof(wrqu));
4907 memset(metrics_notification, 0, sizeof(metrics_notification));
4908
4909 wrqu.data.pointer = metrics_notification;
4910 wrqu.data.length = scnprintf(metrics_notification,
4911 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_HANDOVER "
4912 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
4913
4914 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
4915
4916 EXIT();
4917
4918 return VOS_STATUS_SUCCESS;
4919}
4920#endif
4921
Jeff Johnson295189b2012-06-20 16:38:30 -07004922/*
4923 * FUNCTION: hdd_cfg80211_scan_done_callback
4924 * scanning callback function, called after finishing scan
4925 *
4926 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304927static eHalStatus hdd_cfg80211_scan_done_callback(tHalHandle halHandle,
Jeff Johnson295189b2012-06-20 16:38:30 -07004928 void *pContext, tANI_U32 scanId, eCsrScanStatus status)
4929{
4930 struct net_device *dev = (struct net_device *) pContext;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304931 //struct wireless_dev *wdev = dev->ieee80211_ptr;
Jeff Johnson295189b2012-06-20 16:38:30 -07004932 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07004933 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
4934 hdd_scaninfo_t *pScanInfo = &pHddCtx->scan_info;
Jeff Johnson295189b2012-06-20 16:38:30 -07004935 struct cfg80211_scan_request *req = NULL;
4936 int ret = 0;
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +05304937 bool aborted = false;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05304938 long waitRet = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07004939
4940 ENTER();
4941
4942 hddLog(VOS_TRACE_LEVEL_INFO,
4943 "%s called with halHandle = %p, pContext = %p,"
Arif Hussain6d2a3322013-11-17 19:50:10 -08004944 "scanID = %d, returned status = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07004945 __func__, halHandle, pContext, (int) scanId, (int) status);
4946
Kiet Lamac06e2c2013-10-23 16:25:07 +05304947 pScanInfo->mScanPendingCounter = 0;
4948
Jeff Johnson295189b2012-06-20 16:38:30 -07004949 //Block on scan req completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +05304950 waitRet = wait_for_completion_interruptible_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07004951 &pScanInfo->scan_req_completion_event,
4952 msecs_to_jiffies(WLAN_WAIT_TIME_SCAN_REQ));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05304953 if (waitRet <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -07004954 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05304955 hddLog(VOS_TRACE_LEVEL_ERROR,
4956 "%s wait on scan_req_completion_event failed %ld",__func__, waitRet);
Jeff Johnson295189b2012-06-20 16:38:30 -07004957 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -07004958 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -07004959 }
4960
Yue Maef608272013-04-08 23:09:17 -07004961 if (pScanInfo->mScanPending != VOS_TRUE)
Jeff Johnson295189b2012-06-20 16:38:30 -07004962 {
4963 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -07004964 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -07004965 }
4966
4967 /* Check the scanId */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304968 if (pScanInfo->scanId != scanId)
Jeff Johnson295189b2012-06-20 16:38:30 -07004969 {
4970 hddLog(VOS_TRACE_LEVEL_INFO,
4971 "%s called with mismatched scanId pScanInfo->scanId = %d "
Arif Hussain6d2a3322013-11-17 19:50:10 -08004972 "scanId = %d", __func__, (int) pScanInfo->scanId,
Jeff Johnson295189b2012-06-20 16:38:30 -07004973 (int) scanId);
4974 }
4975
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304976 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07004977 pAdapter);
4978
4979 if (0 > ret)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304980 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004981
4982
4983 /* If any client wait scan result through WEXT
4984 * send scan done event to client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07004985 if (pHddCtx->scan_info.waitScanResult)
Jeff Johnson295189b2012-06-20 16:38:30 -07004986 {
4987 /* The other scan request waiting for current scan finish
4988 * Send event to notify current scan finished */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07004989 if(WEXT_SCAN_PENDING_DELAY == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -07004990 {
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07004991 vos_event_set(&pHddCtx->scan_info.scan_finished_event);
Jeff Johnson295189b2012-06-20 16:38:30 -07004992 }
4993 /* Send notify to WEXT client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07004994 else if(WEXT_SCAN_PENDING_PIGGYBACK == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -07004995 {
4996 struct net_device *dev = pAdapter->dev;
4997 union iwreq_data wrqu;
4998 int we_event;
4999 char *msg;
5000
5001 memset(&wrqu, '\0', sizeof(wrqu));
5002 we_event = SIOCGIWSCAN;
5003 msg = NULL;
5004 wireless_send_event(dev, we_event, &wrqu, msg);
5005 }
5006 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07005007 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07005008
5009 /* Get the Scan Req */
5010 req = pAdapter->request;
5011
5012 if (!req)
5013 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08005014 hddLog(VOS_TRACE_LEVEL_ERROR, "request is became NULL");
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07005015 pScanInfo->mScanPending = VOS_FALSE;
Jeff Johnsone7245742012-09-05 17:12:55 -07005016 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -07005017 }
5018
5019 /*
5020 * setting up 0, just in case.
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305021 */
Jeff Johnson295189b2012-06-20 16:38:30 -07005022 req->n_ssids = 0;
5023 req->n_channels = 0;
5024 req->ie = 0;
5025
Jeff Johnson295189b2012-06-20 16:38:30 -07005026 pAdapter->request = NULL;
Jeff Johnsone7245742012-09-05 17:12:55 -07005027 /* Scan is no longer pending */
5028 pScanInfo->mScanPending = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07005029
Madan Mohan Koyyalamudib764bf82012-10-11 16:38:51 -07005030 /*
5031 * cfg80211_scan_done informing NL80211 about completion
5032 * of scanning
5033 */
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +05305034 if (status == eCSR_SCAN_ABORT || status == eCSR_SCAN_FAILURE)
5035 {
5036 aborted = true;
5037 }
5038 cfg80211_scan_done(req, aborted);
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -08005039 complete(&pScanInfo->abortscan_event_var);
Jeff Johnson295189b2012-06-20 16:38:30 -07005040
Jeff Johnsone7245742012-09-05 17:12:55 -07005041allow_suspend:
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07005042 /* release the wake lock at the end of the scan*/
5043 hdd_allow_suspend();
Jeff Johnsone7245742012-09-05 17:12:55 -07005044
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -07005045 /* Acquire wakelock to handle the case where APP's tries to suspend
5046 * immediatly after the driver gets connect request(i.e after scan)
5047 * from supplicant, this result in app's is suspending and not able
5048 * to process the connect request to AP */
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +05305049 hdd_prevent_suspend_timeout(1000);
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -07005050
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07005051#ifdef FEATURE_WLAN_TDLS
5052 wlan_hdd_tdls_scan_done_callback(pAdapter);
5053#endif
5054
Jeff Johnson295189b2012-06-20 16:38:30 -07005055 EXIT();
5056 return 0;
5057}
5058
5059/*
Rashmi Ramannab1429032014-04-26 14:59:09 +05305060 * FUNCTION: hdd_isConnectionInProgress
5061 * Go through each adapter and check if Connection is in progress
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08005062 *
5063 */
Rashmi Ramannab1429032014-04-26 14:59:09 +05305064v_BOOL_t hdd_isConnectionInProgress( hdd_context_t *pHddCtx )
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08005065{
5066 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
5067 hdd_station_ctx_t *pHddStaCtx = NULL;
5068 hdd_adapter_t *pAdapter = NULL;
5069 VOS_STATUS status = 0;
5070 v_U8_t staId = 0;
5071 v_U8_t *staMac = NULL;
5072
c_hpothu9b781ba2013-12-30 20:57:45 +05305073 if (TRUE == pHddCtx->btCoexModeSet)
5074 {
5075 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Rashmi Ramannab1429032014-04-26 14:59:09 +05305076 FL("BTCoex Mode operation in progress"));
5077 return VOS_TRUE;
c_hpothu9b781ba2013-12-30 20:57:45 +05305078 }
5079
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08005080 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
5081
5082 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
5083 {
5084 pAdapter = pAdapterNode->pAdapter;
5085
5086 if( pAdapter )
5087 {
5088 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05305089 "%s: Adapter with device mode %s (%d) exists",
5090 __func__, hdd_device_modetoString(pAdapter->device_mode),
5091 pAdapter->device_mode);
Rashmi Ramannab1429032014-04-26 14:59:09 +05305092 if (((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
5093 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
5094 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode)) &&
5095 (eConnectionState_Connecting ==
5096 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
5097 {
5098 hddLog(VOS_TRACE_LEVEL_ERROR,
5099 "%s: %p(%d) Connection is in progress", __func__,
5100 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
5101 return VOS_TRUE;
5102 }
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08005103 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05305104 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
5105 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08005106 {
5107 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
5108 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05305109 (VOS_FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08005110 {
5111 staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]);
5112 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain24bafea2013-11-15 15:10:03 -08005113 "%s: client " MAC_ADDRESS_STR
5114 " is in the middle of WPS/EAPOL exchange.", __func__,
5115 MAC_ADDR_ARRAY(staMac));
Rashmi Ramannab1429032014-04-26 14:59:09 +05305116 return VOS_TRUE;
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08005117 }
5118 }
5119 else if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) ||
5120 (WLAN_HDD_P2P_GO == pAdapter->device_mode))
5121 {
5122 for (staId = 0; staId < WLAN_MAX_STA_COUNT; staId++)
5123 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305124 if ((pAdapter->aStaInfo[staId].isUsed) &&
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08005125 (WLANTL_STA_CONNECTED == pAdapter->aStaInfo[staId].tlSTAState))
5126 {
5127 staMac = (v_U8_t *) &(pAdapter->aStaInfo[staId].macAddrSTA.bytes[0]);
5128
5129 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain24bafea2013-11-15 15:10:03 -08005130 "%s: client " MAC_ADDRESS_STR " of SoftAP/P2P-GO is in the "
5131 "middle of WPS/EAPOL exchange.", __func__,
5132 MAC_ADDR_ARRAY(staMac));
Rashmi Ramannab1429032014-04-26 14:59:09 +05305133 return VOS_TRUE;
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08005134 }
5135 }
5136 }
5137 }
5138 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
5139 pAdapterNode = pNext;
5140 }
Rashmi Ramannab1429032014-04-26 14:59:09 +05305141 return VOS_FALSE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305142}
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08005143
5144/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +05305145 * FUNCTION: __wlan_hdd_cfg80211_scan
Jeff Johnson295189b2012-06-20 16:38:30 -07005146 * this scan respond to scan trigger and update cfg80211 scan database
5147 * later, scan dump command can be used to recieve scan results
5148 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +05305149int __wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -08005150#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
5151 struct net_device *dev,
5152#endif
5153 struct cfg80211_scan_request *request)
5154{
Siddharth Bhal0c162d02014-05-06 19:50:42 +05305155 hdd_adapter_t *pAdapter = NULL;
5156 hdd_context_t *pHddCtx = NULL;
5157 hdd_wext_state_t *pwextBuf = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305158 hdd_config_t *cfg_param = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07005159 tCsrScanRequest scanRequest;
5160 tANI_U8 *channelList = NULL, i;
5161 v_U32_t scanId = 0;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305162 int status;
5163 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07005164 v_U8_t* pP2pIe = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07005165
Siddharth Bhal0c162d02014-05-06 19:50:42 +05305166#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
5167 struct net_device *dev = NULL;
5168 if (NULL == request)
5169 {
5170 hddLog(VOS_TRACE_LEVEL_ERROR,
5171 "%s: scan req param null", __func__);
5172 return -EINVAL;
5173 }
5174 dev = request->wdev->netdev;
5175#endif
5176
5177 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
5178 pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
5179 pwextBuf = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
5180
Jeff Johnson295189b2012-06-20 16:38:30 -07005181 ENTER();
5182
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05305183
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05305184 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
5185 __func__, hdd_device_modetoString(pAdapter->device_mode),
5186 pAdapter->device_mode);
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08005187
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305188 status = wlan_hdd_validate_context(pHddCtx);
5189
5190 if (0 != status)
5191 {
5192 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5193 "%s: HDD context is not valid", __func__);
5194 return status;
5195 }
5196
Siddharth Bhal0c162d02014-05-06 19:50:42 +05305197 if (NULL == pwextBuf)
5198 {
5199 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: invalid WEXT state\n",
5200 __func__);
5201 return -EIO;
5202 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305203 cfg_param = pHddCtx->cfg_ini;
5204 pScanInfo = &pHddCtx->scan_info;
5205
Jeff Johnson295189b2012-06-20 16:38:30 -07005206#ifdef WLAN_BTAMP_FEATURE
5207 //Scan not supported when AMP traffic is on.
Gopichand Nakkala681989c2013-03-06 22:27:48 -08005208 if (VOS_TRUE == WLANBAP_AmpSessionOn())
Jeff Johnson295189b2012-06-20 16:38:30 -07005209 {
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08005210 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07005211 "%s: No scanning when AMP is on", __func__);
5212 return -EOPNOTSUPP;
5213 }
5214#endif
5215 //Scan on any other interface is not supported.
Gopichand Nakkala681989c2013-03-06 22:27:48 -08005216 if (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07005217 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -08005218 hddLog(VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05305219 "%s: Not scanning on device_mode = %s (%d)",
5220 __func__, hdd_device_modetoString(pAdapter->device_mode),
5221 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07005222 return -EOPNOTSUPP;
5223 }
5224
5225 if (TRUE == pScanInfo->mScanPending)
5226 {
Kiet Lamac06e2c2013-10-23 16:25:07 +05305227 if ( MAX_PENDING_LOG > pScanInfo->mScanPendingCounter++ )
5228 {
5229 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: mScanPending is TRUE", __func__);
5230 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08005231 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -07005232 }
5233
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305234 //Don't Allow Scan and return busy if Remain On
Jeff Johnson32d95a32012-09-10 13:15:23 -07005235 //Channel and action frame is pending
5236 //Otherwise Cancel Remain On Channel and allow Scan
5237 //If no action frame pending
Gopichand Nakkala681989c2013-03-06 22:27:48 -08005238 if (0 != wlan_hdd_check_remain_on_channel(pAdapter))
Jeff Johnson32d95a32012-09-10 13:15:23 -07005239 {
Kiet Lamac06e2c2013-10-23 16:25:07 +05305240 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Remain On Channel Pending", __func__);
Jeff Johnson32d95a32012-09-10 13:15:23 -07005241 return -EBUSY;
5242 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08005243#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07005244 /* if tdls disagree scan right now, return immediately.
5245 tdls will schedule the scan when scan is allowed. (return SUCCESS)
5246 or will reject the scan if any TDLS is in progress. (return -EBUSY)
5247 */
5248 status = wlan_hdd_tdls_scan_callback (pAdapter,
5249 wiphy,
5250#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
5251 dev,
Gopichand Nakkalac3c42b92013-03-20 19:42:34 -07005252#endif
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07005253 request);
5254 if(status <= 0)
5255 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05305256 if(!status)
5257 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS in progress."
5258 "scan rejected %d", __func__, status);
5259 else
5260 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS teardown is ongoing %d",
5261 __func__, status);
5262
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07005263 return status;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08005264 }
5265#endif
Jeff Johnson32d95a32012-09-10 13:15:23 -07005266
Jeff Johnson295189b2012-06-20 16:38:30 -07005267 if (mutex_lock_interruptible(&pHddCtx->tmInfo.tmOperationLock))
5268 {
5269 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_ERROR,
Jeff Johnson1250df42012-12-10 14:31:52 -08005270 "%s: Acquire lock fail", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005271 return -EAGAIN;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305272 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005273 if (TRUE == pHddCtx->tmInfo.tmAction.enterImps)
5274 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05305275 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07005276 "%s: MAX TM Level Scan not allowed", __func__);
5277 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305278 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -07005279 }
5280 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
5281
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08005282 /* Check if scan is allowed at this point of time.
5283 */
Rashmi Ramannab1429032014-04-26 14:59:09 +05305284 if (hdd_isConnectionInProgress(pHddCtx))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08005285 {
5286 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Scan not allowed", __func__);
5287 return -EBUSY;
5288 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305289
Jeff Johnson295189b2012-06-20 16:38:30 -07005290 vos_mem_zero( &scanRequest, sizeof(scanRequest));
5291
5292 if (NULL != request)
5293 {
Siddharth Bhal0c162d02014-05-06 19:50:42 +05305294 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
5295 TRACE_CODE_HDD_CFG80211_SCAN,
5296 pAdapter->sessionId, request->n_channels));
Jeff Johnson295189b2012-06-20 16:38:30 -07005297 hddLog(VOS_TRACE_LEVEL_INFO, "scan request for ssid = %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305298 (int)request->n_ssids);
Jeff Johnson295189b2012-06-20 16:38:30 -07005299
5300 /* Even though supplicant doesn't provide any SSIDs, n_ssids is set to 1.
5301 * Becasue of this, driver is assuming that this is not wildcard scan and so
5302 * is not aging out the scan results.
5303 */
Jeff Johnson32d95a32012-09-10 13:15:23 -07005304 if (request->ssids && '\0' == request->ssids->ssid[0])
Jeff Johnson295189b2012-06-20 16:38:30 -07005305 {
5306 request->n_ssids = 0;
5307 }
5308
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07005309 if ((request->ssids) && (0 < request->n_ssids))
Jeff Johnson295189b2012-06-20 16:38:30 -07005310 {
5311 tCsrSSIDInfo *SsidInfo;
5312 int j;
5313 scanRequest.SSIDs.numOfSSIDs = request->n_ssids;
5314 /* Allocate num_ssid tCsrSSIDInfo structure */
5315 SsidInfo = scanRequest.SSIDs.SSIDList =
5316 ( tCsrSSIDInfo *)vos_mem_malloc(
5317 request->n_ssids*sizeof(tCsrSSIDInfo));
5318
5319 if(NULL == scanRequest.SSIDs.SSIDList)
5320 {
5321 hddLog(VOS_TRACE_LEVEL_ERROR,
Nirav Shah20ac06f2013-12-12 18:14:06 +05305322 "%s: memory alloc failed SSIDInfo buffer", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005323 return -ENOMEM;
5324 }
5325
5326 /* copy all the ssid's and their length */
5327 for(j = 0; j < request->n_ssids; j++, SsidInfo++)
5328 {
5329 /* get the ssid length */
5330 SsidInfo->SSID.length = request->ssids[j].ssid_len;
5331 vos_mem_copy(SsidInfo->SSID.ssId, &request->ssids[j].ssid[0],
5332 SsidInfo->SSID.length);
5333 SsidInfo->SSID.ssId[SsidInfo->SSID.length] = '\0';
Nirav Shah20ac06f2013-12-12 18:14:06 +05305334 hddLog(VOS_TRACE_LEVEL_INFO, "SSID number %d: %s",
Jeff Johnson295189b2012-06-20 16:38:30 -07005335 j, SsidInfo->SSID.ssId);
5336 }
5337 /* set the scan type to active */
5338 scanRequest.scanType = eSIR_ACTIVE_SCAN;
5339 }
5340 else if(WLAN_HDD_P2P_GO == pAdapter->device_mode)
5341 {
5342 /* set the scan type to active */
5343 scanRequest.scanType = eSIR_ACTIVE_SCAN;
5344 }
5345 else
5346 {
5347 /*Set the scan type to default type, in this case it is ACTIVE*/
5348 scanRequest.scanType = pScanInfo->scan_mode;
5349 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305350 scanRequest.minChnTime = cfg_param->nActiveMinChnTime;
Jeff Johnson295189b2012-06-20 16:38:30 -07005351 scanRequest.maxChnTime = cfg_param->nActiveMaxChnTime;
5352 }
5353 else
5354 {
Siddharth Bhal0c162d02014-05-06 19:50:42 +05305355 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
5356 TRACE_CODE_HDD_CFG80211_SCAN,
5357 pAdapter->sessionId, 0));
Jeff Johnson295189b2012-06-20 16:38:30 -07005358 /* set the scan type to active */
5359 scanRequest.scanType = eSIR_ACTIVE_SCAN;
5360 vos_mem_set( scanRequest.bssid, sizeof( tCsrBssid ), 0xff );
5361
5362 /* set min and max channel time to zero */
5363 scanRequest.minChnTime = 0;
5364 scanRequest.maxChnTime = 0;
5365 }
5366
5367 /* set BSSType to default type */
5368 scanRequest.BSSType = eCSR_BSS_TYPE_ANY;
5369
5370 /*TODO: scan the requested channels only*/
5371
5372 /*Right now scanning all the channels */
5373 if( request )
5374 {
c_hpothu53512302014-04-15 18:49:53 +05305375 if (MAX_CHANNEL < request->n_channels)
5376 {
5377 hddLog(VOS_TRACE_LEVEL_WARN,
5378 "No of Scan Channels exceeded limit: %d", request->n_channels);
5379 request->n_channels = MAX_CHANNEL;
5380 }
Nirav Shah20ac06f2013-12-12 18:14:06 +05305381 hddLog(VOS_TRACE_LEVEL_INFO,
5382 "No of Scan Channels: %d", request->n_channels);
c_hpothu53512302014-04-15 18:49:53 +05305383
Jeff Johnson295189b2012-06-20 16:38:30 -07005384 if( request->n_channels )
5385 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05305386 char chList [(request->n_channels*5)+1];
5387 int len;
Jeff Johnson295189b2012-06-20 16:38:30 -07005388 channelList = vos_mem_malloc( request->n_channels );
5389 if( NULL == channelList )
5390 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305391 hddLog(VOS_TRACE_LEVEL_ERROR,
Nirav Shah20ac06f2013-12-12 18:14:06 +05305392 "%s: memory alloc failed channelList", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005393 status = -ENOMEM;
5394 goto free_mem;
5395 }
5396
Nirav Shah20ac06f2013-12-12 18:14:06 +05305397 for( i = 0, len = 0; i < request->n_channels ; i++ )
5398 {
Jeff Johnson295189b2012-06-20 16:38:30 -07005399 channelList[i] = request->channels[i]->hw_value;
Nirav Shah20ac06f2013-12-12 18:14:06 +05305400 len += snprintf(chList+len, 5, "%d ", channelList[i]);
5401 }
5402
5403 hddLog(VOS_TRACE_LEVEL_INFO,
5404 "Channel-List: %s ", chList);
Jeff Johnson295189b2012-06-20 16:38:30 -07005405 }
5406
5407 scanRequest.ChannelInfo.numOfChannels = request->n_channels;
5408 scanRequest.ChannelInfo.ChannelList = channelList;
5409
5410 /* set requestType to full scan */
5411 scanRequest.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305412
5413 /* Flush the scan results(only p2p beacons) for STA scan and P2P
Madan Mohan Koyyalamudi8d50f312012-11-27 15:48:57 -08005414 * search (Flush on both full scan and social scan but not on single
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305415 * channel scan).P2P search happens on 3 social channels (1, 6, 11)
Madan Mohan Koyyalamudi8d50f312012-11-27 15:48:57 -08005416 */
5417
5418 /* Supplicant does single channel scan after 8-way handshake
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305419 * and in that case driver shoudnt flush scan results. If
5420 * driver flushes the scan results here and unfortunately if
5421 * the AP doesnt respond to our probe req then association
Madan Mohan Koyyalamudi8d50f312012-11-27 15:48:57 -08005422 * fails which is not desired
5423 */
5424
5425 if( request->n_channels != WLAN_HDD_P2P_SINGLE_CHANNEL_SCAN )
5426 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05305427 hddLog(VOS_TRACE_LEVEL_DEBUG, "Flushing P2P Results");
Madan Mohan Koyyalamudi8d50f312012-11-27 15:48:57 -08005428 sme_ScanFlushP2PResult( WLAN_HDD_GET_HAL_CTX(pAdapter),
5429 pAdapter->sessionId );
5430 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005431
5432 if( request->ie_len )
5433 {
5434 /* save this for future association (join requires this) */
Agarwal Ashish4f616132013-12-30 23:32:50 +05305435 /*TODO: Array needs to be converted to dynamic allocation,
5436 * as multiple ie.s can be sent in cfg80211_scan_request structure
5437 * CR 597966
5438 */
Jeff Johnson295189b2012-06-20 16:38:30 -07005439 memset( &pScanInfo->scanAddIE, 0, sizeof(pScanInfo->scanAddIE) );
5440 memcpy( pScanInfo->scanAddIE.addIEdata, request->ie, request->ie_len);
5441 pScanInfo->scanAddIE.length = request->ie_len;
5442
Agarwal Ashish4f616132013-12-30 23:32:50 +05305443 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Jeff Johnsone7245742012-09-05 17:12:55 -07005444 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
Agarwal Ashish4f616132013-12-30 23:32:50 +05305445 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -07005446 {
Agarwal Ashish4f616132013-12-30 23:32:50 +05305447 if ( request->ie_len <= SIR_MAC_MAX_IE_LENGTH)
5448 {
5449 pwextBuf->roamProfile.nAddIEScanLength = request->ie_len;
5450 memcpy( pwextBuf->roamProfile.addIEScan,
5451 request->ie, request->ie_len);
5452 }
5453 else
5454 {
5455 hddLog(VOS_TRACE_LEVEL_ERROR, "Scan Ie length is invalid:"
Arun Kumar Khandavalli75eeb122014-03-27 21:43:12 +05305456 "%zu", request->ie_len);
Agarwal Ashish4f616132013-12-30 23:32:50 +05305457 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005458
Agarwal Ashish4f616132013-12-30 23:32:50 +05305459 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005460 scanRequest.uIEFieldLen = pScanInfo->scanAddIE.length;
5461 scanRequest.pIEField = pScanInfo->scanAddIE.addIEdata;
5462
Jeff Johnson295189b2012-06-20 16:38:30 -07005463 pP2pIe = wlan_hdd_get_p2p_ie_ptr((v_U8_t*)request->ie,
5464 request->ie_len);
5465 if (pP2pIe != NULL)
5466 {
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07005467#ifdef WLAN_FEATURE_P2P_DEBUG
5468 if (((globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED) ||
5469 (globalP2PConnectionStatus == P2P_GO_NEG_PROCESS)) &&
5470 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
5471 {
5472 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_1;
5473 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
5474 "Go nego completed to Connection is started");
5475 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
5476 "for 8way Handshake");
5477 }
5478 else if((globalP2PConnectionStatus == P2P_CLIENT_DISCONNECTED_STATE) &&
5479 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
5480 {
5481 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_2;
5482 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
5483 "Disconnected state to Connection is started");
5484 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
5485 "for 4way Handshake");
5486 }
5487#endif
5488
Jeff Johnsone7245742012-09-05 17:12:55 -07005489 /* no_cck will be set during p2p find to disable 11b rates */
5490 if(TRUE == request->no_cck)
Jeff Johnson295189b2012-06-20 16:38:30 -07005491 {
Jeff Johnson295189b2012-06-20 16:38:30 -07005492 hddLog(VOS_TRACE_LEVEL_INFO,
5493 "%s: This is a P2P Search", __func__);
5494 scanRequest.p2pSearch = 1;
Jeff Johnsone7245742012-09-05 17:12:55 -07005495
Jeff Johnsone7245742012-09-05 17:12:55 -07005496 if( request->n_channels == WLAN_HDD_P2P_SOCIAL_CHANNELS )
5497 {
Madan Mohan Koyyalamudi1b1d9e82012-10-21 11:38:33 -07005498 /* set requestType to P2P Discovery */
5499 scanRequest.requestType = eCSR_SCAN_P2P_DISCOVERY;
Jeff Johnsone7245742012-09-05 17:12:55 -07005500 }
5501
5502 /*
5503 Skip Dfs Channel in case of P2P Search
5504 if it is set in ini file
5505 */
5506 if(cfg_param->skipDfsChnlInP2pSearch)
5507 {
5508 scanRequest.skipDfsChnlInP2pSearch = 1;
5509 }
5510 else
5511 {
5512 scanRequest.skipDfsChnlInP2pSearch = 0;
5513 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005514
Jeff Johnson295189b2012-06-20 16:38:30 -07005515 }
5516 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005517 }
5518 }
5519
5520 INIT_COMPLETION(pScanInfo->scan_req_completion_event);
5521
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07005522 /* acquire the wakelock to avoid the apps suspend during the scan. To
5523 * address the following issues.
5524 * 1) Disconnected scenario: we are not allowing the suspend as WLAN is not in
5525 * BMPS/IMPS this result in android trying to suspend aggressively and backing off
5526 * for long time, this result in apps running at full power for long time.
5527 * 2) Connected scenario: If we allow the suspend during the scan, RIVA will
5528 * be stuck in full power because of resume BMPS
5529 */
5530 hdd_prevent_suspend();
Jeff Johnsone7245742012-09-05 17:12:55 -07005531
Nirav Shah20ac06f2013-12-12 18:14:06 +05305532 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
5533 "requestType %d, scanType %d, minChnTime %d, maxChnTime %d,"
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05305534 "p2pSearch %d, skipDfsChnlInP2pSearch %d",
5535 scanRequest.requestType, scanRequest.scanType,
5536 scanRequest.minChnTime, scanRequest.maxChnTime,
Nirav Shah20ac06f2013-12-12 18:14:06 +05305537 scanRequest.p2pSearch, scanRequest.skipDfsChnlInP2pSearch);
5538
Jeff Johnsone7245742012-09-05 17:12:55 -07005539 status = sme_ScanRequest( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07005540 pAdapter->sessionId, &scanRequest, &scanId,
5541 &hdd_cfg80211_scan_done_callback, dev );
Jeff Johnsone7245742012-09-05 17:12:55 -07005542
Jeff Johnson295189b2012-06-20 16:38:30 -07005543 if (eHAL_STATUS_SUCCESS != status)
5544 {
5545 hddLog(VOS_TRACE_LEVEL_ERROR,
5546 "%s: sme_ScanRequest returned error %d", __func__, status);
5547 complete(&pScanInfo->scan_req_completion_event);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -07005548 if(eHAL_STATUS_RESOURCES == status)
5549 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05305550 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: HO is in progress."
5551 "So defer the scan by informing busy",__func__);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -07005552 status = -EBUSY;
5553 } else {
5554 status = -EIO;
5555 }
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07005556 hdd_allow_suspend();
Jeff Johnson295189b2012-06-20 16:38:30 -07005557 goto free_mem;
5558 }
5559
5560 pScanInfo->mScanPending = TRUE;
5561 pAdapter->request = request;
5562 pScanInfo->scanId = scanId;
5563
5564 complete(&pScanInfo->scan_req_completion_event);
5565
5566free_mem:
5567 if( scanRequest.SSIDs.SSIDList )
5568 {
5569 vos_mem_free(scanRequest.SSIDs.SSIDList);
5570 }
5571
5572 if( channelList )
5573 vos_mem_free( channelList );
5574
5575 EXIT();
5576
5577 return status;
5578}
5579
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +05305580int wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
5581#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
5582 struct net_device *dev,
5583#endif
5584 struct cfg80211_scan_request *request)
5585{
5586 int ret;
5587
5588 vos_ssr_protect(__func__);
5589 ret = __wlan_hdd_cfg80211_scan(wiphy,
5590#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
5591 dev,
5592#endif
5593 request);
5594 vos_ssr_unprotect(__func__);
5595
5596 return ret;
5597}
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07005598
5599void hdd_select_cbmode( hdd_adapter_t *pAdapter,v_U8_t operationChannel)
5600{
5601 v_U8_t iniDot11Mode =
5602 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->dot11Mode;
5603 eHddDot11Mode hddDot11Mode = iniDot11Mode;
5604
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +05305605 hddLog(LOG1, FL("Channel Bonding Mode Selected is %u"),
5606 iniDot11Mode);
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07005607 switch ( iniDot11Mode )
5608 {
5609 case eHDD_DOT11_MODE_AUTO:
5610 case eHDD_DOT11_MODE_11ac:
5611 case eHDD_DOT11_MODE_11ac_ONLY:
5612#ifdef WLAN_FEATURE_11AC
5613 hddDot11Mode = eHDD_DOT11_MODE_11ac;
5614#else
5615 hddDot11Mode = eHDD_DOT11_MODE_11n;
5616#endif
5617 break;
5618 case eHDD_DOT11_MODE_11n:
5619 case eHDD_DOT11_MODE_11n_ONLY:
5620 hddDot11Mode = eHDD_DOT11_MODE_11n;
5621 break;
5622 default:
5623 hddDot11Mode = iniDot11Mode;
5624 break;
5625 }
5626 /* This call decides required channel bonding mode */
5627 sme_SelectCBMode((WLAN_HDD_GET_CTX(pAdapter)->hHal),
5628 hdd_cfg_xlate_to_csr_phy_mode(hddDot11Mode),
5629 operationChannel);
5630}
5631
Jeff Johnson295189b2012-06-20 16:38:30 -07005632/*
5633 * FUNCTION: wlan_hdd_cfg80211_connect_start
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305634 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -07005635 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305636int wlan_hdd_cfg80211_connect_start( hdd_adapter_t *pAdapter,
Jeff Johnson32d95a32012-09-10 13:15:23 -07005637 const u8 *ssid, size_t ssid_len, const u8 *bssid, u8 operatingChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -07005638{
5639 int status = 0;
5640 hdd_wext_state_t *pWextState;
Yue Mae36e3552014-03-05 17:06:20 -08005641 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07005642 v_U32_t roamId;
5643 tCsrRoamProfile *pRoamProfile;
Jeff Johnson295189b2012-06-20 16:38:30 -07005644 eCsrAuthType RSNAuthType;
5645
5646 ENTER();
5647
5648 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Yue Mae36e3552014-03-05 17:06:20 -08005649 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
5650
5651 status = wlan_hdd_validate_context(pHddCtx);
5652 if (status)
5653 {
5654 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5655 "%s: HDD context is not valid!", __func__);
5656 return status;
5657 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305658
Jeff Johnson295189b2012-06-20 16:38:30 -07005659 if (SIR_MAC_MAX_SSID_LENGTH < ssid_len)
5660 {
5661 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wrong SSID len", __func__);
5662 return -EINVAL;
5663 }
5664
5665 pRoamProfile = &pWextState->roamProfile;
5666
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305667 if (pRoamProfile)
Jeff Johnson295189b2012-06-20 16:38:30 -07005668 {
Jeff Johnsone7245742012-09-05 17:12:55 -07005669 hdd_station_ctx_t *pHddStaCtx;
5670 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07005671
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305672 if (HDD_WMM_USER_MODE_NO_QOS ==
Jeff Johnson295189b2012-06-20 16:38:30 -07005673 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->WmmMode)
5674 {
5675 /*QoS not enabled in cfg file*/
5676 pRoamProfile->uapsd_mask = 0;
5677 }
5678 else
5679 {
5680 /*QoS enabled, update uapsd mask from cfg file*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305681 pRoamProfile->uapsd_mask =
Jeff Johnson295189b2012-06-20 16:38:30 -07005682 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask;
5683 }
5684
5685 pRoamProfile->SSIDs.numOfSSIDs = 1;
5686 pRoamProfile->SSIDs.SSIDList->SSID.length = ssid_len;
5687 vos_mem_zero(pRoamProfile->SSIDs.SSIDList->SSID.ssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305688 sizeof(pRoamProfile->SSIDs.SSIDList->SSID.ssId));
Jeff Johnson295189b2012-06-20 16:38:30 -07005689 vos_mem_copy((void *)(pRoamProfile->SSIDs.SSIDList->SSID.ssId),
5690 ssid, ssid_len);
5691
5692 if (bssid)
5693 {
5694 pRoamProfile->BSSIDs.numOfBSSIDs = 1;
5695 vos_mem_copy((void *)(pRoamProfile->BSSIDs.bssid), bssid,
5696 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305697 /* Save BSSID in seperate variable as well, as RoamProfile
5698 BSSID is getting zeroed out in the association process. And in
Jeff Johnson295189b2012-06-20 16:38:30 -07005699 case of join failure we should send valid BSSID to supplicant
5700 */
5701 vos_mem_copy((void *)(pWextState->req_bssId), bssid,
5702 WNI_CFG_BSSID_LEN);
5703 }
Dhanashri Atre51981c62013-06-13 11:47:57 -07005704 else
5705 {
5706 vos_mem_zero((void *)(pRoamProfile->BSSIDs.bssid),WNI_CFG_BSSID_LEN);
5707 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005708
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +05305709 hddLog(LOG1, FL("Connect to SSID: %s opertating Channel: %u"),
5710 pRoamProfile->SSIDs.SSIDList->SSID.ssId, operatingChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -07005711 if ((IW_AUTH_WPA_VERSION_WPA == pWextState->wpaVersion) ||
5712 (IW_AUTH_WPA_VERSION_WPA2 == pWextState->wpaVersion))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305713 {
Jeff Johnson295189b2012-06-20 16:38:30 -07005714 /*set gen ie*/
5715 hdd_SetGENIEToCsr(pAdapter, &RSNAuthType);
5716 /*set auth*/
5717 hdd_set_csr_auth_type(pAdapter, RSNAuthType);
5718 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005719#ifdef FEATURE_WLAN_WAPI
5720 if (pAdapter->wapi_info.nWapiMode)
5721 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005722 hddLog(LOG1, "%s: Setting WAPI AUTH Type and Encryption Mode values", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005723 switch (pAdapter->wapi_info.wapiAuthMode)
5724 {
5725 case WAPI_AUTH_MODE_PSK:
5726 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005727 hddLog(LOG1, "%s: WAPI AUTH TYPE: PSK: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07005728 pAdapter->wapi_info.wapiAuthMode);
5729 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_PSK;
5730 break;
5731 }
5732 case WAPI_AUTH_MODE_CERT:
5733 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005734 hddLog(LOG1, "%s: WAPI AUTH TYPE: CERT: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07005735 pAdapter->wapi_info.wapiAuthMode);
5736 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE;
5737 break;
5738 }
5739 } // End of switch
5740 if ( pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_PSK ||
5741 pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_CERT)
5742 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005743 hddLog(LOG1, "%s: WAPI PAIRWISE/GROUP ENCRYPTION: WPI", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005744 pRoamProfile->AuthType.numEntries = 1;
5745 pRoamProfile->EncryptionType.numEntries = 1;
5746 pRoamProfile->EncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
5747 pRoamProfile->mcEncryptionType.numEntries = 1;
5748 pRoamProfile->mcEncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
5749 }
5750 }
5751#endif /* FEATURE_WLAN_WAPI */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05305752#ifdef WLAN_FEATURE_GTK_OFFLOAD
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05305753 /* Initializing gtkOffloadReqParams */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05305754 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
5755 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
5756 {
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05305757 memset(&pHddStaCtx->gtkOffloadReqParams, 0,
5758 sizeof (tSirGtkOffloadParams));
5759 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_DISABLE;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05305760 }
5761#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005762 pRoamProfile->csrPersona = pAdapter->device_mode;
5763
Jeff Johnson32d95a32012-09-10 13:15:23 -07005764 if( operatingChannel )
5765 {
5766 pRoamProfile->ChannelInfo.ChannelList = &operatingChannel;
5767 pRoamProfile->ChannelInfo.numOfChannels = 1;
5768 }
Chet Lanctot186b5732013-03-18 10:26:30 -07005769 else
5770 {
5771 pRoamProfile->ChannelInfo.ChannelList = NULL;
5772 pRoamProfile->ChannelInfo.numOfChannels = 0;
5773 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07005774 if ( (WLAN_HDD_IBSS == pAdapter->device_mode) && operatingChannel)
5775 {
5776 hdd_select_cbmode(pAdapter,operatingChannel);
5777 }
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +05305778
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08005779 /* change conn_state to connecting before sme_RoamConnect(), because sme_RoamConnect()
5780 * has a direct path to call hdd_smeRoamCallback(), which will change the conn_state
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305781 * If direct path, conn_state will be accordingly changed to NotConnected or Associated
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08005782 * by either hdd_AssociationCompletionHandler() or hdd_DisConnectHandler() in sme_RoamCallback()
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -08005783 * if sme_RomConnect is to be queued, Connecting state will remain until it is completed.
5784 */
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05305785 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
5786 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode)
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -08005787 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
5788 eConnectionState_Connecting);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305789
5790 status = sme_RoamConnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07005791 pAdapter->sessionId, pRoamProfile, &roamId);
5792
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05305793 if ((eHAL_STATUS_SUCCESS != status) &&
5794 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
5795 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +05305796
5797 {
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08005798 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: sme_RoamConnect (session %d) failed with "
5799 "status %d. -> NotConnected", __func__, pAdapter->sessionId, status);
5800 /* change back to NotAssociated */
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +05305801 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08005802 eConnectionState_NotConnected);
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +05305803 }
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -08005804
5805 pRoamProfile->ChannelInfo.ChannelList = NULL;
5806 pRoamProfile->ChannelInfo.numOfChannels = 0;
5807
Jeff Johnson295189b2012-06-20 16:38:30 -07005808 }
5809 else
5810 {
5811 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid Roam profile", __func__);
5812 return -EINVAL;
5813 }
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08005814 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07005815 return status;
5816}
5817
5818/*
5819 * FUNCTION: wlan_hdd_set_cfg80211_auth_type
5820 * This function is used to set the authentication type (OPEN/SHARED).
5821 *
5822 */
5823static int wlan_hdd_cfg80211_set_auth_type(hdd_adapter_t *pAdapter,
5824 enum nl80211_auth_type auth_type)
5825{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305826 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07005827 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
5828
5829 ENTER();
5830
5831 /*set authentication type*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305832 switch (auth_type)
Jeff Johnson295189b2012-06-20 16:38:30 -07005833 {
Jeff Johnson295189b2012-06-20 16:38:30 -07005834 case NL80211_AUTHTYPE_AUTOMATIC:
Gopichand Nakkala29149562013-05-10 21:43:41 +05305835 hddLog(VOS_TRACE_LEVEL_INFO,
5836 "%s: set authentication type to AUTOSWITCH", __func__);
5837 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_AUTOSWITCH;
5838 break;
5839
5840 case NL80211_AUTHTYPE_OPEN_SYSTEM:
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07005841#ifdef WLAN_FEATURE_VOWIFI_11R
5842 case NL80211_AUTHTYPE_FT:
5843#endif /* WLAN_FEATURE_VOWIFI_11R */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305844 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -07005845 "%s: set authentication type to OPEN", __func__);
5846 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
5847 break;
5848
5849 case NL80211_AUTHTYPE_SHARED_KEY:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305850 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -07005851 "%s: set authentication type to SHARED", __func__);
5852 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_SHARED_KEY;
5853 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005854#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -07005855 case NL80211_AUTHTYPE_NETWORK_EAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305856 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -07005857 "%s: set authentication type to CCKM WPA", __func__);
5858 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_CCKM_WPA;//eCSR_AUTH_TYPE_CCKM_RSN needs to be handled as well if required.
5859 break;
5860#endif
5861
5862
5863 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305864 hddLog(VOS_TRACE_LEVEL_ERROR,
5865 "%s: Unsupported authentication type %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07005866 auth_type);
5867 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_UNKNOWN;
5868 return -EINVAL;
5869 }
5870
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305871 pWextState->roamProfile.AuthType.authType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -07005872 pHddStaCtx->conn_info.authType;
5873 return 0;
5874}
5875
5876/*
5877 * FUNCTION: wlan_hdd_set_akm_suite
5878 * This function is used to set the key mgmt type(PSK/8021x).
5879 *
5880 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305881static int wlan_hdd_set_akm_suite( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07005882 u32 key_mgmt
5883 )
5884{
5885 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
5886 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305887
Jeff Johnson295189b2012-06-20 16:38:30 -07005888 /*set key mgmt type*/
5889 switch(key_mgmt)
5890 {
5891 case WLAN_AKM_SUITE_PSK:
Gopichand Nakkala356fb102013-03-06 12:34:04 +05305892#ifdef WLAN_FEATURE_VOWIFI_11R
5893 case WLAN_AKM_SUITE_FT_PSK:
5894#endif
5895 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to PSK",
Jeff Johnson295189b2012-06-20 16:38:30 -07005896 __func__);
5897 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_PSK;
5898 break;
5899
5900 case WLAN_AKM_SUITE_8021X:
Gopichand Nakkala356fb102013-03-06 12:34:04 +05305901#ifdef WLAN_FEATURE_VOWIFI_11R
5902 case WLAN_AKM_SUITE_FT_8021X:
5903#endif
5904 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to 8021x",
Jeff Johnson295189b2012-06-20 16:38:30 -07005905 __func__);
5906 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
5907 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005908#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -07005909#define WLAN_AKM_SUITE_CCKM 0x00409600 /* Should be in ieee802_11_defs.h */
5910#define IW_AUTH_KEY_MGMT_CCKM 8 /* Should be in linux/wireless.h */
5911 case WLAN_AKM_SUITE_CCKM:
5912 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to CCKM",
5913 __func__);
5914 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_CCKM;
5915 break;
5916#endif
Leela Venkata Kiran Kumar Reddy Chiralae208a832014-04-27 22:34:25 -07005917#ifndef WLAN_AKM_SUITE_OSEN
5918#define WLAN_AKM_SUITE_OSEN 0x506f9a01 /* Should be in ieee802_11_defs.h */
5919 case WLAN_AKM_SUITE_OSEN:
5920 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to OSEN",
5921 __func__);
5922 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
5923 break;
5924#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005925
5926 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305927 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported key mgmt type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07005928 __func__, key_mgmt);
5929 return -EINVAL;
5930
5931 }
5932 return 0;
5933}
5934
5935/*
5936 * FUNCTION: wlan_hdd_cfg80211_set_cipher
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305937 * This function is used to set the encryption type
Jeff Johnson295189b2012-06-20 16:38:30 -07005938 * (NONE/WEP40/WEP104/TKIP/CCMP).
5939 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305940static int wlan_hdd_cfg80211_set_cipher( hdd_adapter_t *pAdapter,
5941 u32 cipher,
Jeff Johnson295189b2012-06-20 16:38:30 -07005942 bool ucast
5943 )
5944{
5945 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305946 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07005947 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
5948
5949 ENTER();
5950
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305951 if (!cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -07005952 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305953 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: received cipher %d - considering none",
Jeff Johnson295189b2012-06-20 16:38:30 -07005954 __func__, cipher);
5955 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
5956 }
5957 else
5958 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305959
Jeff Johnson295189b2012-06-20 16:38:30 -07005960 /*set encryption method*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305961 switch (cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -07005962 {
5963 case IW_AUTH_CIPHER_NONE:
5964 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
5965 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305966
Jeff Johnson295189b2012-06-20 16:38:30 -07005967 case WLAN_CIPHER_SUITE_WEP40:
Gopichand Nakkala29149562013-05-10 21:43:41 +05305968 encryptionType = eCSR_ENCRYPT_TYPE_WEP40;
Jeff Johnson295189b2012-06-20 16:38:30 -07005969 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305970
Jeff Johnson295189b2012-06-20 16:38:30 -07005971 case WLAN_CIPHER_SUITE_WEP104:
Gopichand Nakkala29149562013-05-10 21:43:41 +05305972 encryptionType = eCSR_ENCRYPT_TYPE_WEP104;
Jeff Johnson295189b2012-06-20 16:38:30 -07005973 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305974
Jeff Johnson295189b2012-06-20 16:38:30 -07005975 case WLAN_CIPHER_SUITE_TKIP:
5976 encryptionType = eCSR_ENCRYPT_TYPE_TKIP;
5977 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305978
Jeff Johnson295189b2012-06-20 16:38:30 -07005979 case WLAN_CIPHER_SUITE_CCMP:
5980 encryptionType = eCSR_ENCRYPT_TYPE_AES;
5981 break;
5982#ifdef FEATURE_WLAN_WAPI
5983 case WLAN_CIPHER_SUITE_SMS4:
5984 encryptionType = eCSR_ENCRYPT_TYPE_WPI;
5985 break;
5986#endif
5987
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005988#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -07005989 case WLAN_CIPHER_SUITE_KRK:
5990 encryptionType = eCSR_ENCRYPT_TYPE_KRK;
5991 break;
5992#endif
5993 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305994 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported cipher type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07005995 __func__, cipher);
5996 return -EOPNOTSUPP;
5997 }
5998 }
5999
6000 if (ucast)
6001 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306002 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting unicast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07006003 __func__, encryptionType);
6004 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
6005 pWextState->roamProfile.EncryptionType.numEntries = 1;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306006 pWextState->roamProfile.EncryptionType.encryptionType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -07006007 encryptionType;
6008 }
6009 else
6010 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306011 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting mcast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07006012 __func__, encryptionType);
6013 pHddStaCtx->conn_info.mcEncryptionType = encryptionType;
6014 pWextState->roamProfile.mcEncryptionType.numEntries = 1;
6015 pWextState->roamProfile.mcEncryptionType.encryptionType[0] = encryptionType;
6016 }
6017
6018 return 0;
6019}
6020
6021
6022/*
6023 * FUNCTION: wlan_hdd_cfg80211_set_ie
6024 * This function is used to parse WPA/RSN IE's.
6025 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306026int wlan_hdd_cfg80211_set_ie( hdd_adapter_t *pAdapter,
6027 u8 *ie,
Jeff Johnson295189b2012-06-20 16:38:30 -07006028 size_t ie_len
6029 )
6030{
6031 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
6032 u8 *genie = ie;
6033 v_U16_t remLen = ie_len;
6034#ifdef FEATURE_WLAN_WAPI
6035 v_U32_t akmsuite[MAX_NUM_AKM_SUITES];
6036 u16 *tmp;
6037 v_U16_t akmsuiteCount;
6038 int *akmlist;
6039#endif
6040 ENTER();
6041
6042 /* clear previous assocAddIE */
6043 pWextState->assocAddIE.length = 0;
6044 pWextState->roamProfile.bWPSAssociation = VOS_FALSE;
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -07006045 pWextState->roamProfile.bOSENAssociation = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07006046
6047 while (remLen >= 2)
6048 {
6049 v_U16_t eLen = 0;
6050 v_U8_t elementId;
6051 elementId = *genie++;
6052 eLen = *genie++;
6053 remLen -= 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306054
Arif Hussain6d2a3322013-11-17 19:50:10 -08006055 hddLog(VOS_TRACE_LEVEL_INFO, "%s: IE[0x%X], LEN[%d]",
Jeff Johnson295189b2012-06-20 16:38:30 -07006056 __func__, elementId, eLen);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306057
6058 switch ( elementId )
Jeff Johnson295189b2012-06-20 16:38:30 -07006059 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306060 case DOT11F_EID_WPA:
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07006061 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 -07006062 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306063 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07006064 "%s: Invalid WPA IE", __func__);
6065 return -EINVAL;
6066 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306067 else if (0 == memcmp(&genie[0], "\x00\x50\xf2\x04", 4))
Jeff Johnson295189b2012-06-20 16:38:30 -07006068 {
6069 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306070 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPS IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -07006071 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306072
Jeff Johnson295189b2012-06-20 16:38:30 -07006073 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
6074 {
Jeff Johnson902c9832012-12-10 14:28:09 -08006075 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE. "
6076 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -07006077 VOS_ASSERT(0);
6078 return -ENOMEM;
6079 }
6080 // WSC IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
6081 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
6082 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306083
Jeff Johnson295189b2012-06-20 16:38:30 -07006084 pWextState->roamProfile.bWPSAssociation = VOS_TRUE;
6085 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
6086 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
6087 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306088 else if (0 == memcmp(&genie[0], "\x00\x50\xf2", 3))
6089 {
Jeff Johnson295189b2012-06-20 16:38:30 -07006090 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPA IE (len %d)",__func__, eLen + 2);
6091 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
6092 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2) /*ie_len*/);
6093 pWextState->roamProfile.pWPAReqIE = pWextState->WPARSNIE;
6094 pWextState->roamProfile.nWPAReqIELength = eLen + 2;//ie_len;
6095 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306096 else if ( (0 == memcmp(&genie[0], P2P_OUI_TYPE,
Kiet Lam8da98992013-11-21 15:59:07 +05306097 P2P_OUI_TYPE_SIZE)))
Jeff Johnson295189b2012-06-20 16:38:30 -07006098 {
6099 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306100 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set P2P IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -07006101 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306102
Jeff Johnson295189b2012-06-20 16:38:30 -07006103 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
6104 {
Jeff Johnson902c9832012-12-10 14:28:09 -08006105 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
6106 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -07006107 VOS_ASSERT(0);
6108 return -ENOMEM;
6109 }
6110 // P2P IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
6111 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
6112 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306113
Jeff Johnson295189b2012-06-20 16:38:30 -07006114 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
6115 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
6116 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006117#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306118 else if ( (0 == memcmp(&genie[0], WFD_OUI_TYPE,
6119 WFD_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07006120 /*Consider WFD IE, only for P2P Client */
6121 && (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
6122 {
6123 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306124 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WFD IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -07006125 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306126
Jeff Johnson295189b2012-06-20 16:38:30 -07006127 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
6128 {
Jeff Johnson902c9832012-12-10 14:28:09 -08006129 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
6130 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -07006131 VOS_ASSERT(0);
6132 return -ENOMEM;
6133 }
6134 // WFD IE is saved to Additional IE ; it should be accumulated to handle
6135 // WPS IE + P2P IE + WFD IE
6136 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
6137 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306138
Jeff Johnson295189b2012-06-20 16:38:30 -07006139 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
6140 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
6141 }
6142#endif
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07006143 /* Appending HS 2.0 Indication Element in Assiciation Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306144 else if ( (0 == memcmp(&genie[0], HS20_OUI_TYPE,
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07006145 HS20_OUI_TYPE_SIZE)) )
6146 {
6147 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306148 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set HS20 IE(len %d)",
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07006149 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07006150
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07006151 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
6152 {
Jeff Johnson902c9832012-12-10 14:28:09 -08006153 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
6154 "Need bigger buffer space");
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07006155 VOS_ASSERT(0);
6156 return -ENOMEM;
6157 }
6158 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
6159 pWextState->assocAddIE.length += eLen + 2;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07006160
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07006161 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
6162 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
6163 }
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -07006164 /* Appending OSEN Information Element in Assiciation Request */
6165 else if ( (0 == memcmp(&genie[0], OSEN_OUI_TYPE,
6166 OSEN_OUI_TYPE_SIZE)) )
6167 {
6168 v_U16_t curAddIELen = pWextState->assocAddIE.length;
6169 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set OSEN IE(len %d)",
6170 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07006171
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -07006172 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
6173 {
6174 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
6175 "Need bigger buffer space");
6176 VOS_ASSERT(0);
6177 return -ENOMEM;
6178 }
6179 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
6180 pWextState->assocAddIE.length += eLen + 2;
6181
6182 pWextState->roamProfile.bOSENAssociation = VOS_TRUE;
6183 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
6184 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
6185 }
6186
6187 break;
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -07006188 if (WLAN_HDD_IBSS == pAdapter->device_mode) {
6189
6190 /* populating as ADDIE in beacon frames */
6191 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
6192 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, genie - 2, eLen + 2,
6193 NULL, eANI_BOOLEAN_FALSE)== eHAL_STATUS_SUCCESS)
6194 {
6195 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
6196 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
6197 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
6198 {
6199 hddLog(LOGE,
6200 "Coldn't pass "
6201 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
6202 }
6203 }/* ccmCfgSetStr(,WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, , )*/
6204 else
6205 hddLog(LOGE,
6206 "Could not pass on "
6207 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
6208
6209 /* IBSS mode doesn't contain params->proberesp_ies still
6210 beaconIE's need to be populated in probe response frames */
6211 if ( (NULL != (genie - 2)) && (0 != eLen + 2) )
6212 {
6213 u16 rem_probe_resp_ie_len = eLen + 2;
6214 u8 probe_rsp_ie_len[3] = {0};
6215 u8 counter = 0;
6216
6217 /* Check Probe Resp Length if it is greater then 255 then
6218 Store Probe Rsp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1
6219 & WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are
6220 not able Store More then 255 bytes into One Variable */
6221
6222 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
6223 {
6224 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
6225 {
6226 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
6227 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
6228 }
6229 else
6230 {
6231 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
6232 rem_probe_resp_ie_len = 0;
6233 }
6234 }
6235
6236 rem_probe_resp_ie_len = 0;
6237
6238 if (probe_rsp_ie_len[0] > 0)
6239 {
6240 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
6241 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
6242 (tANI_U8*)(genie - 2),
6243 probe_rsp_ie_len[0], NULL,
6244 eANI_BOOLEAN_FALSE)
6245 == eHAL_STATUS_FAILURE)
6246 {
6247 hddLog(LOGE,
6248 "Could not pass"
6249 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
6250 }
6251 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
6252 }
6253
6254 if (probe_rsp_ie_len[1] > 0)
6255 {
6256 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
6257 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
6258 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
6259 probe_rsp_ie_len[1], NULL,
6260 eANI_BOOLEAN_FALSE)
6261 == eHAL_STATUS_FAILURE)
6262 {
6263 hddLog(LOGE,
6264 "Could not pass"
6265 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
6266 }
6267 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
6268 }
6269
6270 if (probe_rsp_ie_len[2] > 0)
6271 {
6272 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
6273 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
6274 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
6275 probe_rsp_ie_len[2], NULL,
6276 eANI_BOOLEAN_FALSE)
6277 == eHAL_STATUS_FAILURE)
6278 {
6279 hddLog(LOGE,
6280 "Could not pass"
6281 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
6282 }
6283 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
6284 }
6285
6286 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
6287 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
6288 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
6289 {
6290 hddLog(LOGE,
6291 "Could not pass"
6292 "on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
6293 }
6294 }
6295 else
6296 {
6297 // Reset WNI_CFG_PROBE_RSP Flags
6298 wlan_hdd_reset_prob_rspies(pAdapter);
6299
6300 hddLog(VOS_TRACE_LEVEL_INFO,
6301 "%s: No Probe Response IE received in set beacon",
6302 __func__);
6303 }
6304 } /* end of if (WLAN_HDD_IBSS == pAdapter->device_mode) */
Jeff Johnson295189b2012-06-20 16:38:30 -07006305 break;
6306 case DOT11F_EID_RSN:
6307 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set RSN IE(len %d)",__func__, eLen + 2);
6308 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
6309 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2)/*ie_len*/);
6310 pWextState->roamProfile.pRSNReqIE = pWextState->WPARSNIE;
6311 pWextState->roamProfile.nRSNReqIELength = eLen + 2; //ie_len;
6312 break;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07006313 /* Appending Extended Capabilities with Interworking bit set in Assoc Req */
6314 case DOT11F_EID_EXTCAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306315 {
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07006316 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306317 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set Extended CAPS IE(len %d)",
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07006318 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306319
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07006320 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
6321 {
Jeff Johnson902c9832012-12-10 14:28:09 -08006322 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
6323 "Need bigger buffer space");
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07006324 VOS_ASSERT(0);
6325 return -ENOMEM;
6326 }
6327 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
6328 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306329
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07006330 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
6331 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
6332 break;
6333 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006334#ifdef FEATURE_WLAN_WAPI
6335 case WLAN_EID_WAPI:
6336 pAdapter->wapi_info.nWapiMode = 1; //Setting WAPI Mode to ON=1
Jeff Johnson0299d0a2013-10-30 12:37:43 -07006337 hddLog(VOS_TRACE_LEVEL_INFO, "WAPI MODE IS %u",
Jeff Johnson295189b2012-06-20 16:38:30 -07006338 pAdapter->wapi_info.nWapiMode);
6339 tmp = (u16 *)ie;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306340 tmp = tmp + 2; // Skip element Id and Len, Version
Jeff Johnson295189b2012-06-20 16:38:30 -07006341 akmsuiteCount = WPA_GET_LE16(tmp);
6342 tmp = tmp + 1;
6343 akmlist = (int *)(tmp);
6344 if(akmsuiteCount <= MAX_NUM_AKM_SUITES)
6345 {
6346 memcpy(akmsuite, akmlist, (4*akmsuiteCount));
6347 }
6348 else
6349 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08006350 hddLog(VOS_TRACE_LEVEL_FATAL, "Invalid akmSuite count");
Jeff Johnson295189b2012-06-20 16:38:30 -07006351 VOS_ASSERT(0);
6352 return -EINVAL;
6353 }
6354
6355 if (WAPI_PSK_AKM_SUITE == akmsuite[0])
6356 {
6357 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO PSK",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006358 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006359 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_PSK;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306360 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006361 if (WAPI_CERT_AKM_SUITE == akmsuite[0])
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306362 {
Jeff Johnson295189b2012-06-20 16:38:30 -07006363 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO CERTIFICATE",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006364 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006365 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_CERT;
6366 }
6367 break;
6368#endif
6369 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306370 hddLog (VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07006371 "%s Set UNKNOWN IE %X", __func__, elementId);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07006372 /* when Unknown IE is received we should break and continue
6373 * to the next IE in the buffer instead we were returning
6374 * so changing this to break */
6375 break;
Jeff Johnson295189b2012-06-20 16:38:30 -07006376 }
6377 genie += eLen;
6378 remLen -= eLen;
6379 }
6380 EXIT();
6381 return 0;
6382}
6383
6384/*
Gopichand Nakkala18f0c262013-05-07 23:25:08 +05306385 * FUNCTION: hdd_isWPAIEPresent
6386 * Parse the received IE to find the WPA IE
6387 *
6388 */
6389static bool hdd_isWPAIEPresent(u8 *ie, u8 ie_len)
6390{
6391 v_U8_t eLen = 0;
6392 v_U16_t remLen = ie_len;
6393 v_U8_t elementId = 0;
6394
6395 while (remLen >= 2)
6396 {
6397 elementId = *ie++;
6398 eLen = *ie++;
6399 remLen -= 2;
6400 if (eLen > remLen)
6401 {
6402 hddLog(VOS_TRACE_LEVEL_ERROR,
6403 "%s: IE length is wrong %d", __func__, eLen);
6404 return FALSE;
6405 }
6406 if ((elementId == DOT11F_EID_WPA) && (remLen > 5))
6407 {
6408 /* OUI - 0x00 0X50 0XF2
6409 WPA Information Element - 0x01
6410 WPA version - 0x01*/
6411 if (0 == memcmp(&ie[0], "\x00\x50\xf2\x01\x01", 5))
6412 return TRUE;
6413 }
6414 ie += eLen;
6415 remLen -= eLen;
6416 }
6417 return FALSE;
6418}
6419
6420/*
Jeff Johnson295189b2012-06-20 16:38:30 -07006421 * FUNCTION: wlan_hdd_cfg80211_set_privacy
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306422 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -07006423 * parameters during connect operation.
6424 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306425int wlan_hdd_cfg80211_set_privacy( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07006426 struct cfg80211_connect_params *req
6427 )
6428{
6429 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306430 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07006431 ENTER();
6432
6433 /*set wpa version*/
6434 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
6435
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306436 if (req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -07006437 {
Gopichand Nakkala781ded42013-06-28 12:10:45 +05306438 if (NL80211_WPA_VERSION_1 == req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -07006439 {
6440 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
6441 }
6442 else if (NL80211_WPA_VERSION_2 == req->crypto.wpa_versions)
6443 {
6444 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
6445 }
6446 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306447
6448 hddLog(VOS_TRACE_LEVEL_INFO, "%s: set wpa version to %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07006449 pWextState->wpaVersion);
6450
6451 /*set authentication type*/
6452 status = wlan_hdd_cfg80211_set_auth_type(pAdapter, req->auth_type);
6453
6454 if (0 > status)
6455 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306456 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07006457 "%s: failed to set authentication type ", __func__);
6458 return status;
6459 }
6460
6461 /*set key mgmt type*/
6462 if (req->crypto.n_akm_suites)
6463 {
6464 status = wlan_hdd_set_akm_suite(pAdapter, req->crypto.akm_suites[0]);
6465 if (0 > status)
6466 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306467 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set akm suite",
Jeff Johnson295189b2012-06-20 16:38:30 -07006468 __func__);
6469 return status;
6470 }
6471 }
6472
6473 /*set pairwise cipher type*/
6474 if (req->crypto.n_ciphers_pairwise)
6475 {
6476 status = wlan_hdd_cfg80211_set_cipher(pAdapter,
6477 req->crypto.ciphers_pairwise[0], true);
6478 if (0 > status)
6479 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306480 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07006481 "%s: failed to set unicast cipher type", __func__);
6482 return status;
6483 }
6484 }
6485 else
6486 {
6487 /*Reset previous cipher suite to none*/
6488 status = wlan_hdd_cfg80211_set_cipher(pAdapter, 0, true);
6489 if (0 > status)
6490 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306491 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07006492 "%s: failed to set unicast cipher type", __func__);
6493 return status;
6494 }
6495 }
6496
6497 /*set group cipher type*/
6498 status = wlan_hdd_cfg80211_set_cipher(pAdapter, req->crypto.cipher_group,
6499 false);
6500
6501 if (0 > status)
6502 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306503 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set mcast cipher type",
Jeff Johnson295189b2012-06-20 16:38:30 -07006504 __func__);
6505 return status;
6506 }
6507
Chet Lanctot186b5732013-03-18 10:26:30 -07006508#ifdef WLAN_FEATURE_11W
6509 pWextState->roamProfile.MFPEnabled = (req->mfp == NL80211_MFP_REQUIRED);
6510#endif
6511
Jeff Johnson295189b2012-06-20 16:38:30 -07006512 /*parse WPA/RSN IE, and set the correspoing fileds in Roam profile*/
6513 if (req->ie_len)
6514 {
6515 status = wlan_hdd_cfg80211_set_ie(pAdapter, req->ie, req->ie_len);
6516 if ( 0 > status)
6517 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306518 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse the WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -07006519 __func__);
6520 return status;
6521 }
6522 }
6523
6524 /*incase of WEP set default key information*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306525 if (req->key && req->key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -07006526 {
6527 if ( (WLAN_CIPHER_SUITE_WEP40 == req->crypto.ciphers_pairwise[0])
6528 || (WLAN_CIPHER_SUITE_WEP104 == req->crypto.ciphers_pairwise[0])
6529 )
6530 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306531 if ( IW_AUTH_KEY_MGMT_802_1X
Jeff Johnson295189b2012-06-20 16:38:30 -07006532 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X ))
6533 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306534 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Dynamic WEP not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -07006535 __func__);
6536 return -EOPNOTSUPP;
6537 }
6538 else
6539 {
6540 u8 key_len = req->key_len;
6541 u8 key_idx = req->key_idx;
6542
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306543 if ((eCSR_SECURITY_WEP_KEYSIZE_MAX_BYTES >= key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -07006544 && (CSR_MAX_NUM_KEY > key_idx)
6545 )
6546 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306547 hddLog(VOS_TRACE_LEVEL_INFO,
6548 "%s: setting default wep key, key_idx = %hu key_len %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07006549 __func__, key_idx, key_len);
6550 vos_mem_copy(
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306551 &pWextState->roamProfile.Keys.KeyMaterial[key_idx][0],
Jeff Johnson295189b2012-06-20 16:38:30 -07006552 req->key, key_len);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306553 pWextState->roamProfile.Keys.KeyLength[key_idx] =
Jeff Johnson295189b2012-06-20 16:38:30 -07006554 (u8)key_len;
6555 pWextState->roamProfile.Keys.defaultIndex = (u8)key_idx;
6556 }
6557 }
6558 }
6559 }
6560
6561 return status;
6562}
6563
6564/*
Vinay Krishna Eranna21042322014-01-08 19:21:39 +05306565 * FUNCTION: wlan_hdd_try_disconnect
6566 * This function is used to disconnect from previous
6567 * connection
6568 */
6569static int wlan_hdd_try_disconnect( hdd_adapter_t *pAdapter )
6570{
6571 long ret = 0;
6572 hdd_station_ctx_t *pHddStaCtx;
6573 eMib_dot11DesiredBssType connectedBssType;
6574
6575 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6576
6577 hdd_connGetConnectedBssType(pHddStaCtx,&connectedBssType );
6578
6579 if((eMib_dot11DesiredBssType_independent == connectedBssType) ||
6580 (eConnectionState_Associated == pHddStaCtx->conn_info.connState) ||
6581 (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState))
6582 {
6583 /* Issue disconnect to CSR */
6584 INIT_COMPLETION(pAdapter->disconnect_comp_var);
6585 if( eHAL_STATUS_SUCCESS ==
6586 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
6587 pAdapter->sessionId,
6588 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
6589 {
6590 ret = wait_for_completion_interruptible_timeout(
6591 &pAdapter->disconnect_comp_var,
6592 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
6593 if (0 >= ret)
6594 {
6595 hddLog(LOGE, FL("Failed to receive disconnect event"));
6596 return -EALREADY;
6597 }
6598 }
6599 }
6600 else if(eConnectionState_Disconnecting == pHddStaCtx->conn_info.connState)
6601 {
6602 ret = wait_for_completion_interruptible_timeout(
6603 &pAdapter->disconnect_comp_var,
6604 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
6605 if (0 >= ret)
6606 {
6607 hddLog(LOGE, FL("Failed to receive disconnect event"));
6608 return -EALREADY;
6609 }
6610 }
6611
6612 return 0;
6613}
6614
6615/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +05306616 * FUNCTION: __wlan_hdd_cfg80211_set_privacy
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306617 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -07006618 * parameters during connect operation.
6619 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +05306620static int __wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07006621 struct net_device *ndev,
6622 struct cfg80211_connect_params *req
6623 )
6624{
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306625 int status;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306626 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -07006627 VOS_STATUS exitbmpsStatus = VOS_STATUS_E_INVAL;
Rajesh Chauhana0516c62014-01-30 16:11:18 -08006628 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07006629
6630 ENTER();
6631
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05306632 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
6633 TRACE_CODE_HDD_CFG80211_CONNECT,
6634 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306635 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05306636 "%s: device_mode = %s (%d)", __func__,
6637 hdd_device_modetoString(pAdapter->device_mode),
6638 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07006639
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306640 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -08006641 if (!pHddCtx)
6642 {
6643 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6644 "%s: HDD context is null", __func__);
6645 return VOS_STATUS_E_FAILURE;
6646 }
6647
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306648 status = wlan_hdd_validate_context(pHddCtx);
6649
6650 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -07006651 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306652 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6653 "%s: HDD context is not valid", __func__);
6654 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -07006655 }
6656
6657#ifdef WLAN_BTAMP_FEATURE
6658 //Infra connect not supported when AMP traffic is on.
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306659 if( VOS_TRUE == WLANBAP_AmpSessionOn() )
Jeff Johnson295189b2012-06-20 16:38:30 -07006660 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306661 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07006662 "%s: No connection when AMP is on", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08006663 return -ECONNREFUSED;
Jeff Johnson295189b2012-06-20 16:38:30 -07006664 }
6665#endif
Vinay Krishna Eranna21042322014-01-08 19:21:39 +05306666
6667 //If Device Mode is Station Concurrent Sessions Exit BMps
6668 //P2P Mode will be taken care in Open/close adapter
6669 if((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
6670 (vos_concurrent_sessions_running()))
6671 {
6672 exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
6673 }
6674
6675 /*Try disconnecting if already in connected state*/
6676 status = wlan_hdd_try_disconnect(pAdapter);
6677 if ( 0 > status)
6678 {
6679 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
6680 " connection"));
6681 return -EALREADY;
6682 }
6683
Jeff Johnson295189b2012-06-20 16:38:30 -07006684 /*initialise security parameters*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306685 status = wlan_hdd_cfg80211_set_privacy(pAdapter, req);
Jeff Johnson295189b2012-06-20 16:38:30 -07006686
6687 if ( 0 > status)
6688 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306689 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security params",
Jeff Johnson295189b2012-06-20 16:38:30 -07006690 __func__);
6691 return status;
6692 }
6693
Mohit Khanna765234a2012-09-11 15:08:35 -07006694 if ( req->channel )
6695 {
6696 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
6697 req->ssid_len, req->bssid,
6698 req->channel->hw_value);
6699 }
6700 else
6701 {
6702 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306703 req->ssid_len, req->bssid, 0);
Mohit Khanna765234a2012-09-11 15:08:35 -07006704 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006705
6706 if (0 > status)
6707 {
6708 //ReEnable BMPS if disabled
6709 if((VOS_STATUS_SUCCESS == exitbmpsStatus) &&
6710 (NULL != pHddCtx))
6711 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306712 if (pHddCtx->hdd_wlan_suspended)
6713 {
6714 hdd_set_pwrparams(pHddCtx);
6715 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006716 //ReEnable Bmps and Imps back
6717 hdd_enable_bmps_imps(pHddCtx);
6718 }
6719
6720 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: connect failed", __func__);
6721 return status;
6722 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306723 pHddCtx->isAmpAllowed = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07006724 EXIT();
6725 return status;
6726}
6727
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +05306728static int wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
6729 struct net_device *ndev,
6730 struct cfg80211_connect_params *req)
6731{
6732 int ret;
6733 vos_ssr_protect(__func__);
6734 ret = __wlan_hdd_cfg80211_connect(wiphy, ndev, req);
6735 vos_ssr_unprotect(__func__);
6736
6737 return ret;
6738}
Jeff Johnson295189b2012-06-20 16:38:30 -07006739
6740/*
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05306741 * FUNCTION: wlan_hdd_disconnect
6742 * This function is used to issue a disconnect request to SME
6743 */
6744int wlan_hdd_disconnect( hdd_adapter_t *pAdapter, u16 reason )
6745{
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306746 int status;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05306747 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306748 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
6749
6750 status = wlan_hdd_validate_context(pHddCtx);
6751
6752 if (0 != status)
6753 {
6754 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6755 "%s: HDD context is not valid", __func__);
6756 return status;
6757 }
6758
6759 pHddCtx->isAmpAllowed = VOS_TRUE;
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +05306760 pHddStaCtx->conn_info.connState = eConnectionState_Disconnecting;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05306761 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306762
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05306763 /*issue disconnect*/
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +05306764
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05306765 status = sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
6766 pAdapter->sessionId, reason);
6767
6768 if ( 0 != status )
6769 {
6770 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006771 "%s csrRoamDisconnect failure, returned %d",
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05306772 __func__, (int)status );
6773 return -EINVAL;
6774 }
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +05306775 status = wait_for_completion_interruptible_timeout(
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05306776 &pAdapter->disconnect_comp_var,
6777 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +05306778 if (!status)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306779 {
6780 hddLog(VOS_TRACE_LEVEL_ERROR,
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +05306781 "%s: Failed to disconnect, timed out", __func__);
6782 return -ETIMEDOUT;
6783 }
6784 else if (status == -ERESTARTSYS)
6785 {
6786 hddLog(VOS_TRACE_LEVEL_ERROR,
6787 "%s: Failed to disconnect, wait interrupted", __func__);
6788 return status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306789 }
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05306790 /*stop tx queues*/
6791 netif_tx_disable(pAdapter->dev);
6792 netif_carrier_off(pAdapter->dev);
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +05306793 return 0;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05306794}
6795
6796
6797/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +05306798 * FUNCTION: __wlan_hdd_cfg80211_disconnect
Jeff Johnson295189b2012-06-20 16:38:30 -07006799 * This function is used to issue a disconnect request to SME
6800 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +05306801static int __wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07006802 struct net_device *dev,
6803 u16 reason
6804 )
6805{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306806 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
6807 tCsrRoamProfile *pRoamProfile =
Jeff Johnson295189b2012-06-20 16:38:30 -07006808 &(WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter))->roamProfile;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306809 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07006810 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkala4327a152013-03-04 23:22:42 -08006811 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaaa353782013-05-17 20:36:22 +05306812#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08006813 tANI_U8 staIdx;
6814#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306815
Jeff Johnson295189b2012-06-20 16:38:30 -07006816 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306817
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05306818 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
6819 TRACE_CODE_HDD_CFG80211_DISCONNECT,
6820 pAdapter->sessionId, reason));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05306821 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s(%d)",
6822 __func__, hdd_device_modetoString(pAdapter->device_mode),
6823 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07006824
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306825 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Disconnect called with reason code %d",
6826 __func__, reason);
Jeff Johnson295189b2012-06-20 16:38:30 -07006827
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306828 status = wlan_hdd_validate_context(pHddCtx);
6829
6830 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -07006831 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306832 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6833 "%s: HDD context is not valid", __func__);
6834 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -07006835 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306836
Jeff Johnson295189b2012-06-20 16:38:30 -07006837 if (NULL != pRoamProfile)
6838 {
6839 /*issue disconnect request to SME, if station is in connected state*/
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +05306840 if ((pHddStaCtx->conn_info.connState == eConnectionState_Associated) ||
6841 (pHddStaCtx->conn_info.connState == eConnectionState_Connecting))
Jeff Johnson295189b2012-06-20 16:38:30 -07006842 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306843 eCsrRoamDisconnectReason reasonCode =
Jeff Johnson295189b2012-06-20 16:38:30 -07006844 eCSR_DISCONNECT_REASON_UNSPECIFIED;
Gopichand Nakkalaaa353782013-05-17 20:36:22 +05306845 hdd_scaninfo_t *pScanInfo;
Jeff Johnson295189b2012-06-20 16:38:30 -07006846 switch(reason)
6847 {
6848 case WLAN_REASON_MIC_FAILURE:
6849 reasonCode = eCSR_DISCONNECT_REASON_MIC_ERROR;
6850 break;
6851
6852 case WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY:
6853 case WLAN_REASON_DISASSOC_AP_BUSY:
6854 case WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA:
6855 reasonCode = eCSR_DISCONNECT_REASON_DISASSOC;
6856 break;
6857
6858 case WLAN_REASON_PREV_AUTH_NOT_VALID:
6859 case WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA:
6860 reasonCode = eCSR_DISCONNECT_REASON_DEAUTH;
6861 break;
6862
6863 case WLAN_REASON_DEAUTH_LEAVING:
6864 default:
6865 reasonCode = eCSR_DISCONNECT_REASON_UNSPECIFIED;
6866 break;
6867 }
Gopichand Nakkalaaa353782013-05-17 20:36:22 +05306868 pScanInfo = &pHddCtx->scan_info;
6869 if (pScanInfo->mScanPending)
6870 {
Srinivas, Dasari138af4f2014-02-07 11:13:45 +05306871 hddLog(VOS_TRACE_LEVEL_INFO, "Disconnect is in progress, "
Gopichand Nakkalaaa353782013-05-17 20:36:22 +05306872 "Aborting Scan");
Srinivas, Dasari138af4f2014-02-07 11:13:45 +05306873 hdd_abort_mac_scan(pHddCtx, pAdapter->sessionId,
6874 eCSR_SCAN_ABORT_DEFAULT);
Gopichand Nakkalaaa353782013-05-17 20:36:22 +05306875 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006876
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08006877#ifdef FEATURE_WLAN_TDLS
6878 /* First clean up the tdls peers if any */
Gopichand Nakkala4327a152013-03-04 23:22:42 -08006879 for (staIdx = 0 ; staIdx < HDD_MAX_NUM_TDLS_STA; staIdx++)
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08006880 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -08006881 if ((pHddCtx->tdlsConnInfo[staIdx].sessionId == pAdapter->sessionId) &&
6882 (pHddCtx->tdlsConnInfo[staIdx].staId))
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08006883 {
Hoonki Lee11f7dda2013-02-14 16:55:44 -08006884 uint8 *mac;
Gopichand Nakkala4327a152013-03-04 23:22:42 -08006885 mac = pHddCtx->tdlsConnInfo[staIdx].peerMac.bytes;
Hoonki Lee11f7dda2013-02-14 16:55:44 -08006886 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07006887 "%s: call sme_DeleteTdlsPeerSta staId %d sessionId %d " MAC_ADDRESS_STR,
Gopichand Nakkala4327a152013-03-04 23:22:42 -08006888 __func__, pHddCtx->tdlsConnInfo[staIdx].staId, pAdapter->sessionId,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07006889 MAC_ADDR_ARRAY(mac));
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08006890 sme_DeleteTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala4327a152013-03-04 23:22:42 -08006891 pAdapter->sessionId,
6892 mac);
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08006893 }
6894 }
6895#endif
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +05306896 hddLog(LOG1, FL("Disconnecting with reasoncode:%u"), reasonCode);
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05306897 status = wlan_hdd_disconnect(pAdapter, reasonCode);
6898 if ( 0 != status )
Jeff Johnson295189b2012-06-20 16:38:30 -07006899 {
6900 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006901 "%s wlan_hdd_disconnect failure, returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07006902 __func__, (int)status );
6903 return -EINVAL;
6904 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006905 }
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +05306906 else
6907 {
6908 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unexpected cfg disconnect API"
6909 "called while in %d state", __func__,
6910 pHddStaCtx->conn_info.connState);
6911 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006912 }
6913 else
6914 {
6915 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid roam profile", __func__);
6916 }
6917
6918 return status;
6919}
6920
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +05306921static int wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
6922 struct net_device *dev,
6923 u16 reason
6924 )
6925{
6926 int ret;
6927 vos_ssr_protect(__func__);
6928 ret = __wlan_hdd_cfg80211_disconnect(wiphy, dev, reason);
6929 vos_ssr_unprotect(__func__);
6930
6931 return ret;
6932}
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05306933
Jeff Johnson295189b2012-06-20 16:38:30 -07006934/*
6935 * FUNCTION: wlan_hdd_cfg80211_set_privacy_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306936 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -07006937 * settings in IBSS mode.
6938 */
6939static int wlan_hdd_cfg80211_set_privacy_ibss(
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306940 hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07006941 struct cfg80211_ibss_params *params
6942 )
6943{
6944 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306945 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07006946 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
6947 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306948
Jeff Johnson295189b2012-06-20 16:38:30 -07006949 ENTER();
6950
6951 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
Ravi Joshib58ca0d2013-10-29 09:50:23 -07006952 vos_mem_zero(&pHddStaCtx->ibss_enc_key, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -07006953
6954 if (params->ie_len && ( NULL != params->ie) )
6955 {
Shailender Karmuchi67edd312013-06-18 16:30:48 -07006956 if (wlan_hdd_cfg80211_get_ie_ptr (params->ie,
6957 params->ie_len, WLAN_EID_RSN ))
Jeff Johnson295189b2012-06-20 16:38:30 -07006958 {
6959 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
6960 encryptionType = eCSR_ENCRYPT_TYPE_AES;
6961 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -07006962 else if ( hdd_isWPAIEPresent (params->ie, params->ie_len ))
Jeff Johnson295189b2012-06-20 16:38:30 -07006963 {
Shailender Karmuchi642e9812013-05-30 14:34:49 -07006964 tDot11fIEWPA dot11WPAIE;
6965 tHalHandle halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
Shailender Karmuchi67edd312013-06-18 16:30:48 -07006966 u8 *ie;
Shailender Karmuchi642e9812013-05-30 14:34:49 -07006967
Wilson Yang00256342013-10-10 23:13:38 -07006968 memset(&dot11WPAIE, 0, sizeof(dot11WPAIE));
Shailender Karmuchi67edd312013-06-18 16:30:48 -07006969 ie = wlan_hdd_cfg80211_get_ie_ptr (params->ie,
6970 params->ie_len, DOT11F_EID_WPA);
6971 if ( NULL != ie )
6972 {
6973 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
6974 // Unpack the WPA IE
6975 //Skip past the EID byte and length byte - and four byte WiFi OUI
6976 dot11fUnpackIeWPA((tpAniSirGlobal) halHandle,
6977 &ie[2+4],
6978 ie[1] - 4,
6979 &dot11WPAIE);
6980 /*Extract the multicast cipher, the encType for unicast
6981 cipher for wpa-none is none*/
6982 encryptionType =
6983 hdd_TranslateWPAToCsrEncryptionType(dot11WPAIE.multicast_cipher);
6984 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006985 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -07006986
Jeff Johnson295189b2012-06-20 16:38:30 -07006987 status = wlan_hdd_cfg80211_set_ie(pAdapter, params->ie, params->ie_len);
6988
6989 if (0 > status)
6990 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306991 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -07006992 __func__);
6993 return status;
6994 }
6995 }
6996
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306997 pWextState->roamProfile.AuthType.authType[0] =
6998 pHddStaCtx->conn_info.authType =
Jeff Johnson295189b2012-06-20 16:38:30 -07006999 eCSR_AUTH_TYPE_OPEN_SYSTEM;
7000
7001 if (params->privacy)
7002 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307003 /* Security enabled IBSS, At this time there is no information available
7004 * about the security paramters, so initialise the encryption type to
Jeff Johnson295189b2012-06-20 16:38:30 -07007005 * eCSR_ENCRYPT_TYPE_WEP40_STATICKEY.
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307006 * The correct security parameters will be updated later in
Jeff Johnson295189b2012-06-20 16:38:30 -07007007 * wlan_hdd_cfg80211_add_key */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307008 /* Hal expects encryption type to be set inorder
Jeff Johnson295189b2012-06-20 16:38:30 -07007009 *enable privacy bit in beacons */
7010
7011 encryptionType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
7012 }
Shailender Karmuchi642e9812013-05-30 14:34:49 -07007013 VOS_TRACE (VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
7014 "encryptionType=%d", encryptionType);
Jeff Johnson295189b2012-06-20 16:38:30 -07007015 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
7016 pWextState->roamProfile.EncryptionType.numEntries = 1;
7017 pWextState->roamProfile.EncryptionType.encryptionType[0] = encryptionType;
Jeff Johnson295189b2012-06-20 16:38:30 -07007018 return status;
7019}
7020
7021/*
7022 * FUNCTION: wlan_hdd_cfg80211_join_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307023 * This function is used to create/join an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -07007024 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307025static int wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07007026 struct net_device *dev,
7027 struct cfg80211_ibss_params *params
7028 )
7029{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307030 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Jeff Johnson295189b2012-06-20 16:38:30 -07007031 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
7032 tCsrRoamProfile *pRoamProfile;
7033 int status;
krunal sonie9002db2013-11-25 14:24:17 -08007034 bool alloc_bssid = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07007035 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307036 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07007037
7038 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307039
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307040 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7041 TRACE_CODE_HDD_CFG80211_JOIN_IBSS,
7042 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307043 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05307044 "%s: device_mode = %s (%d)", __func__,
7045 hdd_device_modetoString(pAdapter->device_mode),
7046 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07007047
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307048 status = wlan_hdd_validate_context(pHddCtx);
7049
7050 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -07007051 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307052 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7053 "%s: HDD context is not valid", __func__);
7054 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -07007055 }
7056
7057 if (NULL == pWextState)
7058 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08007059 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -07007060 __func__);
7061 return -EIO;
7062 }
7063
Vinay Krishna Eranna21042322014-01-08 19:21:39 +05307064 /*Try disconnecting if already in connected state*/
7065 status = wlan_hdd_try_disconnect(pAdapter);
7066 if ( 0 > status)
7067 {
7068 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
7069 " IBSS connection"));
7070 return -EALREADY;
7071 }
7072
Jeff Johnson295189b2012-06-20 16:38:30 -07007073 pRoamProfile = &pWextState->roamProfile;
7074
7075 if ( eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType )
7076 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307077 hddLog (VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007078 "%s Interface type is not set to IBSS", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007079 return -EINVAL;
7080 }
7081
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -07007082 /* BSSID is provided by upper layers hence no need to AUTO generate */
7083 if (NULL != params->bssid) {
7084 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
7085 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) {
7086 hddLog (VOS_TRACE_LEVEL_ERROR,
7087 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
7088 return -EIO;
7089 }
7090 }
krunal sonie9002db2013-11-25 14:24:17 -08007091 else if(pHddCtx->cfg_ini->isCoalesingInIBSSAllowed == 0)
7092 {
7093 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
7094 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
7095 {
7096 hddLog (VOS_TRACE_LEVEL_ERROR,
7097 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
7098 return -EIO;
7099 }
7100 params->bssid = vos_mem_malloc(sizeof(VOS_MAC_ADDR_SIZE));
7101 if (!params->bssid)
7102 {
7103 hddLog (VOS_TRACE_LEVEL_ERROR,
7104 "%s:Failed memory allocation", __func__);
7105 return -EIO;
7106 }
7107 vos_mem_copy((v_U8_t *)params->bssid,
7108 (v_U8_t *)&pHddCtx->cfg_ini->IbssBssid.bytes[0],
7109 VOS_MAC_ADDR_SIZE);
7110 alloc_bssid = VOS_TRUE;
7111 }
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -07007112
Jeff Johnson295189b2012-06-20 16:38:30 -07007113 /* Set Channel */
Yue Maf49ba872013-08-19 12:04:25 -07007114 if (NULL !=
7115#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
7116 params->chandef.chan)
7117#else
7118 params->channel)
7119#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007120 {
7121 u8 channelNum;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07007122 v_U32_t numChans = WNI_CFG_VALID_CHANNEL_LIST_LEN;
7123 v_U8_t validChan[WNI_CFG_VALID_CHANNEL_LIST_LEN];
7124 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
7125 int indx;
Jeff Johnson295189b2012-06-20 16:38:30 -07007126
7127 /* Get channel number */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307128 channelNum =
Yue Maf49ba872013-08-19 12:04:25 -07007129 ieee80211_frequency_to_channel(
7130#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
7131 params->chandef.chan->center_freq);
7132#else
7133 params->channel->center_freq);
7134#endif
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07007135
7136 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
7137 validChan, &numChans))
Jeff Johnson295189b2012-06-20 16:38:30 -07007138 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07007139 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid channel list",
7140 __func__);
7141 return -EOPNOTSUPP;
Jeff Johnson295189b2012-06-20 16:38:30 -07007142 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07007143
7144 for (indx = 0; indx < numChans; indx++)
Jeff Johnson295189b2012-06-20 16:38:30 -07007145 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07007146 if (channelNum == validChan[indx])
7147 {
7148 break;
7149 }
7150 }
7151 if (indx >= numChans)
7152 {
7153 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Not valid Channel %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07007154 __func__, channelNum);
7155 return -EINVAL;
7156 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07007157 /* Set the Operational Channel */
7158 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: set channel %d", __func__,
7159 channelNum);
7160 pRoamProfile->ChannelInfo.numOfChannels = 1;
7161 pHddStaCtx->conn_info.operationChannel = channelNum;
7162 pRoamProfile->ChannelInfo.ChannelList =
7163 &pHddStaCtx->conn_info.operationChannel;
Jeff Johnson295189b2012-06-20 16:38:30 -07007164 }
7165
7166 /* Initialize security parameters */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307167 status = wlan_hdd_cfg80211_set_privacy_ibss(pAdapter, params);
Jeff Johnson295189b2012-06-20 16:38:30 -07007168 if (status < 0)
7169 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307170 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security parameters",
Jeff Johnson295189b2012-06-20 16:38:30 -07007171 __func__);
7172 return status;
7173 }
7174
7175 /* Issue connect start */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307176 status = wlan_hdd_cfg80211_connect_start(pAdapter, params->ssid,
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07007177 params->ssid_len, params->bssid,
7178 pHddStaCtx->conn_info.operationChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -07007179
7180 if (0 > status)
7181 {
7182 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: connect failed", __func__);
7183 return status;
7184 }
7185
krunal sonie9002db2013-11-25 14:24:17 -08007186 if (NULL != params->bssid &&
7187 pHddCtx->cfg_ini->isCoalesingInIBSSAllowed == 0 &&
7188 alloc_bssid == VOS_TRUE)
7189 {
7190 vos_mem_free(params->bssid);
7191 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007192 return 0;
7193}
7194
7195/*
7196 * FUNCTION: wlan_hdd_cfg80211_leave_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307197 * This function is used to leave an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -07007198 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307199static int wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07007200 struct net_device *dev
7201 )
7202{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307203 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Jeff Johnson295189b2012-06-20 16:38:30 -07007204 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
7205 tCsrRoamProfile *pRoamProfile;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307206 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7207 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07007208
7209 ENTER();
7210
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307211 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7212 TRACE_CODE_HDD_CFG80211_LEAVE_IBSS,
7213 pAdapter->sessionId, eCSR_DISCONNECT_REASON_IBSS_LEAVE));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307214 status = wlan_hdd_validate_context(pHddCtx);
7215
7216 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007217 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307218 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7219 "%s: HDD context is not valid", __func__);
7220 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007221 }
7222
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05307223 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)", __func__,
7224 hdd_device_modetoString(pAdapter->device_mode),
7225 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07007226 if (NULL == pWextState)
7227 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08007228 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -07007229 __func__);
7230 return -EIO;
7231 }
7232
7233 pRoamProfile = &pWextState->roamProfile;
7234
7235 /* Issue disconnect only if interface type is set to IBSS */
7236 if (eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType)
7237 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307238 hddLog (VOS_TRACE_LEVEL_ERROR, "%s: BSS Type is not set to IBSS",
Jeff Johnson295189b2012-06-20 16:38:30 -07007239 __func__);
7240 return -EINVAL;
7241 }
7242
7243 /* Issue Disconnect request */
7244 INIT_COMPLETION(pAdapter->disconnect_comp_var);
7245 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
7246 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
7247
7248 return 0;
7249}
7250
7251/*
7252 * FUNCTION: wlan_hdd_cfg80211_set_wiphy_params
7253 * This function is used to set the phy parameters
7254 * (RTS Threshold/FRAG Threshold/Retry Count etc ...)
7255 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307256static int wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07007257 u32 changed)
7258{
7259 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
7260 tHalHandle hHal = pHddCtx->hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307261 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07007262
7263 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307264 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7265 TRACE_CODE_HDD_CFG80211_SET_WIPHY_PARAMS,
7266 NO_SESSION, wiphy->rts_threshold));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307267 status = wlan_hdd_validate_context(pHddCtx);
7268
7269 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007270 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307271 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7272 "%s: HDD context is not valid", __func__);
7273 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007274 }
7275
Jeff Johnson295189b2012-06-20 16:38:30 -07007276 if (changed & WIPHY_PARAM_RTS_THRESHOLD)
7277 {
7278 u16 rts_threshold = (wiphy->rts_threshold == -1) ?
7279 WNI_CFG_RTS_THRESHOLD_STAMAX :
7280 wiphy->rts_threshold;
7281
7282 if ((WNI_CFG_RTS_THRESHOLD_STAMIN > rts_threshold) ||
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307283 (WNI_CFG_RTS_THRESHOLD_STAMAX < rts_threshold))
Jeff Johnson295189b2012-06-20 16:38:30 -07007284 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307285 hddLog(VOS_TRACE_LEVEL_ERROR,
7286 "%s: Invalid RTS Threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07007287 __func__, rts_threshold);
7288 return -EINVAL;
7289 }
7290
7291 if (0 != ccmCfgSetInt(hHal, WNI_CFG_RTS_THRESHOLD,
7292 rts_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307293 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -07007294 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307295 hddLog(VOS_TRACE_LEVEL_ERROR,
7296 "%s: ccmCfgSetInt failed for rts_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07007297 __func__, rts_threshold);
7298 return -EIO;
7299 }
7300
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307301 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set rts threshold %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07007302 rts_threshold);
7303 }
7304
7305 if (changed & WIPHY_PARAM_FRAG_THRESHOLD)
7306 {
7307 u16 frag_threshold = (wiphy->frag_threshold == -1) ?
7308 WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX :
7309 wiphy->frag_threshold;
7310
7311 if ((WNI_CFG_FRAGMENTATION_THRESHOLD_STAMIN > frag_threshold)||
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307312 (WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX < frag_threshold) )
Jeff Johnson295189b2012-06-20 16:38:30 -07007313 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307314 hddLog(VOS_TRACE_LEVEL_ERROR,
7315 "%s: Invalid frag_threshold value %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07007316 frag_threshold);
7317 return -EINVAL;
7318 }
7319
7320 if (0 != ccmCfgSetInt(hHal, WNI_CFG_FRAGMENTATION_THRESHOLD,
7321 frag_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307322 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -07007323 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307324 hddLog(VOS_TRACE_LEVEL_ERROR,
7325 "%s: ccmCfgSetInt failed for frag_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07007326 __func__, frag_threshold);
7327 return -EIO;
7328 }
7329
7330 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set frag threshold %hu", __func__,
7331 frag_threshold);
7332 }
7333
7334 if ((changed & WIPHY_PARAM_RETRY_SHORT)
7335 || (changed & WIPHY_PARAM_RETRY_LONG))
7336 {
7337 u8 retry_value = (changed & WIPHY_PARAM_RETRY_SHORT) ?
7338 wiphy->retry_short :
7339 wiphy->retry_long;
7340
7341 if ((WNI_CFG_LONG_RETRY_LIMIT_STAMIN > retry_value) ||
7342 (WNI_CFG_LONG_RETRY_LIMIT_STAMAX < retry_value))
7343 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307344 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07007345 __func__, retry_value);
7346 return -EINVAL;
7347 }
7348
7349 if (changed & WIPHY_PARAM_RETRY_SHORT)
7350 {
7351 if (0 != ccmCfgSetInt(hHal, WNI_CFG_LONG_RETRY_LIMIT,
7352 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307353 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -07007354 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307355 hddLog(VOS_TRACE_LEVEL_ERROR,
7356 "%s: ccmCfgSetInt failed for long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07007357 __func__, retry_value);
7358 return -EIO;
7359 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307360 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07007361 __func__, retry_value);
7362 }
7363 else if (changed & WIPHY_PARAM_RETRY_SHORT)
7364 {
7365 if (0 != ccmCfgSetInt(hHal, WNI_CFG_SHORT_RETRY_LIMIT,
7366 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307367 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -07007368 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307369 hddLog(VOS_TRACE_LEVEL_ERROR,
7370 "%s: ccmCfgSetInt failed for short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07007371 __func__, retry_value);
7372 return -EIO;
7373 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307374 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07007375 __func__, retry_value);
7376 }
7377 }
7378
7379 return 0;
7380}
7381
7382/*
7383 * FUNCTION: wlan_hdd_cfg80211_set_txpower
7384 * This function is used to set the txpower
7385 */
7386static int wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
Yue Maf49ba872013-08-19 12:04:25 -07007387#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
7388 struct wireless_dev *wdev,
7389#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007390#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307391 enum tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -07007392#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307393 enum nl80211_tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -07007394#endif
7395 int dbm)
7396{
7397 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307398 tHalHandle hHal = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07007399 tSirMacAddr bssid = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
7400 tSirMacAddr selfMac = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307401 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07007402
7403 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307404 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7405 TRACE_CODE_HDD_CFG80211_SET_TXPOWER,
7406 NO_SESSION, type ));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307407 status = wlan_hdd_validate_context(pHddCtx);
7408
7409 if (0 != status)
7410 {
7411 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7412 "%s: HDD context is not valid", __func__);
7413 return status;
7414 }
7415
7416 hHal = pHddCtx->hHal;
7417
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307418 if (0 != ccmCfgSetInt(hHal, WNI_CFG_CURRENT_TX_POWER_LEVEL,
7419 dbm, ccmCfgSetCallback,
7420 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -07007421 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307422 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07007423 "%s: ccmCfgSetInt failed for tx power %hu", __func__, dbm);
7424 return -EIO;
7425 }
7426
7427 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set tx power level %d dbm", __func__,
7428 dbm);
7429
7430 switch(type)
7431 {
7432 case NL80211_TX_POWER_AUTOMATIC: /*automatically determine transmit power*/
7433 /* Fall through */
7434 case NL80211_TX_POWER_LIMITED: /*limit TX power by the mBm parameter*/
7435 if( sme_SetMaxTxPower(hHal, bssid, selfMac, dbm) != eHAL_STATUS_SUCCESS )
7436 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307437 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Setting maximum tx power failed",
7438 __func__);
7439 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -07007440 }
7441 break;
7442 case NL80211_TX_POWER_FIXED: /*fix TX power to the mBm parameter*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307443 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: NL80211_TX_POWER_FIXED not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -07007444 __func__);
7445 return -EOPNOTSUPP;
7446 break;
7447 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307448 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid power setting type %d",
7449 __func__, type);
Jeff Johnson295189b2012-06-20 16:38:30 -07007450 return -EIO;
7451 }
7452
7453 return 0;
7454}
7455
7456/*
7457 * FUNCTION: wlan_hdd_cfg80211_get_txpower
7458 * This function is used to read the txpower
7459 */
Yue Maf49ba872013-08-19 12:04:25 -07007460static int wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy,
7461#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
7462 struct wireless_dev *wdev,
7463#endif
7464 int *dbm)
Jeff Johnson295189b2012-06-20 16:38:30 -07007465{
7466
7467 hdd_adapter_t *pAdapter;
7468 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307469 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07007470
Jeff Johnsone7245742012-09-05 17:12:55 -07007471 ENTER();
7472
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307473 status = wlan_hdd_validate_context(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07007474
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307475 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007476 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307477 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7478 "%s: HDD context is not valid", __func__);
7479 *dbm = 0;
7480 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007481 }
7482
Jeff Johnson295189b2012-06-20 16:38:30 -07007483 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
7484 if (NULL == pAdapter)
7485 {
7486 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Not in station context " ,__func__);
7487 return -ENOENT;
7488 }
7489
7490 wlan_hdd_get_classAstats(pAdapter);
7491 *dbm = pAdapter->hdd_stats.ClassA_stat.max_pwr;
7492
Jeff Johnsone7245742012-09-05 17:12:55 -07007493 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07007494 return 0;
7495}
7496
7497static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
7498 u8* mac, struct station_info *sinfo)
7499{
7500 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
7501 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7502 int ssidlen = pHddStaCtx->conn_info.SSID.SSID.length;
c_hpothu44ff4e02014-05-08 00:13:57 +05307503 tANI_U32 rate_flags;
Jeff Johnson295189b2012-06-20 16:38:30 -07007504
7505 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
7506 hdd_config_t *pCfg = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -07007507
7508 tANI_U8 OperationalRates[CSR_DOT11_SUPPORTED_RATES_MAX];
7509 tANI_U32 ORLeng = CSR_DOT11_SUPPORTED_RATES_MAX;
7510 tANI_U8 ExtendedRates[CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX];
7511 tANI_U32 ERLeng = CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX;
7512 tANI_U8 MCSRates[SIZE_OF_BASIC_MCS_SET];
7513 tANI_U32 MCSLeng = SIZE_OF_BASIC_MCS_SET;
7514 tANI_U16 maxRate = 0;
7515 tANI_U16 myRate;
7516 tANI_U16 currentRate = 0;
7517 tANI_U8 maxSpeedMCS = 0;
7518 tANI_U8 maxMCSIdx = 0;
7519 tANI_U8 rateFlag = 1;
7520 tANI_U8 i, j, rssidx;
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07007521 tANI_U16 temp;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307522 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07007523
Leo Chang6f8870f2013-03-26 18:11:36 -07007524#ifdef WLAN_FEATURE_11AC
7525 tANI_U32 vht_mcs_map;
7526 eDataRate11ACMaxMcs vhtMaxMcs;
7527#endif /* WLAN_FEATURE_11AC */
7528
Jeff Johnsone7245742012-09-05 17:12:55 -07007529 ENTER();
7530
Jeff Johnson295189b2012-06-20 16:38:30 -07007531 if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) ||
7532 (0 == ssidlen))
7533 {
7534 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Not associated or"
7535 " Invalid ssidlen, %d", __func__, ssidlen);
7536 /*To keep GUI happy*/
7537 return 0;
7538 }
7539
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307540 status = wlan_hdd_validate_context(pHddCtx);
7541
7542 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007543 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307544 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7545 "%s: HDD context is not valid", __func__);
7546 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007547 }
7548
Jeff Johnson295189b2012-06-20 16:38:30 -07007549
Kiet Lam3b17fc82013-09-27 05:24:08 +05307550 wlan_hdd_get_rssi(pAdapter, &sinfo->signal);
7551 sinfo->filled |= STATION_INFO_SIGNAL;
7552
c_hpothu44ff4e02014-05-08 00:13:57 +05307553 if ((eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed) ||
7554 (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed &&
7555 sinfo->signal >= pCfg->linkSpeedRssiHigh))
7556 {
7557 rate_flags = pAdapter->maxRateFlags;
7558 }
7559 else
7560 {
7561 wlan_hdd_get_station_stats(pAdapter);
7562 rate_flags = pAdapter->hdd_stats.ClassA_stat.tx_rate_flags;
7563 }
7564
Jeff Johnson295189b2012-06-20 16:38:30 -07007565 //convert to the UI units of 100kbps
7566 myRate = pAdapter->hdd_stats.ClassA_stat.tx_rate * 5;
7567
7568#ifdef LINKSPEED_DEBUG_ENABLED
Leo Chang6f8870f2013-03-26 18:11:36 -07007569 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 -07007570 sinfo->signal,
7571 pCfg->reportMaxLinkSpeed,
7572 myRate,
7573 (int) pCfg->linkSpeedRssiHigh,
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07007574 (int) pCfg->linkSpeedRssiMid,
7575 (int) pCfg->linkSpeedRssiLow,
Leo Chang6f8870f2013-03-26 18:11:36 -07007576 (int) rate_flags,
7577 (int) pAdapter->hdd_stats.ClassA_stat.mcs_index);
Jeff Johnson295189b2012-06-20 16:38:30 -07007578#endif //LINKSPEED_DEBUG_ENABLED
7579
7580 if (eHDD_LINK_SPEED_REPORT_ACTUAL != pCfg->reportMaxLinkSpeed)
7581 {
7582 // we do not want to necessarily report the current speed
7583 if (eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed)
7584 {
7585 // report the max possible speed
7586 rssidx = 0;
7587 }
7588 else if (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed)
7589 {
7590 // report the max possible speed with RSSI scaling
7591 if (sinfo->signal >= pCfg->linkSpeedRssiHigh)
7592 {
7593 // report the max possible speed
7594 rssidx = 0;
7595 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07007596 else if (sinfo->signal >= pCfg->linkSpeedRssiMid)
Jeff Johnson295189b2012-06-20 16:38:30 -07007597 {
7598 // report middle speed
7599 rssidx = 1;
7600 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07007601 else if (sinfo->signal >= pCfg->linkSpeedRssiLow)
7602 {
7603 // report middle speed
7604 rssidx = 2;
7605 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007606 else
7607 {
7608 // report actual speed
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07007609 rssidx = 3;
Jeff Johnson295189b2012-06-20 16:38:30 -07007610 }
7611 }
7612 else
7613 {
7614 // unknown, treat as eHDD_LINK_SPEED_REPORT_MAX
7615 hddLog(VOS_TRACE_LEVEL_ERROR,
7616 "%s: Invalid value for reportMaxLinkSpeed: %u",
7617 __func__, pCfg->reportMaxLinkSpeed);
7618 rssidx = 0;
7619 }
7620
7621 maxRate = 0;
7622
7623 /* Get Basic Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +05307624 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_OPERATIONAL_RATE_SET,
7625 OperationalRates, &ORLeng))
7626 {
7627 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
7628 /*To keep GUI happy*/
7629 return 0;
7630 }
7631
Jeff Johnson295189b2012-06-20 16:38:30 -07007632 for (i = 0; i < ORLeng; i++)
7633 {
Jeff Johnsone7245742012-09-05 17:12:55 -07007634 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -07007635 {
7636 /* Validate Rate Set */
7637 if (supported_data_rate[j].beacon_rate_index == (OperationalRates[i] & 0x7F))
7638 {
7639 currentRate = supported_data_rate[j].supported_rate[rssidx];
7640 break;
7641 }
7642 }
7643 /* Update MAX rate */
7644 maxRate = (currentRate > maxRate)?currentRate:maxRate;
7645 }
7646
7647 /* Get Extended Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +05307648 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET,
7649 ExtendedRates, &ERLeng))
7650 {
7651 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
7652 /*To keep GUI happy*/
7653 return 0;
7654 }
7655
Jeff Johnson295189b2012-06-20 16:38:30 -07007656 for (i = 0; i < ERLeng; i++)
7657 {
Jeff Johnsone7245742012-09-05 17:12:55 -07007658 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -07007659 {
7660 if (supported_data_rate[j].beacon_rate_index == (ExtendedRates[i] & 0x7F))
7661 {
7662 currentRate = supported_data_rate[j].supported_rate[rssidx];
7663 break;
7664 }
7665 }
7666 /* Update MAX rate */
7667 maxRate = (currentRate > maxRate)?currentRate:maxRate;
7668 }
Kiet Lamb69f8dc2013-11-15 15:34:27 +05307669 /* Get MCS Rate Set --
Kaushik, Sushantdc304d82014-01-22 10:58:37 +05307670 Only if we are always reporting max speed (or)
Kiet Lamb69f8dc2013-11-15 15:34:27 +05307671 if we have good rssi */
Kaushik, Sushantdc304d82014-01-22 10:58:37 +05307672 if ((0 == rssidx) ||
Kiet Lamb69f8dc2013-11-15 15:34:27 +05307673 (eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed))
Jeff Johnson295189b2012-06-20 16:38:30 -07007674 {
Gopichand Nakkala05ab1322013-02-15 11:28:38 +05307675 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_CURRENT_MCS_SET,
7676 MCSRates, &MCSLeng))
7677 {
7678 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
7679 /*To keep GUI happy*/
7680 return 0;
7681 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007682 rateFlag = 0;
Leo Chang6f8870f2013-03-26 18:11:36 -07007683#ifdef WLAN_FEATURE_11AC
7684 /* VHT80 rate has seperate rate table */
Gopichand Nakkala4c705372013-04-24 13:20:33 +05307685 if (rate_flags & (eHAL_TX_RATE_VHT20|eHAL_TX_RATE_VHT40|eHAL_TX_RATE_VHT80))
Jeff Johnson295189b2012-06-20 16:38:30 -07007686 {
Leo Chang6f8870f2013-03-26 18:11:36 -07007687 ccmCfgGetInt(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_VHT_TX_MCS_MAP, &vht_mcs_map);
Gopichand Nakkala4c705372013-04-24 13:20:33 +05307688 vhtMaxMcs = (eDataRate11ACMaxMcs)(vht_mcs_map & DATA_RATE_11AC_MCS_MASK );
Leo Chang6f8870f2013-03-26 18:11:36 -07007689 if (rate_flags & eHAL_TX_RATE_SGI)
Jeff Johnson295189b2012-06-20 16:38:30 -07007690 {
Leo Chang6f8870f2013-03-26 18:11:36 -07007691 rateFlag |= 1;
Jeff Johnson295189b2012-06-20 16:38:30 -07007692 }
Leo Chang6f8870f2013-03-26 18:11:36 -07007693 if (DATA_RATE_11AC_MAX_MCS_7 == vhtMaxMcs)
Jeff Johnson295189b2012-06-20 16:38:30 -07007694 {
Leo Chang6f8870f2013-03-26 18:11:36 -07007695 maxMCSIdx = 7;
7696 }
7697 else if (DATA_RATE_11AC_MAX_MCS_8 == vhtMaxMcs)
7698 {
7699 maxMCSIdx = 8;
7700 }
7701 else if (DATA_RATE_11AC_MAX_MCS_9 == vhtMaxMcs)
7702 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +05307703 //VHT20 is supporting 0~8
7704 if (rate_flags & eHAL_TX_RATE_VHT20)
7705 maxMCSIdx = 8;
7706 else
7707 maxMCSIdx = 9;
Leo Chang6f8870f2013-03-26 18:11:36 -07007708 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +05307709
7710 if (rate_flags & eHAL_TX_RATE_VHT80)
7711 {
7712 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT80_rate[rateFlag];
7713 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT80_rate[rateFlag];
7714 }
7715 else if (rate_flags & eHAL_TX_RATE_VHT40)
7716 {
7717 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT40_rate[rateFlag];
7718 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT40_rate[rateFlag];
7719 }
7720 else if (rate_flags & eHAL_TX_RATE_VHT20)
7721 {
7722 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT20_rate[rateFlag];
7723 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT20_rate[rateFlag];
7724 }
7725
Leo Chang6f8870f2013-03-26 18:11:36 -07007726 maxSpeedMCS = 1;
7727 if (currentRate > maxRate)
7728 {
7729 maxRate = currentRate;
7730 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +05307731
Leo Chang6f8870f2013-03-26 18:11:36 -07007732 }
7733 else
7734#endif /* WLAN_FEATURE_11AC */
7735 {
7736 if (rate_flags & eHAL_TX_RATE_HT40)
7737 {
7738 rateFlag |= 1;
7739 }
7740 if (rate_flags & eHAL_TX_RATE_SGI)
7741 {
7742 rateFlag |= 2;
7743 }
7744
7745 for (i = 0; i < MCSLeng; i++)
7746 {
7747 temp = sizeof(supported_mcs_rate) / sizeof(supported_mcs_rate[0]);
7748 for (j = 0; j < temp; j++)
7749 {
7750 if (supported_mcs_rate[j].beacon_rate_index == MCSRates[i])
7751 {
7752 currentRate = supported_mcs_rate[j].supported_rate[rateFlag];
7753 break;
7754 }
7755 }
7756 if ((j < temp) && (currentRate > maxRate))
7757 {
7758 maxRate = currentRate;
7759 maxSpeedMCS = 1;
7760 maxMCSIdx = supported_mcs_rate[j].beacon_rate_index;
7761 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007762 }
7763 }
7764 }
7765
Gopichand Nakkala4c705372013-04-24 13:20:33 +05307766 else if (!(rate_flags & eHAL_TX_RATE_LEGACY))
7767 {
7768 maxRate = myRate;
7769 maxSpeedMCS = 1;
7770 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
7771 }
7772
Jeff Johnson295189b2012-06-20 16:38:30 -07007773 // make sure we report a value at least as big as our current rate
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07007774 if (((maxRate < myRate) && (0 == rssidx)) ||
7775 (0 == maxRate))
Jeff Johnson295189b2012-06-20 16:38:30 -07007776 {
7777 maxRate = myRate;
7778 if (rate_flags & eHAL_TX_RATE_LEGACY)
7779 {
7780 maxSpeedMCS = 0;
7781 }
7782 else
7783 {
7784 maxSpeedMCS = 1;
7785 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
7786 }
7787 }
7788
Gopichand Nakkala4c705372013-04-24 13:20:33 +05307789 if (rate_flags & eHAL_TX_RATE_LEGACY)
Jeff Johnson295189b2012-06-20 16:38:30 -07007790 {
7791 sinfo->txrate.legacy = maxRate;
7792#ifdef LINKSPEED_DEBUG_ENABLED
7793 pr_info("Reporting legacy rate %d\n", sinfo->txrate.legacy);
7794#endif //LINKSPEED_DEBUG_ENABLED
7795 }
7796 else
7797 {
7798 sinfo->txrate.mcs = maxMCSIdx;
Leo Chang6f8870f2013-03-26 18:11:36 -07007799#ifdef WLAN_FEATURE_11AC
7800 sinfo->txrate.nss = 1;
7801 if (rate_flags & eHAL_TX_RATE_VHT80)
7802 {
7803 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
Gopichand Nakkala4c705372013-04-24 13:20:33 +05307804 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
Leo Chang6f8870f2013-03-26 18:11:36 -07007805 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +05307806 else if (rate_flags & eHAL_TX_RATE_VHT40)
Leo Chang6f8870f2013-03-26 18:11:36 -07007807 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +05307808 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
7809 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
7810 }
7811 else if (rate_flags & eHAL_TX_RATE_VHT20)
7812 {
7813 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
7814 }
7815#endif /* WLAN_FEATURE_11AC */
7816 if (rate_flags & (eHAL_TX_RATE_HT20 | eHAL_TX_RATE_HT40))
7817 {
7818 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
7819 if (rate_flags & eHAL_TX_RATE_HT40)
7820 {
7821 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
7822 }
Leo Chang6f8870f2013-03-26 18:11:36 -07007823 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007824 if (rate_flags & eHAL_TX_RATE_SGI)
7825 {
7826 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
7827 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +05307828
Jeff Johnson295189b2012-06-20 16:38:30 -07007829#ifdef LINKSPEED_DEBUG_ENABLED
7830 pr_info("Reporting MCS rate %d flags %x\n",
7831 sinfo->txrate.mcs,
7832 sinfo->txrate.flags );
7833#endif //LINKSPEED_DEBUG_ENABLED
7834 }
7835 }
7836 else
7837 {
7838 // report current rate instead of max rate
7839
7840 if (rate_flags & eHAL_TX_RATE_LEGACY)
7841 {
7842 //provide to the UI in units of 100kbps
7843 sinfo->txrate.legacy = myRate;
7844#ifdef LINKSPEED_DEBUG_ENABLED
7845 pr_info("Reporting actual legacy rate %d\n", sinfo->txrate.legacy);
7846#endif //LINKSPEED_DEBUG_ENABLED
7847 }
7848 else
7849 {
7850 //must be MCS
7851 sinfo->txrate.mcs = pAdapter->hdd_stats.ClassA_stat.mcs_index;
Leo Chang6f8870f2013-03-26 18:11:36 -07007852#ifdef WLAN_FEATURE_11AC
7853 sinfo->txrate.nss = 1;
7854 if (rate_flags & eHAL_TX_RATE_VHT80)
7855 {
7856 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
7857 }
7858 else
7859#endif /* WLAN_FEATURE_11AC */
7860 {
7861 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
7862 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007863 if (rate_flags & eHAL_TX_RATE_SGI)
7864 {
7865 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
7866 }
7867 if (rate_flags & eHAL_TX_RATE_HT40)
7868 {
7869 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
7870 }
Leo Chang6f8870f2013-03-26 18:11:36 -07007871#ifdef WLAN_FEATURE_11AC
7872 else if (rate_flags & eHAL_TX_RATE_VHT80)
7873 {
7874 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
7875 }
7876#endif /* WLAN_FEATURE_11AC */
Jeff Johnson295189b2012-06-20 16:38:30 -07007877#ifdef LINKSPEED_DEBUG_ENABLED
7878 pr_info("Reporting actual MCS rate %d flags %x\n",
7879 sinfo->txrate.mcs,
7880 sinfo->txrate.flags );
7881#endif //LINKSPEED_DEBUG_ENABLED
7882 }
7883 }
7884 sinfo->filled |= STATION_INFO_TX_BITRATE;
7885
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -07007886 sinfo->tx_packets =
7887 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[0] +
7888 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[1] +
7889 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[2] +
7890 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[3];
7891
7892 sinfo->tx_retries =
7893 pAdapter->hdd_stats.summary_stat.retry_cnt[0] +
7894 pAdapter->hdd_stats.summary_stat.retry_cnt[1] +
7895 pAdapter->hdd_stats.summary_stat.retry_cnt[2] +
7896 pAdapter->hdd_stats.summary_stat.retry_cnt[3];
7897
7898 sinfo->tx_failed =
7899 pAdapter->hdd_stats.summary_stat.fail_cnt[0] +
7900 pAdapter->hdd_stats.summary_stat.fail_cnt[1] +
7901 pAdapter->hdd_stats.summary_stat.fail_cnt[2] +
7902 pAdapter->hdd_stats.summary_stat.fail_cnt[3];
7903
7904 sinfo->filled |=
7905 STATION_INFO_TX_PACKETS |
7906 STATION_INFO_TX_RETRIES |
7907 STATION_INFO_TX_FAILED;
7908
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307909 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7910 TRACE_CODE_HDD_CFG80211_GET_STA,
7911 pAdapter->sessionId, maxRate));
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -07007912 EXIT();
7913 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07007914}
7915
7916static int wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
Sameer Thalappilc9f26e92013-06-07 10:11:06 -07007917 struct net_device *dev, bool mode, int timeout)
Jeff Johnson295189b2012-06-20 16:38:30 -07007918{
7919 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +05307920 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07007921 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307922 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07007923
Jeff Johnsone7245742012-09-05 17:12:55 -07007924 ENTER();
7925
Jeff Johnson295189b2012-06-20 16:38:30 -07007926 if (NULL == pAdapter)
7927 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08007928 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007929 return -ENODEV;
7930 }
7931
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307932 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7933 TRACE_CODE_HDD_CFG80211_SET_POWER_MGMT,
7934 pAdapter->sessionId, timeout));
7935
Gopichand Nakkala20c4c042013-04-19 22:08:55 +05307936 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307937 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +05307938
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307939 if (0 != status)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307940 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307941 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7942 "%s: HDD context is not valid", __func__);
7943 return status;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307944 }
7945
Gopichand Nakkala20c4c042013-04-19 22:08:55 +05307946 if ((DRIVER_POWER_MODE_AUTO == !mode) &&
7947 (TRUE == pHddCtx->hdd_wlan_suspended) &&
7948 (pHddCtx->cfg_ini->fhostArpOffload) &&
7949 (eConnectionState_Associated ==
7950 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
7951 {
Amar Singhald53568e2013-09-26 11:03:45 -07007952
7953 hddLog(VOS_TRACE_LEVEL_INFO,
7954 "offload: in cfg80211_set_power_mgmt, calling arp offload");
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05307955 vos_status = hdd_conf_arp_offload(pAdapter, TRUE);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +05307956 if (!VOS_IS_STATUS_SUCCESS(vos_status))
7957 {
7958 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007959 "%s:Failed to enable ARPOFFLOAD Feature %d",
Gopichand Nakkala20c4c042013-04-19 22:08:55 +05307960 __func__, vos_status);
7961 }
7962 }
7963
Jeff Johnson295189b2012-06-20 16:38:30 -07007964 /**The get power cmd from the supplicant gets updated by the nl only
7965 *on successful execution of the function call
7966 *we are oppositely mapped w.r.t mode in the driver
7967 **/
7968 vos_status = wlan_hdd_enter_bmps(pAdapter, !mode);
7969
Jeff Johnsone7245742012-09-05 17:12:55 -07007970 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07007971 if (VOS_STATUS_E_FAILURE == vos_status)
7972 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307973 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7974 "%s: failed to enter bmps mode", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007975 return -EINVAL;
7976 }
7977 return 0;
7978}
7979
7980
7981#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
7982static int wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
7983 struct net_device *netdev,
7984 u8 key_index)
7985{
Jeff Johnsone7245742012-09-05 17:12:55 -07007986 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07007987 return 0;
7988}
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307989#endif //LINUX_VERSION_CODE
Jeff Johnson295189b2012-06-20 16:38:30 -07007990
7991#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
7992static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
7993 struct net_device *dev,
7994 struct ieee80211_txq_params *params)
7995{
Jeff Johnsone7245742012-09-05 17:12:55 -07007996 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07007997 return 0;
7998}
7999#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
8000static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
8001 struct ieee80211_txq_params *params)
8002{
Jeff Johnsone7245742012-09-05 17:12:55 -07008003 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07008004 return 0;
8005}
8006#endif //LINUX_VERSION_CODE
8007
8008static int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
8009 struct net_device *dev, u8 *mac)
8010{
8011 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308012 hdd_context_t *pHddCtx;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08008013 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308014 int status;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08008015 v_U8_t staId;
Jeff Johnson295189b2012-06-20 16:38:30 -07008016
Jeff Johnsone7245742012-09-05 17:12:55 -07008017 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308018
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308019 if ( NULL == pAdapter )
Jeff Johnson295189b2012-06-20 16:38:30 -07008020 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308021 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008022 return -EINVAL;
8023 }
8024
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308025 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
8026 TRACE_CODE_HDD_CFG80211_DEL_STA,
8027 pAdapter->sessionId, pAdapter->device_mode));
8028
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308029 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8030 status = wlan_hdd_validate_context(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07008031
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308032 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008033 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308034 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8035 "%s: HDD context is not valid", __func__);
8036 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008037 }
8038
Jeff Johnson295189b2012-06-20 16:38:30 -07008039 if ( (WLAN_HDD_SOFTAP == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -07008040 || (WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -07008041 )
8042 {
8043 if( NULL == mac )
8044 {
8045 v_U16_t i;
8046 for(i = 0; i < WLAN_MAX_STA_COUNT; i++)
8047 {
Rajesh Chauhan18488fc2013-08-22 10:15:03 -07008048 if ((pAdapter->aStaInfo[i].isUsed) &&
8049 (!pAdapter->aStaInfo[i].isDeauthInProgress))
Jeff Johnson295189b2012-06-20 16:38:30 -07008050 {
8051 u8 *macAddr = pAdapter->aStaInfo[i].macAddrSTA.bytes;
8052 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -08008053 "%s: Delete STA with MAC::"
8054 MAC_ADDRESS_STR,
8055 __func__, MAC_ADDR_ARRAY(macAddr));
Rajesh Chauhan18488fc2013-08-22 10:15:03 -07008056 vos_status = hdd_softap_sta_deauth(pAdapter, macAddr);
8057 if (VOS_IS_STATUS_SUCCESS(vos_status))
8058 pAdapter->aStaInfo[i].isDeauthInProgress = TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -07008059 }
8060 }
8061 }
8062 else
8063 {
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08008064
8065 vos_status = hdd_softap_GetStaId(pAdapter,(v_MACADDR_t *)mac, &staId);
8066 if (!VOS_IS_STATUS_SUCCESS(vos_status))
8067 {
8068 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -08008069 "%s: Skip this DEL STA as this is not used::"
8070 MAC_ADDRESS_STR,
8071 __func__, MAC_ADDR_ARRAY(mac));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08008072 return -ENOENT;
8073 }
8074
8075 if( pAdapter->aStaInfo[staId].isDeauthInProgress == TRUE)
8076 {
8077 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -08008078 "%s: Skip this DEL STA as deauth is in progress::"
8079 MAC_ADDRESS_STR,
8080 __func__, MAC_ADDR_ARRAY(mac));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08008081 return -ENOENT;
8082 }
8083
8084 pAdapter->aStaInfo[staId].isDeauthInProgress = TRUE;
8085
Jeff Johnson295189b2012-06-20 16:38:30 -07008086 hddLog(VOS_TRACE_LEVEL_INFO,
8087 "%s: Delete STA with MAC::"
Arif Hussain24bafea2013-11-15 15:10:03 -08008088 MAC_ADDRESS_STR,
Jeff Johnson295189b2012-06-20 16:38:30 -07008089 __func__,
Arif Hussain24bafea2013-11-15 15:10:03 -08008090 MAC_ADDR_ARRAY(mac));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08008091
8092 vos_status = hdd_softap_sta_deauth(pAdapter, mac);
8093 if (!VOS_IS_STATUS_SUCCESS(vos_status))
8094 {
8095 pAdapter->aStaInfo[staId].isDeauthInProgress = FALSE;
8096 hddLog(VOS_TRACE_LEVEL_INFO,
8097 "%s: STA removal failed for ::"
Arif Hussain24bafea2013-11-15 15:10:03 -08008098 MAC_ADDRESS_STR,
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08008099 __func__,
Arif Hussain24bafea2013-11-15 15:10:03 -08008100 MAC_ADDR_ARRAY(mac));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08008101 return -ENOENT;
8102 }
8103
Jeff Johnson295189b2012-06-20 16:38:30 -07008104 }
8105 }
8106
8107 EXIT();
8108
8109 return 0;
8110}
8111
Hoonki Lee11f7dda2013-02-14 16:55:44 -08008112static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
8113 struct net_device *dev, u8 *mac, struct station_parameters *params)
8114{
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308115 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkalab977a972013-02-18 19:15:09 -08008116 int status = -EPERM;
Hoonki Lee11f7dda2013-02-14 16:55:44 -08008117#ifdef FEATURE_WLAN_TDLS
8118 u32 mask, set;
Hoonki Lee11f7dda2013-02-14 16:55:44 -08008119 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308120
8121 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
8122 TRACE_CODE_HDD_CFG80211_ADD_STA,
8123 pAdapter->sessionId, params->listen_interval));
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008124 mask = params->sta_flags_mask;
8125
8126 set = params->sta_flags_set;
8127
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07008128#ifdef WLAN_FEATURE_TDLS_DEBUG
8129 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8130 "%s: mask 0x%x set 0x%x " MAC_ADDRESS_STR,
8131 __func__, mask, set, MAC_ADDR_ARRAY(mac));
8132#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008133
8134 if (mask & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
8135 if (set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008136 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 0, NULL);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008137 }
8138 }
8139#endif
Gopichand Nakkalab977a972013-02-18 19:15:09 -08008140 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -07008141}
8142
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008143
8144#ifdef FEATURE_WLAN_LFR
Wilson Yang6507c4e2013-10-01 20:11:19 -07008145#define MAX_PMKSAIDS_IN_CACHE 8
8146
8147static tPmkidCacheInfo PMKIDCache[MAX_PMKSAIDS_IN_CACHE]; // HDD local cache
8148static tANI_U32 PMKIDCacheIndex; // HDD local Cache index
8149
8150
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008151static int wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
Jeff Johnsond13512a2012-07-17 11:42:19 -07008152 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008153{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308154 tANI_U32 j=0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008155 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
8156 tHalHandle halHandle;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308157 eHalStatus result;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308158 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008159 tANI_U8 BSSIDMatched = 0;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308160 hdd_context_t *pHddCtx;
Jeff Johnson0299d0a2013-10-30 12:37:43 -07008161 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: set PMKSA for " MAC_ADDRESS_STR,
8162 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
Jeff Johnsone7245742012-09-05 17:12:55 -07008163
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308164 // Validate pAdapter
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308165 if ( NULL == pAdapter )
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008166 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308167 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008168 return -EINVAL;
8169 }
8170
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308171 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8172 status = wlan_hdd_validate_context(pHddCtx);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008173
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308174 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008175 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308176 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8177 "%s: HDD context is not valid", __func__);
8178 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008179 }
8180
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308181 // Retrieve halHandle
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008182 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
8183
Wilson Yang6507c4e2013-10-01 20:11:19 -07008184 for (j = 0; j < PMKIDCacheIndex; j++)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008185 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308186 if(vos_mem_compare(PMKIDCache[j].BSSID,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008187 pmksa->bssid, WNI_CFG_BSSID_LEN))
8188 {
8189 /* BSSID matched previous entry. Overwrite it. */
8190 BSSIDMatched = 1;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308191 vos_mem_copy(PMKIDCache[j].BSSID,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008192 pmksa->bssid, WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308193 vos_mem_copy(PMKIDCache[j].PMKID,
8194 pmksa->pmkid,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008195 CSR_RSN_PMKID_SIZE);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308196 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Reusing cache entry %d.",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008197 __func__, j );
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008198 dump_bssid(pmksa->bssid);
8199 dump_pmkid(halHandle, pmksa->pmkid);
8200 break;
8201 }
8202 }
8203
Madan Mohan Koyyalamudic4b317d2012-10-18 19:43:08 -07008204 /* Check we compared all entries,if then take the first slot now */
Wilson Yang6507c4e2013-10-01 20:11:19 -07008205 if(j == MAX_PMKSAIDS_IN_CACHE) PMKIDCacheIndex=0;
Madan Mohan Koyyalamudic4b317d2012-10-18 19:43:08 -07008206
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008207 if (!BSSIDMatched)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308208 {
8209 // Now, we DON'T have a BSSID match, so take a new entry in the cache.
Wilson Yang6507c4e2013-10-01 20:11:19 -07008210 vos_mem_copy(PMKIDCache[PMKIDCacheIndex].BSSID,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308211 pmksa->bssid, ETHER_ADDR_LEN);
Wilson Yang6507c4e2013-10-01 20:11:19 -07008212 vos_mem_copy(PMKIDCache[PMKIDCacheIndex].PMKID,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308213 pmksa->pmkid,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008214 CSR_RSN_PMKID_SIZE);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308215 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Adding a new cache entry %d.",
Wilson Yang6507c4e2013-10-01 20:11:19 -07008216 __func__, PMKIDCacheIndex );
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008217 dump_bssid(pmksa->bssid);
8218 dump_pmkid(halHandle, pmksa->pmkid);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308219 // Increment the HDD Local Cache index
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008220 // The "i=0" doesn't work for the call to sme_RoamSetPMKIDCache() - LFR FIXME
Wilson Yang6507c4e2013-10-01 20:11:19 -07008221 if (PMKIDCacheIndex <= (MAX_PMKSAIDS_IN_CACHE-1)) PMKIDCacheIndex++; else PMKIDCacheIndex = 0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008222 }
8223
8224
8225 // Calling csrRoamSetPMKIDCache to configure the PMKIDs into the cache
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308226 //hddLog(LOG1, FL("%s: Calling csrRoamSetPMKIDCache with %d cache entries."),
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008227 // __func__, i );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308228 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Calling csrRoamSetPMKIDCache with %d cache entries.",
Wilson Yang6507c4e2013-10-01 20:11:19 -07008229 __func__, PMKIDCacheIndex );
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008230 // Finally set the PMKSA ID Cache in CSR
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308231 result = sme_RoamSetPMKIDCache(halHandle,pAdapter->sessionId,
8232 PMKIDCache,
Wilson Yang6507c4e2013-10-01 20:11:19 -07008233 PMKIDCacheIndex);
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308234 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
8235 TRACE_CODE_HDD_CFG80211_SET_PMKSA,
8236 pAdapter->sessionId, result));
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008237 return 0;
8238}
8239
8240
Wilson Yang6507c4e2013-10-01 20:11:19 -07008241
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008242static int wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
Wilson Yang6507c4e2013-10-01 20:11:19 -07008243 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008244{
Wilson Yang6507c4e2013-10-01 20:11:19 -07008245 tANI_U32 j=0;
8246 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
8247 tHalHandle halHandle;
Wilson Yang6507c4e2013-10-01 20:11:19 -07008248 tANI_U8 BSSIDMatched = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -07008249 hdd_context_t *pHddCtx;
Wilson Yangef657d32014-01-15 19:19:23 -08008250 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -07008251
Jeff Johnson0299d0a2013-10-30 12:37:43 -07008252 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: deleting PMKSA for " MAC_ADDRESS_STR,
8253 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
Wilson Yang6507c4e2013-10-01 20:11:19 -07008254
8255 /* Validate pAdapter */
8256 if (NULL == pAdapter)
8257 {
8258 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
8259 return -EINVAL;
8260 }
8261
8262 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8263 status = wlan_hdd_validate_context(pHddCtx);
8264
8265 if (0 != status)
8266 {
8267 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8268 "%s: HDD context is not valid", __func__);
8269 return status;
8270 }
8271
8272 /*Retrieve halHandle*/
8273 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
8274
8275 /*in case index is 0,no entry to delete*/
8276 if (0 == PMKIDCacheIndex)
8277 {
8278 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid entry to delete" ,
8279 __func__);
8280 return -EINVAL;
8281 }
8282
8283 /*find the matching PMKSA entry from j=0 to (index-1),
8284 * and delete the matched one
8285 */
8286 for (j = 0; j<PMKIDCacheIndex; j++)
8287 {
8288 if (vos_mem_compare(PMKIDCache[j].BSSID,
8289 pmksa->bssid,
8290 WNI_CFG_BSSID_LEN))
8291 {
8292 /* BSSID matched entry */
8293 BSSIDMatched = 1;
8294
8295 if (j<PMKIDCacheIndex-1)
8296 {
8297 /*replace the matching entry with the last entry in HDD local cache*/
8298 vos_mem_copy(PMKIDCache[j].BSSID,
8299 PMKIDCache[PMKIDCacheIndex-1].BSSID,
8300 WNI_CFG_BSSID_LEN);
8301 vos_mem_copy(PMKIDCache[j].PMKID,
8302 PMKIDCache[PMKIDCacheIndex-1].PMKID,
8303 CSR_RSN_PMKID_SIZE);
8304 }
8305
8306 /*clear the last entry in HDD cache ---[index-1]*/
Wilson Yang6507c4e2013-10-01 20:11:19 -07008307 vos_mem_zero(PMKIDCache[PMKIDCacheIndex-1].BSSID, WNI_CFG_BSSID_LEN);
8308 vos_mem_zero(PMKIDCache[PMKIDCacheIndex-1].PMKID, CSR_RSN_PMKID_SIZE);
8309
8310 /*reduce the PMKID array index*/
8311 PMKIDCacheIndex--;
8312
8313 /*delete the last PMKID cache in CSR*/
Wilson Yangef657d32014-01-15 19:19:23 -08008314 if (eHAL_STATUS_SUCCESS !=
8315 sme_RoamDelPMKIDfromCache(halHandle, pAdapter->sessionId, pmksa->bssid))
Wilson Yang6507c4e2013-10-01 20:11:19 -07008316 {
8317 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: cannot delete PMKSA %d CONTENT.",
8318 __func__,PMKIDCacheIndex);
Wilson Yangef657d32014-01-15 19:19:23 -08008319 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -07008320 }
8321
8322 dump_bssid(pmksa->bssid);
8323 dump_pmkid(halHandle,pmksa->pmkid);
8324
8325 break;
8326 }
8327 }
8328
8329 /* we compare all entries,but cannot find matching entry */
8330 if (j == MAX_PMKSAIDS_IN_CACHE && !BSSIDMatched)
8331 {
Jeff Johnson0299d0a2013-10-30 12:37:43 -07008332 hddLog(VOS_TRACE_LEVEL_FATAL,
8333 "%s: No such PMKSA entry existed " MAC_ADDRESS_STR,
8334 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
Wilson Yang6507c4e2013-10-01 20:11:19 -07008335 dump_bssid(pmksa->bssid);
8336 dump_pmkid(halHandle, pmksa->pmkid);
8337 return -EINVAL;
8338 }
Wilson Yangef657d32014-01-15 19:19:23 -08008339 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008340}
8341
Wilson Yang6507c4e2013-10-01 20:11:19 -07008342
8343
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008344static int wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
8345{
Wilson Yang6507c4e2013-10-01 20:11:19 -07008346 tANI_U32 j=0;
8347 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
8348 tHalHandle halHandle;
8349 hdd_context_t *pHddCtx;
8350 tANI_U8 *pBSSId;
Wilson Yangef657d32014-01-15 19:19:23 -08008351 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -07008352
8353 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: flushing PMKSA ",__func__);
8354
8355 /* Validate pAdapter */
8356 if (NULL == pAdapter)
8357 {
8358 hddLog(VOS_TRACE_LEVEL_ERROR,
8359 "%s: Invalid Adapter" ,__func__);
8360 return -EINVAL;
8361 }
8362
8363 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8364 status = wlan_hdd_validate_context(pHddCtx);
8365
8366 if (0 != status)
8367 {
8368 hddLog(VOS_TRACE_LEVEL_ERROR,
8369 "%s: HDD context is not valid", __func__);
8370 return status;
8371 }
8372
8373 /*Retrieve halHandle*/
8374 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
8375
8376 /*in case index is 0,no entry to delete*/
8377 if (0 == PMKIDCacheIndex)
8378 {
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +05308379 hddLog(VOS_TRACE_LEVEL_ERROR, FL("No entries to flush"));
Wilson Yang6507c4e2013-10-01 20:11:19 -07008380 return -EINVAL;
8381 }
8382
8383 /*delete all the PMKSA one by one */
8384 for (j = 0; j<PMKIDCacheIndex; j++)
8385 {
Wilson Yang6507c4e2013-10-01 20:11:19 -07008386 pBSSId =(tANI_U8 *)(PMKIDCache[j].BSSID);
Wilson Yang6507c4e2013-10-01 20:11:19 -07008387
8388 /*delete the PMKID in CSR*/
Wilson Yangef657d32014-01-15 19:19:23 -08008389 if (eHAL_STATUS_SUCCESS !=
8390 sme_RoamDelPMKIDfromCache(halHandle, pAdapter->sessionId, pBSSId))
Wilson Yang6507c4e2013-10-01 20:11:19 -07008391 {
8392 hddLog(VOS_TRACE_LEVEL_ERROR ,"%s cannot flush PMKIDCache %d.",
8393 __func__,j);
Wilson Yangef657d32014-01-15 19:19:23 -08008394 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -07008395 }
Kiet Lam8d21d5b2013-10-31 17:18:29 +05308396 /*clear the entry in HDD cache 0--index-1 */
8397 vos_mem_zero(PMKIDCache[j].BSSID, WNI_CFG_BSSID_LEN);
8398 vos_mem_zero(PMKIDCache[j].PMKID, CSR_RSN_PMKID_SIZE);
Wilson Yang6507c4e2013-10-01 20:11:19 -07008399 }
8400
8401 PMKIDCacheIndex = 0;
Wilson Yangef657d32014-01-15 19:19:23 -08008402 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008403}
8404#endif
8405
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07008406#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308407static int wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07008408 struct net_device *dev, struct cfg80211_update_ft_ies_params *ftie)
8409{
8410 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
8411 hdd_station_ctx_t *pHddStaCtx;
8412
8413 if (NULL == pAdapter)
8414 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08008415 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07008416 return -ENODEV;
8417 }
8418
8419 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
8420
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308421 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
8422 TRACE_CODE_HDD_CFG80211_UPDATE_FT_IES,
8423 pAdapter->sessionId, pHddStaCtx->conn_info.connState));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07008424 // Added for debug on reception of Re-assoc Req.
8425 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
8426 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08008427 hddLog(LOGE, FL("Called with Ie of length = %zu when not associated"),
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07008428 ftie->ie_len);
Arif Hussain6d2a3322013-11-17 19:50:10 -08008429 hddLog(LOGE, FL("Should be Re-assoc Req IEs"));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07008430 }
8431
8432#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG
Arif Hussain6d2a3322013-11-17 19:50:10 -08008433 hddLog(LOGE, FL("%s called with Ie of length = %zu"), __func__,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07008434 ftie->ie_len);
8435#endif
8436
8437 // Pass the received FT IEs to SME
Gopichand Nakkala356fb102013-03-06 12:34:04 +05308438 sme_SetFTIEs( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
8439 (const u8 *)ftie->ie,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07008440 ftie->ie_len);
8441 return 0;
8442}
8443#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008444
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308445#ifdef FEATURE_WLAN_SCAN_PNO
8446
8447void hdd_cfg80211_sched_scan_done_callback(void *callbackContext,
8448 tSirPrefNetworkFoundInd *pPrefNetworkFoundInd)
8449{
8450 int ret;
8451 hdd_adapter_t* pAdapter = (hdd_adapter_t*)callbackContext;
8452 hdd_context_t *pHddCtx;
8453
Nirav Shah80830bf2013-12-31 16:35:12 +05308454 ENTER();
8455
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308456 if (NULL == pAdapter)
8457 {
Agarwal Ashish971c2882013-10-30 20:11:12 +05308458 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308459 "%s: HDD adapter is Null", __func__);
8460 return ;
8461 }
8462
8463 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8464 if (NULL == pHddCtx)
8465 {
8466 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8467 "%s: HDD context is Null!!!", __func__);
8468 return ;
8469 }
8470
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05308471 spin_lock(&pHddCtx->schedScan_lock);
8472 if (TRUE == pHddCtx->isWiphySuspended)
8473 {
8474 pHddCtx->isSchedScanUpdatePending = TRUE;
8475 spin_unlock(&pHddCtx->schedScan_lock);
8476 hddLog(VOS_TRACE_LEVEL_INFO,
8477 "%s: Update cfg80211 scan database after it resume", __func__);
8478 return ;
8479 }
8480 spin_unlock(&pHddCtx->schedScan_lock);
8481
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308482 ret = wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter);
8483
8484 if (0 > ret)
8485 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
8486
8487 cfg80211_sched_scan_results(pHddCtx->wiphy);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05308488 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8489 "%s: cfg80211 scan result database updated", __func__);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308490}
8491
8492/*
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +05308493 * FUNCTION: wlan_hdd_is_pno_allowed
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +05308494 * Disallow pno if any session is active
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +05308495 */
8496static eHalStatus wlan_hdd_is_pno_allowed(hdd_adapter_t *pAdapter)
8497{
8498 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
8499 hdd_adapter_t *pTempAdapter = NULL;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +05308500 hdd_station_ctx_t *pStaCtx;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +05308501 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8502 int status = 0;
8503 status = hdd_get_front_adapter(pHddCtx, &pAdapterNode);
8504
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +05308505 /* The current firmware design does not allow PNO during any
8506 * active sessions. Hence, determine the active sessions
8507 * and return a failure.
8508 */
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +05308509 while ((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status))
8510 {
8511 pTempAdapter = pAdapterNode->pAdapter;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +05308512 pStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pTempAdapter);
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +05308513
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +05308514 if (((WLAN_HDD_INFRA_STATION == pTempAdapter->device_mode)
8515 && (eConnectionState_NotConnected != pStaCtx->conn_info.connState))
8516 || (WLAN_HDD_P2P_CLIENT == pTempAdapter->device_mode)
8517 || (WLAN_HDD_P2P_GO == pTempAdapter->device_mode)
8518 || (WLAN_HDD_SOFTAP == pTempAdapter->device_mode)
8519 )
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +05308520 {
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +05308521 return eHAL_STATUS_FAILURE;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +05308522 }
8523 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
8524 pAdapterNode = pNext;
8525 }
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +05308526 return eHAL_STATUS_SUCCESS;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +05308527}
8528
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +05308529void hdd_cfg80211_sched_scan_start_status_cb(void *callbackContext, VOS_STATUS status)
8530{
8531 hdd_adapter_t *pAdapter = callbackContext;
8532 hdd_context_t *pHddCtx;
8533
8534 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
8535 {
8536 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8537 FL("Invalid adapter or adapter has invalid magic"));
8538 return;
8539 }
8540
8541 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8542 if (0 != wlan_hdd_validate_context(pHddCtx))
8543 {
8544 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8545 FL("HDD context is not valid"));
8546 return;
8547 }
8548
8549 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8550 FL("PNO enable response status = %d"), status);
8551
8552 pAdapter->pno_req_status = (status == VOS_STATUS_SUCCESS) ? 0 : -EBUSY;
8553 complete(&pAdapter->pno_comp_var);
8554}
8555
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +05308556/*
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308557 * FUNCTION: wlan_hdd_cfg80211_sched_scan_start
8558 * NL interface to enable PNO
8559 */
8560static int wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
8561 struct net_device *dev, struct cfg80211_sched_scan_request *request)
8562{
8563 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
8564 tpSirPNOScanReq pPnoRequest = NULL;
8565 hdd_context_t *pHddCtx;
8566 tHalHandle hHal;
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +05308567 v_U32_t i, indx, num_ch, tempInterval;
Sushant Kaushikd62d9782014-02-19 15:39:40 +05308568 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
8569 u8 channels_allowed[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308570 v_U32_t num_channels_allowed = WNI_CFG_VALID_CHANNEL_LIST_LEN;
8571 eHalStatus status = eHAL_STATUS_FAILURE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308572 int ret = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308573
8574 if (NULL == pAdapter)
8575 {
8576 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
8577 "%s: HDD adapter is Null", __func__);
8578 return -ENODEV;
8579 }
8580
8581 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05308582 ret = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308583
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05308584 if (0 != ret)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308585 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05308586 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8587 "%s: HDD context is not valid", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308588 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308589 }
8590
8591 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
8592 if (NULL == hHal)
8593 {
8594 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8595 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05308596 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308597 }
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +05308598
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +05308599 if (eHAL_STATUS_SUCCESS != wlan_hdd_is_pno_allowed(pAdapter))
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +05308600 {
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +05308601 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +05308602 FL("Cannot handle sched_scan"));
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +05308603 return -EBUSY;
8604 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308605
c_hpothu37f21312014-04-09 21:49:54 +05308606 if (TRUE == pHddCtx->isPnoEnable)
8607 {
8608 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
8609 FL("already PNO is enabled"));
8610 return -EBUSY;
8611 }
8612 pHddCtx->isPnoEnable = TRUE;
8613
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308614 pPnoRequest = (tpSirPNOScanReq) vos_mem_malloc(sizeof (tSirPNOScanReq));
8615 if (NULL == pPnoRequest)
8616 {
8617 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
8618 "%s: vos_mem_malloc failed", __func__);
c_hpothu37f21312014-04-09 21:49:54 +05308619 pHddCtx->isPnoEnable = FALSE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308620 return -ENOMEM;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308621 }
8622
Madan Mohan Koyyalamudic3f04352013-09-26 19:21:48 +05308623 memset(pPnoRequest, 0, sizeof (tSirPNOScanReq));
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308624 pPnoRequest->enable = 1; /*Enable PNO */
8625 pPnoRequest->ucNetworksCount = request->n_match_sets;
8626
8627 if (( !pPnoRequest->ucNetworksCount ) ||
8628 ( pPnoRequest->ucNetworksCount > SIR_PNO_MAX_SUPP_NETWORKS ))
8629 {
8630 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik1e406c32014-05-09 15:57:52 +05308631 "%s: Network input is not correct %d Max Network supported is %d",
8632 __func__, pPnoRequest->ucNetworksCount,
8633 SIR_PNO_MAX_SUPP_NETWORKS);
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308634 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308635 goto error;
8636 }
8637
8638 if ( SIR_PNO_MAX_NETW_CHANNELS_EX < request->n_channels )
8639 {
8640 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +05308641 "%s: Incorrect number of channels %d",
8642 __func__, request->n_channels);
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308643 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308644 goto error;
8645 }
8646
8647 /* Framework provides one set of channels(all)
8648 * common for all saved profile */
8649 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
8650 channels_allowed, &num_channels_allowed))
8651 {
8652 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8653 "%s: failed to get valid channel list", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308654 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308655 goto error;
8656 }
8657 /* Checking each channel against allowed channel list */
8658 num_ch = 0;
Nirav Shah80830bf2013-12-31 16:35:12 +05308659 if (request->n_channels)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308660 {
Nirav Shah80830bf2013-12-31 16:35:12 +05308661 char chList [(request->n_channels*5)+1];
8662 int len;
8663 for (i = 0, len = 0; i < request->n_channels; i++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308664 {
Nirav Shah80830bf2013-12-31 16:35:12 +05308665 for (indx = 0; indx < num_channels_allowed; indx++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308666 {
Nirav Shah80830bf2013-12-31 16:35:12 +05308667 if (request->channels[i]->hw_value == channels_allowed[indx])
8668 {
8669 valid_ch[num_ch++] = request->channels[i]->hw_value;
8670 len += snprintf(chList+len, 5, "%d ",
8671 request->channels[i]->hw_value);
8672 break ;
8673 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308674 }
8675 }
Nirav Shah80830bf2013-12-31 16:35:12 +05308676 hddLog(VOS_TRACE_LEVEL_INFO,"Channel-List: %s ", chList);
8677 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308678
8679 /* Filling per profile params */
8680 for (i = 0; i < pPnoRequest->ucNetworksCount; i++)
8681 {
8682 pPnoRequest->aNetworks[i].ssId.length =
8683 request->match_sets[i].ssid.ssid_len;
8684
8685 if (( 0 == pPnoRequest->aNetworks[i].ssId.length ) ||
8686 ( pPnoRequest->aNetworks[i].ssId.length > 32 ) )
8687 {
8688 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +05308689 "%s: SSID Len %d is not correct for network %d",
8690 __func__, pPnoRequest->aNetworks[i].ssId.length, i);
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308691 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308692 goto error;
8693 }
8694
8695 memcpy(pPnoRequest->aNetworks[i].ssId.ssId,
8696 request->match_sets[i].ssid.ssid,
8697 request->match_sets[i].ssid.ssid_len);
Sushant Kaushik1e406c32014-05-09 15:57:52 +05308698 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8699 "%s: SSID of network %d is %s ", __func__,
8700 i, pPnoRequest->aNetworks[i].ssId.ssId);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308701 pPnoRequest->aNetworks[i].authentication = 0; /*eAUTH_TYPE_ANY*/
8702 pPnoRequest->aNetworks[i].encryption = 0; /*eED_ANY*/
8703 pPnoRequest->aNetworks[i].bcastNetwType = 0; /*eBCAST_UNKNOWN*/
8704
8705 /*Copying list of valid channel into request */
8706 memcpy(pPnoRequest->aNetworks[i].aChannels, valid_ch, num_ch);
8707 pPnoRequest->aNetworks[i].ucChannelCount = num_ch;
8708
8709 pPnoRequest->aNetworks[i].rssiThreshold = 0; //Default value
8710 }
8711
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +05308712 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnson59a121e2013-11-30 09:46:08 -08008713 "request->ie_len = %zu", request->ie_len);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +05308714 if ((0 < request->ie_len) && (NULL != request->ie))
8715 {
8716 pPnoRequest->us24GProbeTemplateLen = request->ie_len;
8717 memcpy(&pPnoRequest->p24GProbeTemplate, request->ie,
8718 pPnoRequest->us24GProbeTemplateLen);
8719
8720 pPnoRequest->us5GProbeTemplateLen = request->ie_len;
8721 memcpy(&pPnoRequest->p5GProbeTemplate, request->ie,
8722 pPnoRequest->us5GProbeTemplateLen);
8723 }
8724
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +05308725 /* Driver gets only one time interval which is hardcoded in
8726 * supplicant for 10000ms. Taking power consumption into account 6 timers
8727 * will be used, Timervalue is increased exponentially i.e 10,20,40,
8728 * 80,160,320 secs. And number of scan cycle for each timer
8729 * is configurable through INI param gPNOScanTimerRepeatValue.
8730 * If it is set to 0 only one timer will be used and PNO scan cycle
8731 * will be repeated after each interval specified by supplicant
8732 * till PNO is disabled.
8733 */
8734 if (0 == pHddCtx->cfg_ini->configPNOScanTimerRepeatValue)
8735 pPnoRequest->scanTimers.ucScanTimersCount = HDD_PNO_SCAN_TIMERS_SET_ONE;
8736 else
8737 pPnoRequest->scanTimers.ucScanTimersCount =
8738 HDD_PNO_SCAN_TIMERS_SET_MULTIPLE;
8739
8740 tempInterval = (request->interval)/1000;
8741 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8742 "Base scan interval = %d PNOScanTimerRepeatValue = %d",
8743 tempInterval, pHddCtx->cfg_ini->configPNOScanTimerRepeatValue);
8744 for ( i = 0; i < pPnoRequest->scanTimers.ucScanTimersCount; i++)
8745 {
8746 pPnoRequest->scanTimers.aTimerValues[i].uTimerRepeat =
8747 pHddCtx->cfg_ini->configPNOScanTimerRepeatValue;
8748 pPnoRequest->scanTimers.aTimerValues[i].uTimerValue = tempInterval;
8749 tempInterval *= 2;
8750 }
8751 //Repeat last timer until pno disabled.
8752 pPnoRequest->scanTimers.aTimerValues[i-1].uTimerRepeat = 0;
8753
Madan Mohan Koyyalamudid206c7b2013-09-26 22:54:51 +05308754 pPnoRequest->modePNO = SIR_PNO_MODE_IMMEDIATE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308755
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +05308756 INIT_COMPLETION(pAdapter->pno_comp_var);
8757 pPnoRequest->statusCallback = hdd_cfg80211_sched_scan_start_status_cb;
8758 pPnoRequest->callbackContext = pAdapter;
8759 pAdapter->pno_req_status = 0;
8760
Nirav Shah80830bf2013-12-31 16:35:12 +05308761 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8762 "SessionId %d, enable %d, modePNO %d, ucScanTimersCount %d",
8763 pAdapter->sessionId, pPnoRequest->enable, pPnoRequest->modePNO,
8764 pPnoRequest->scanTimers.ucScanTimersCount);
8765
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308766 status = sme_SetPreferredNetworkList(WLAN_HDD_GET_HAL_CTX(pAdapter),
8767 pPnoRequest, pAdapter->sessionId,
8768 hdd_cfg80211_sched_scan_done_callback, pAdapter);
8769 if (eHAL_STATUS_SUCCESS != status)
8770 {
8771 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +05308772 "%s: Failed to enable PNO", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308773 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308774 goto error;
8775 }
8776
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +05308777 ret = wait_for_completion_timeout(
8778 &pAdapter->pno_comp_var,
8779 msecs_to_jiffies(WLAN_WAIT_TIME_PNO));
8780 if (0 >= ret)
8781 {
8782 // Did not receive the response for PNO enable in time.
8783 // Assuming the PNO enable was success.
8784 // Returning error from here, because we timeout, results
8785 // in side effect of Wifi (Wifi Setting) not to work.
8786 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8787 FL("Timed out waiting for PNO to be Enabled"));
8788 ret = 0;
8789 goto error;
8790 }
8791
8792 ret = pAdapter->pno_req_status;
c_hpothu37f21312014-04-09 21:49:54 +05308793 return ret;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05308794
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308795error:
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +05308796 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8797 FL("PNO scanRequest offloaded ret = %d"), ret);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308798 vos_mem_free(pPnoRequest);
c_hpothu37f21312014-04-09 21:49:54 +05308799 pHddCtx->isPnoEnable = FALSE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308800 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308801}
8802
8803/*
8804 * FUNCTION: wlan_hdd_cfg80211_sched_scan_stop
8805 * NL interface to disable PNO
8806 */
8807static int wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
8808 struct net_device *dev)
8809{
8810 eHalStatus status = eHAL_STATUS_FAILURE;
8811 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
8812 hdd_context_t *pHddCtx;
8813 tHalHandle hHal;
8814 tpSirPNOScanReq pPnoRequest = NULL;
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308815 int ret = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308816
8817 ENTER();
8818
8819 if (NULL == pAdapter)
8820 {
8821 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
8822 "%s: HDD adapter is Null", __func__);
8823 return -ENODEV;
8824 }
8825
8826 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308827
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308828 if (NULL == pHddCtx)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308829 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05308830 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308831 "%s: HDD context is Null", __func__);
8832 return -ENODEV;
8833 }
8834
8835 /* The return 0 is intentional when isLogpInProgress and
8836 * isLoadUnloadInProgress. We did observe a crash due to a return of
8837 * failure in sched_scan_stop , especially for a case where the unload
8838 * of the happens at the same time. The function __cfg80211_stop_sched_scan
8839 * was clearing rdev->sched_scan_req only when the sched_scan_stop returns
8840 * success. If it returns a failure , then its next invocation due to the
8841 * clean up of the second interface will have the dev pointer corresponding
8842 * to the first one leading to a crash.
8843 */
8844 if (pHddCtx->isLogpInProgress)
8845 {
8846 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8847 "%s: LOGP in Progress. Ignore!!!", __func__);
8848 return ret;
8849 }
8850
Mihir Shete18156292014-03-11 15:38:30 +05308851 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308852 {
8853 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8854 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
8855 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308856 }
8857
8858 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
8859 if (NULL == hHal)
8860 {
8861 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8862 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05308863 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308864 }
8865
8866 pPnoRequest = (tpSirPNOScanReq) vos_mem_malloc(sizeof (tSirPNOScanReq));
8867 if (NULL == pPnoRequest)
8868 {
8869 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
8870 "%s: vos_mem_malloc failed", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308871 return -ENOMEM;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308872 }
8873
8874 memset(pPnoRequest, 0, sizeof (tSirPNOScanReq));
8875 pPnoRequest->enable = 0; /* Disable PNO */
8876 pPnoRequest->ucNetworksCount = 0;
8877
8878 status = sme_SetPreferredNetworkList(hHal, pPnoRequest,
8879 pAdapter->sessionId,
8880 NULL, pAdapter);
8881 if (eHAL_STATUS_SUCCESS != status)
8882 {
8883 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8884 "Failed to disabled PNO");
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308885 ret = -EINVAL;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +05308886 goto error;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308887 }
c_hpothu37f21312014-04-09 21:49:54 +05308888 pHddCtx->isPnoEnable = FALSE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308889
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +05308890error:
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05308891 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +05308892 FL("PNO scan disabled ret = %d"), ret);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308893 vos_mem_free(pPnoRequest);
8894
8895 EXIT();
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308896 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308897}
8898
8899#endif /*FEATURE_WLAN_SCAN_PNO*/
8900
8901
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008902#ifdef FEATURE_WLAN_TDLS
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +05308903#if TDLS_MGMT_VERSION2
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008904static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
8905 u8 *peer, u8 action_code, u8 dialog_token,
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +05308906 u16 status_code, u32 peer_capability, const u8 *buf, size_t len)
8907#else
8908static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
8909 u8 *peer, u8 action_code, u8 dialog_token,
8910 u16 status_code, const u8 *buf, size_t len)
8911#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008912{
8913
8914 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
8915 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008916 u8 peerMac[6];
8917 VOS_STATUS status;
Gopichand Nakkala05922802013-03-14 12:23:19 -07008918 int max_sta_failed = 0;
Hoonki Leea34dd892013-02-05 22:56:02 -08008919 int responder;
Hoonki Leed37cbb32013-04-20 00:31:14 -07008920 long rc;
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +05308921#if !(TDLS_MGMT_VERSION2)
8922 u32 peer_capability = 0;
8923#endif
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05308924 tANI_U16 numCurrTdlsPeers;
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008925
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308926 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
8927 TRACE_CODE_HDD_CFG80211_TDLS_MGMT,
8928 pAdapter->sessionId, action_code));
Hoonki Lee11f7dda2013-02-14 16:55:44 -08008929 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008930 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308931 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008932 "Invalid arguments");
8933 return -EINVAL;
8934 }
8935
Sameer Thalappil75ea31a2013-02-21 19:38:16 -08008936 if (pHddCtx->isLogpInProgress)
8937 {
8938 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8939 "%s:LOGP in Progress. Ignore!!!", __func__);
Gopichand Nakkala05922802013-03-14 12:23:19 -07008940 wlan_hdd_tdls_set_link_status(pAdapter, peer, eTDLS_LINK_IDLE);
Sameer Thalappil75ea31a2013-02-21 19:38:16 -08008941 return -EBUSY;
8942 }
8943
Hoonki Lee27511902013-03-14 18:19:06 -07008944 if (eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode)
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008945 {
Hoonki Lee27511902013-03-14 18:19:06 -07008946 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
8947 "%s: TDLS mode is disabled OR not enabled in FW."
8948 MAC_ADDRESS_STR " action %d declined.",
8949 __func__, MAC_ADDR_ARRAY(peer), action_code);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008950 return -ENOTSUPP;
8951 }
Lee Hoonkic1262f22013-01-24 21:59:00 -08008952
Hoonki Lee27511902013-03-14 18:19:06 -07008953 /* other than teardown frame, other mgmt frames are not sent if disabled */
8954 if (SIR_MAC_TDLS_TEARDOWN != action_code)
8955 {
8956 /* if tdls_mode is disabled to respond to peer's request */
8957 if (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode)
8958 {
8959 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
8960 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07008961 " TDLS mode is disabled. action %d declined.",
8962 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee27511902013-03-14 18:19:06 -07008963
8964 return -ENOTSUPP;
8965 }
8966 }
8967
Gopichand Nakkalab977a972013-02-18 19:15:09 -08008968 if (WLAN_IS_TDLS_SETUP_ACTION(action_code))
8969 {
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308970 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, peer, TRUE))
Gopichand Nakkalab977a972013-02-18 19:15:09 -08008971 {
8972 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07008973 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07008974 " TDLS setup is ongoing. action %d declined.",
8975 __func__, MAC_ADDR_ARRAY(peer), action_code);
8976 return -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -08008977 }
8978 }
8979
Hoonki Lee11f7dda2013-02-14 16:55:44 -08008980 if (SIR_MAC_TDLS_SETUP_REQ == action_code ||
8981 SIR_MAC_TDLS_SETUP_RSP == action_code )
Lee Hoonkic1262f22013-01-24 21:59:00 -08008982 {
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05308983 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
8984 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Lee Hoonkic1262f22013-01-24 21:59:00 -08008985 {
8986 /* supplicant still sends tdls_mgmt(SETUP_REQ) even after
8987 we return error code at 'add_station()'. Hence we have this
8988 check again in addtion to add_station().
8989 Anyway, there is no hard to double-check. */
Hoonki Lee11f7dda2013-02-14 16:55:44 -08008990 if (SIR_MAC_TDLS_SETUP_REQ == action_code)
Lee Hoonkic1262f22013-01-24 21:59:00 -08008991 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07008992 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8993 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05308994 " TDLS Max peer already connected. action (%d) declined. Num of peers (%d), Max allowed (%d).",
8995 __func__, MAC_ADDR_ARRAY(peer), action_code,
8996 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Sunil Dutt388ac8f2013-11-28 18:06:52 +05308997 return -EINVAL;
Lee Hoonkic1262f22013-01-24 21:59:00 -08008998 }
8999 else
9000 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -08009001 /* maximum reached. tweak to send error code to peer and return
9002 error code to supplicant */
Lee Hoonkic1262f22013-01-24 21:59:00 -08009003 status_code = eSIR_MAC_UNSPEC_FAILURE_STATUS;
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07009004 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9005 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05309006 " TDLS Max peer already connected, send response status (%d). Num of peers (%d), Max allowed (%d).",
9007 __func__, MAC_ADDR_ARRAY(peer), status_code,
9008 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -07009009 max_sta_failed = -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -08009010 /* fall through to send setup resp with failure status
9011 code */
Lee Hoonkic1262f22013-01-24 21:59:00 -08009012 }
9013 }
Hoonki Lee11f7dda2013-02-14 16:55:44 -08009014 else
9015 {
9016 hddTdlsPeer_t *pTdlsPeer;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05309017 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009018 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Hoonki Lee11f7dda2013-02-14 16:55:44 -08009019 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07009020 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07009021 "%s:" MAC_ADDRESS_STR " already connected. action %d declined.",
9022 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee11f7dda2013-02-14 16:55:44 -08009023 return -EPERM;
9024 }
9025 }
Lee Hoonkic1262f22013-01-24 21:59:00 -08009026 }
Hoonki Lee11f7dda2013-02-14 16:55:44 -08009027 vos_mem_copy(peerMac, peer, 6);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009028
Hoonki Lee1090c6a2013-01-16 17:40:54 -08009029#ifdef WLAN_FEATURE_TDLS_DEBUG
9030 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +05309031 "%s: " MAC_ADDRESS_STR " action %d, dialog_token %d status %d, len = %zu",
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07009032 "tdls_mgmt", MAC_ADDR_ARRAY(peer),
9033 action_code, dialog_token, status_code, len);
Hoonki Lee1090c6a2013-01-16 17:40:54 -08009034#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009035
Hoonki Leea34dd892013-02-05 22:56:02 -08009036 /*Except teardown responder will not be used so just make 0*/
9037 responder = 0;
Hoonki Lee11f7dda2013-02-14 16:55:44 -08009038 if (SIR_MAC_TDLS_TEARDOWN == action_code)
Hoonki Leea34dd892013-02-05 22:56:02 -08009039 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -07009040
9041 hddTdlsPeer_t *pTdlsPeer;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05309042 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peerMac, TRUE);
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -07009043
9044 if(pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
9045 responder = pTdlsPeer->is_responder;
9046 else
Hoonki Leea34dd892013-02-05 22:56:02 -08009047 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -07009048 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +05309049 "%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 -07009050 __func__, MAC_ADDR_ARRAY(peer), (NULL == pTdlsPeer) ? -1 : pTdlsPeer->link_status,
9051 dialog_token, status_code, len);
9052 return -EPERM;
Hoonki Leea34dd892013-02-05 22:56:02 -08009053 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009054 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009055
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +05309056 /* For explicit trigger of DIS_REQ come out of BMPS for
9057 successfully receiving DIS_RSP from peer. */
Hoonki Lee14621352013-04-16 17:51:19 -07009058 if ((SIR_MAC_TDLS_SETUP_RSP == action_code) ||
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +05309059 (SIR_MAC_TDLS_DIS_RSP == action_code) ||
9060 (SIR_MAC_TDLS_DIS_REQ == action_code))
Hoonki Lee14621352013-04-16 17:51:19 -07009061 {
9062 if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter)))
9063 {
9064 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +05309065 "%s: Sending frame action_code %u.Disable BMPS", __func__, action_code);
Hoonki Lee14621352013-04-16 17:51:19 -07009066 hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
9067 }
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +05309068 if (SIR_MAC_TDLS_DIS_REQ != action_code)
9069 wlan_hdd_tdls_set_cap(pAdapter, peerMac, eTDLS_CAP_SUPPORTED);
Hoonki Lee14621352013-04-16 17:51:19 -07009070 }
9071
Hoonki Lee5305c3a2013-04-29 23:28:59 -07009072 /* make sure doesn't call send_mgmt() while it is pending */
9073 if (TDLS_CTX_MAGIC == pAdapter->mgmtTxCompletionStatus)
9074 {
9075 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009076 "%s: " MAC_ADDRESS_STR " action %d couldn't sent, as one is pending. return EBUSY",
Hoonki Lee5305c3a2013-04-29 23:28:59 -07009077 __func__, MAC_ADDR_ARRAY(peer), action_code);
9078 return -EBUSY;
9079 }
9080
9081 pAdapter->mgmtTxCompletionStatus = TDLS_CTX_MAGIC;
Gopichand Nakkalab977a972013-02-18 19:15:09 -08009082 INIT_COMPLETION(pAdapter->tdls_mgmt_comp);
9083
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009084 status = sme_SendTdlsMgmtFrame(WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
Pradeep Reddy POTTETIca171f82014-03-21 14:17:35 +05309085 peerMac, action_code, dialog_token, status_code, peer_capability, (tANI_U8 *)buf, len, responder);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009086
Gopichand Nakkalab977a972013-02-18 19:15:09 -08009087 if (VOS_STATUS_SUCCESS != status)
9088 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009089 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9090 "%s: sme_SendTdlsMgmtFrame failed!", __func__);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07009091 pAdapter->mgmtTxCompletionStatus = FALSE;
Hoonki Lee14621352013-04-16 17:51:19 -07009092 wlan_hdd_tdls_check_bmps(pAdapter);
Sunil Dutt388ac8f2013-11-28 18:06:52 +05309093 return -EINVAL;
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009094 }
9095
Hoonki Leed37cbb32013-04-20 00:31:14 -07009096 rc = wait_for_completion_interruptible_timeout(&pAdapter->tdls_mgmt_comp,
9097 msecs_to_jiffies(WAIT_TIME_TDLS_MGMT));
9098
9099 if ((rc <= 0) || (TRUE != pAdapter->mgmtTxCompletionStatus))
Gopichand Nakkalab977a972013-02-18 19:15:09 -08009100 {
Hoonki Leed37cbb32013-04-20 00:31:14 -07009101 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07009102 "%s: Mgmt Tx Completion failed status %ld TxCompletion %u",
Hoonki Leed37cbb32013-04-20 00:31:14 -07009103 __func__, rc, pAdapter->mgmtTxCompletionStatus);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07009104 pAdapter->mgmtTxCompletionStatus = FALSE;
Yue Ma4f55ef32014-01-23 16:45:33 -08009105
9106 if (pHddCtx->isLogpInProgress)
9107 {
9108 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9109 "%s: LOGP in Progress. Ignore!!!", __func__);
9110 return -EAGAIN;
9111 }
9112
Hoonki Leed37cbb32013-04-20 00:31:14 -07009113 wlan_hdd_tdls_check_bmps(pAdapter);
Sunil Dutt388ac8f2013-11-28 18:06:52 +05309114 return -EINVAL;
Gopichand Nakkalab977a972013-02-18 19:15:09 -08009115 }
9116
Gopichand Nakkala05922802013-03-14 12:23:19 -07009117 if (max_sta_failed)
Hoonki Lee14621352013-04-16 17:51:19 -07009118 {
9119 wlan_hdd_tdls_check_bmps(pAdapter);
Gopichand Nakkala05922802013-03-14 12:23:19 -07009120 return max_sta_failed;
Hoonki Lee14621352013-04-16 17:51:19 -07009121 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -08009122
Hoonki Leea34dd892013-02-05 22:56:02 -08009123 if (SIR_MAC_TDLS_SETUP_RSP == action_code)
9124 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -08009125 wlan_hdd_tdls_set_responder(pAdapter, peerMac, TRUE);
Hoonki Leea34dd892013-02-05 22:56:02 -08009126 }
9127 else if (SIR_MAC_TDLS_SETUP_CNF == action_code)
9128 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -08009129 wlan_hdd_tdls_set_responder(pAdapter, peerMac, FALSE);
Hoonki Leea34dd892013-02-05 22:56:02 -08009130 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009131
9132 return 0;
9133}
9134
9135static int wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
9136 u8 *peer, enum nl80211_tdls_operation oper)
9137{
9138 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
9139 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309140 int status;
Hoonki Lee5305c3a2013-04-29 23:28:59 -07009141 hddTdlsPeer_t *pTdlsPeer;
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009142
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309143 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
9144 TRACE_CODE_HDD_CFG80211_TDLS_OPER,
9145 pAdapter->sessionId, oper));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309146 if ( NULL == peer )
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009147 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -08009148 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chilam Ngc4244af2013-04-01 15:37:32 -07009149 "%s: Invalid arguments", __func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009150 return -EINVAL;
9151 }
Hoonki Lee1090c6a2013-01-16 17:40:54 -08009152
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309153 status = wlan_hdd_validate_context(pHddCtx);
9154
9155 if (0 != status)
Sameer Thalappil75ea31a2013-02-21 19:38:16 -08009156 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309157 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9158 "%s: HDD context is not valid", __func__);
9159 return status;
Sameer Thalappil75ea31a2013-02-21 19:38:16 -08009160 }
9161
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009162
9163 if( FALSE == pHddCtx->cfg_ini->fEnableTDLSSupport ||
Hoonki Lee1090c6a2013-01-16 17:40:54 -08009164 FALSE == sme_IsFeatureSupportedByFW(TDLS))
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009165 {
Hoonki Lee1090c6a2013-01-16 17:40:54 -08009166 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chilam Ngc4244af2013-04-01 15:37:32 -07009167 "TDLS Disabled in INI OR not enabled in FW. "
9168 "Cannot process TDLS commands");
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009169 return -ENOTSUPP;
9170 }
9171
9172 switch (oper) {
9173 case NL80211_TDLS_ENABLE_LINK:
9174 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009175 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309176 long ret;
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05309177 tCsrTdlsLinkEstablishParams tdlsLinkEstablishParams;
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009178
Sunil Dutt41de4e22013-11-14 18:09:02 +05309179 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
9180
9181 if ( NULL == pTdlsPeer ) {
9182 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
9183 " (oper %d) not exsting. ignored",
9184 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
9185 return -EINVAL;
9186 }
9187
9188 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9189 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
9190 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
9191 "NL80211_TDLS_ENABLE_LINK");
9192
Gopichand Nakkala2f4a2822013-04-17 11:22:01 -07009193 if (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
9194 {
9195 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Staion Index %u "
9196 MAC_ADDRESS_STR " failed",
9197 __func__, pTdlsPeer->staId, MAC_ADDR_ARRAY(peer));
9198 return -EINVAL;
9199 }
9200
Hoonki Lee5305c3a2013-04-29 23:28:59 -07009201 if (eTDLS_LINK_CONNECTED != pTdlsPeer->link_status)
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07009202 {
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +05309203 if (IS_ADVANCE_TDLS_ENABLE) {
Gopichand Nakkala24be5312013-07-02 16:47:12 +05309204
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +05309205 if (0 != wlan_hdd_tdls_get_link_establish_params(
9206 pAdapter, peer,&tdlsLinkEstablishParams)) {
9207 return -EINVAL;
9208 }
9209 INIT_COMPLETION(pAdapter->tdls_link_establish_req_comp);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05309210
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +05309211 sme_SendTdlsLinkEstablishParams(WLAN_HDD_GET_HAL_CTX(pAdapter),
9212 pAdapter->sessionId, peer, &tdlsLinkEstablishParams);
9213 /* Send TDLS peer UAPSD capabilities to the firmware and
9214 * register with the TL on after the response for this operation
9215 * is received .
9216 */
9217 ret = wait_for_completion_interruptible_timeout(
9218 &pAdapter->tdls_link_establish_req_comp,
9219 msecs_to_jiffies(WAIT_TIME_TDLS_LINK_ESTABLISH_REQ));
9220 if (ret <= 0)
9221 {
9222 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9223 "%s: Link Establish Request Faled Status %ld",
9224 __func__, ret);
9225 return -EINVAL;
9226 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05309227 }
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -07009228 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer, eTDLS_LINK_CONNECTED);
Gopichand Nakkala471708b2013-06-04 20:03:01 +05309229 /* Mark TDLS client Authenticated .*/
9230 status = WLANTL_ChangeSTAState( pHddCtx->pvosContext,
9231 pTdlsPeer->staId,
9232 WLANTL_STA_AUTHENTICATED);
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -07009233 if (VOS_STATUS_SUCCESS == status)
9234 {
Hoonki Lee14621352013-04-16 17:51:19 -07009235 if (pTdlsPeer->is_responder == 0)
9236 {
9237 v_U8_t staId = (v_U8_t)pTdlsPeer->staId;
9238
9239 wlan_hdd_tdls_timer_restart(pAdapter,
9240 &pTdlsPeer->initiatorWaitTimeoutTimer,
9241 WAIT_TIME_TDLS_INITIATOR);
9242 /* suspend initiator TX until it receives direct packet from the
9243 reponder or WAIT_TIME_TDLS_INITIATOR timer expires */
9244 WLANTL_SuspendDataTx( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
9245 &staId, NULL);
9246 }
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -07009247 wlan_hdd_tdls_increment_peer_count(pAdapter);
9248 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07009249 wlan_hdd_tdls_check_bmps(pAdapter);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05309250
9251 /* Update TL about the UAPSD masks , to route the packets to firmware */
Gopichand Nakkala574f6d12013-06-27 19:38:43 +05309252 if ((TRUE == pHddCtx->cfg_ini->fEnableTDLSBufferSta)
9253 || pHddCtx->cfg_ini->fTDLSUapsdMask )
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05309254 {
Gopichand Nakkala574f6d12013-06-27 19:38:43 +05309255 int ac;
9256 uint8 ucAc[4] = { WLANTL_AC_VO,
9257 WLANTL_AC_VI,
9258 WLANTL_AC_BK,
9259 WLANTL_AC_BE };
9260 uint8 tlTid[4] = { 7, 5, 2, 3 } ;
9261 for(ac=0; ac < 4; ac++)
9262 {
9263 status = WLANTL_EnableUAPSDForAC( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
9264 pTdlsPeer->staId, ucAc[ac],
9265 tlTid[ac], tlTid[ac], 0, 0,
9266 WLANTL_BI_DIR );
9267 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05309268 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07009269 }
9270
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009271 }
9272 break;
9273 case NL80211_TDLS_DISABLE_LINK:
Lee Hoonkic1262f22013-01-24 21:59:00 -08009274 {
Sunil Dutt41de4e22013-11-14 18:09:02 +05309275 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
9276
9277 if ( NULL == pTdlsPeer ) {
9278 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
9279 " (oper %d) not exsting. ignored",
9280 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
9281 return -EINVAL;
9282 }
9283
9284 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9285 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
9286 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
9287 "NL80211_TDLS_DISABLE_LINK");
9288
Hoonki Lee5305c3a2013-04-29 23:28:59 -07009289 if(TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
Lee Hoonkic1262f22013-01-24 21:59:00 -08009290 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009291 long status;
9292
9293 INIT_COMPLETION(pAdapter->tdls_del_station_comp);
9294
Lee Hoonkic1262f22013-01-24 21:59:00 -08009295 sme_DeleteTdlsPeerSta( WLAN_HDD_GET_HAL_CTX(pAdapter),
9296 pAdapter->sessionId, peer );
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009297
9298 status = wait_for_completion_interruptible_timeout(&pAdapter->tdls_del_station_comp,
9299 msecs_to_jiffies(WAIT_TIME_TDLS_DEL_STA));
9300 if (status <= 0)
9301 {
Hoonki Lee5305c3a2013-04-29 23:28:59 -07009302 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer, eTDLS_LINK_IDLE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009303 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9304 "%s: Del station failed status %ld",
9305 __func__, status);
9306 return -EPERM;
9307 }
Hoonki Lee5305c3a2013-04-29 23:28:59 -07009308 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer, eTDLS_LINK_IDLE);
Lee Hoonkic1262f22013-01-24 21:59:00 -08009309 }
9310 else
9311 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07009312 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9313 "%s: TDLS Peer Station doesn't exist.", __func__);
Lee Hoonkic1262f22013-01-24 21:59:00 -08009314 }
Lee Hoonkic1262f22013-01-24 21:59:00 -08009315 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07009316 break;
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009317 case NL80211_TDLS_TEARDOWN:
Sunil Dutt41de4e22013-11-14 18:09:02 +05309318 {
9319 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9320 " %s : NL80211_TDLS_TEARDOWN for " MAC_ADDRESS_STR,
9321 __func__, MAC_ADDR_ARRAY(peer));
9322
9323 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
9324 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
9325
9326 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9327 " %s TDLS External control and Implicit Trigger not enabled ",
9328 __func__);
9329 return -ENOTSUPP;
9330 }
9331
Sunil Dutt41de4e22013-11-14 18:09:02 +05309332
9333 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
9334
9335 if ( NULL == pTdlsPeer ) {
9336 hddLog(VOS_TRACE_LEVEL_INFO, "%s: " MAC_ADDRESS_STR
9337 " peer not exsting",
9338 __func__, MAC_ADDR_ARRAY(peer));
Naresh Jayaram937abdf2013-11-26 19:50:25 +05309339 return -EINVAL;
Sunil Dutt41de4e22013-11-14 18:09:02 +05309340 }
9341 else {
9342 wlan_hdd_tdls_indicate_teardown(pAdapter, pTdlsPeer,
9343 eSIR_MAC_TDLS_TEARDOWN_UNSPEC_REASON);
9344 }
Naresh Jayaram937abdf2013-11-26 19:50:25 +05309345
9346 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, FALSE) )
9347 return -EINVAL;
Sunil Dutt41de4e22013-11-14 18:09:02 +05309348 break;
9349 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009350 case NL80211_TDLS_SETUP:
Sunil Dutt41de4e22013-11-14 18:09:02 +05309351 {
Naresh Jayaramdb4514b2013-11-25 18:08:10 +05309352 hddTdlsPeer_t *pTdlsPeer;
Sunil Dutt41de4e22013-11-14 18:09:02 +05309353 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9354 " %s : NL80211_TDLS_SETUP for " MAC_ADDRESS_STR,
9355 __func__, MAC_ADDR_ARRAY(peer));
9356
9357 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
9358 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
9359
9360 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9361 " %s TDLS External control and Implicit Trigger not enabled ",
9362 __func__);
9363 return -ENOTSUPP;
9364 }
9365
Naresh Jayaramdb4514b2013-11-25 18:08:10 +05309366 /* To cater the requirement of establishing the TDLS link
9367 * irrespective of the data traffic , get an entry of TDLS peer.
9368 */
9369 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, peer);
9370 if (pTdlsPeer == NULL) {
9371 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9372 "%s: peer " MAC_ADDRESS_STR " not existing",
9373 __func__, MAC_ADDR_ARRAY(peer));
9374 return -EINVAL;
9375 }
Naresh Jayaram937abdf2013-11-26 19:50:25 +05309376
9377 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, TRUE) ) {
9378
9379 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9380 " %s TDLS Add Force Peer Failed",
9381 __func__);
9382 return -EINVAL;
9383 }
Naresh Jayaramdb4514b2013-11-25 18:08:10 +05309384 break;
Sunil Dutt41de4e22013-11-14 18:09:02 +05309385 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009386 case NL80211_TDLS_DISCOVERY_REQ:
9387 /* We don't support in-driver setup/teardown/discovery */
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309388 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
9389 "%s: We don't support in-driver setup/teardown/discovery "
9390 ,__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009391 return -ENOTSUPP;
9392 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309393 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9394 "%s: unsupported event",__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009395 return -ENOTSUPP;
9396 }
9397 return 0;
9398}
Chilam NG571c65a2013-01-19 12:27:36 +05309399
9400int wlan_hdd_cfg80211_send_tdls_discover_req(struct wiphy *wiphy,
9401 struct net_device *dev, u8 *peer)
9402{
Arif Hussaina7c8e412013-11-20 11:06:42 -08009403 hddLog(VOS_TRACE_LEVEL_INFO,
9404 "tdls send discover req: "MAC_ADDRESS_STR,
9405 MAC_ADDR_ARRAY(peer));
Chilam NG571c65a2013-01-19 12:27:36 +05309406
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +05309407#if TDLS_MGMT_VERSION2
9408 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
9409 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
9410#else
Chilam NG571c65a2013-01-19 12:27:36 +05309411 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
9412 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, NULL, 0);
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +05309413#endif
Chilam NG571c65a2013-01-19 12:27:36 +05309414}
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009415#endif
9416
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309417#ifdef WLAN_FEATURE_GTK_OFFLOAD
9418/*
9419 * FUNCTION: wlan_hdd_cfg80211_update_replayCounterCallback
9420 * Callback rountine called upon receiving response for
9421 * get offload info
9422 */
9423void wlan_hdd_cfg80211_update_replayCounterCallback(void *callbackContext,
9424 tpSirGtkOffloadGetInfoRspParams pGtkOffloadGetInfoRsp)
9425{
9426
9427 hdd_adapter_t *pAdapter = (hdd_adapter_t *)callbackContext;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05309428 tANI_U8 tempReplayCounter[8];
9429 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309430
9431 ENTER();
9432
9433 if (NULL == pAdapter)
9434 {
Agarwal Ashish971c2882013-10-30 20:11:12 +05309435 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309436 "%s: HDD adapter is Null", __func__);
9437 return ;
9438 }
9439
9440 if (NULL == pGtkOffloadGetInfoRsp)
9441 {
9442 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9443 "%s: pGtkOffloadGetInfoRsp is Null", __func__);
9444 return ;
9445 }
9446
9447 if (VOS_STATUS_SUCCESS != pGtkOffloadGetInfoRsp->ulStatus)
9448 {
9449 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9450 "%s: wlan Failed to get replay counter value",
9451 __func__);
9452 return ;
9453 }
9454
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05309455 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9456 /* Update replay counter */
9457 pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter =
9458 pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
9459
9460 {
9461 /* changing from little to big endian since supplicant
9462 * works on big endian format
9463 */
9464 int i;
9465 tANI_U8 *p = (tANI_U8 *)&pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
9466
9467 for (i = 0; i < 8; i++)
9468 {
9469 tempReplayCounter[7-i] = (tANI_U8)p[i];
9470 }
9471 }
9472
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309473 /* Update replay counter to NL */
9474 cfg80211_gtk_rekey_notify(pAdapter->dev, pGtkOffloadGetInfoRsp->bssId,
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05309475 tempReplayCounter, GFP_KERNEL);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309476}
9477
9478/*
9479 * FUNCTION: wlan_hdd_cfg80211_set_rekey_data
9480 * This function is used to offload GTK rekeying job to the firmware.
9481 */
9482int wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
9483 struct cfg80211_gtk_rekey_data *data)
9484{
9485 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
9486 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
9487 hdd_station_ctx_t *pHddStaCtx;
9488 tHalHandle hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309489 int result;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05309490 tSirGtkOffloadParams hddGtkOffloadReqParams;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309491 eHalStatus status = eHAL_STATUS_FAILURE;
9492
9493 ENTER();
9494
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309495
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309496 if (NULL == pAdapter)
9497 {
9498 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
9499 "%s: HDD adapter is Null", __func__);
9500 return -ENODEV;
9501 }
9502
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309503 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
9504 TRACE_CODE_HDD_CFG80211_SET_REKEY_DATA,
9505 pAdapter->sessionId, pAdapter->device_mode));
9506
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309507 result = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309508
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309509 if (0 != result)
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309510 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309511 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9512 "%s: HDD context is not valid", __func__);
9513 return result;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309514 }
9515
9516 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9517 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
9518 if (NULL == hHal)
9519 {
9520 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9521 "%s: HAL context is Null!!!", __func__);
9522 return -EAGAIN;
9523 }
9524
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05309525 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_ENABLE;
9526 memcpy(pHddStaCtx->gtkOffloadReqParams.aKCK, data->kck, NL80211_KCK_LEN);
9527 memcpy(pHddStaCtx->gtkOffloadReqParams.aKEK, data->kek, NL80211_KEK_LEN);
9528 memcpy(pHddStaCtx->gtkOffloadReqParams.bssId, &pHddStaCtx->conn_info.bssId,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309529 WNI_CFG_BSSID_LEN);
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05309530 {
9531 /* changing from big to little endian since driver
9532 * works on little endian format
9533 */
9534 tANI_U8 *p =
9535 (tANI_U8 *)&pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter;
9536 int i;
9537
9538 for (i = 0; i < 8; i++)
9539 {
9540 p[7-i] = data->replay_ctr[i];
9541 }
9542 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309543
9544 if (TRUE == pHddCtx->hdd_wlan_suspended)
9545 {
9546 /* if wlan is suspended, enable GTK offload directly from here */
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05309547 memcpy(&hddGtkOffloadReqParams, &pHddStaCtx->gtkOffloadReqParams,
9548 sizeof (tSirGtkOffloadParams));
9549 status = sme_SetGTKOffload(hHal, &hddGtkOffloadReqParams,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309550 pAdapter->sessionId);
9551
9552 if (eHAL_STATUS_SUCCESS != status)
9553 {
9554 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9555 "%s: sme_SetGTKOffload failed, returned %d",
9556 __func__, status);
9557 return status;
9558 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309559 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9560 "%s: sme_SetGTKOffload successfull", __func__);
9561 }
9562 else
9563 {
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309564 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9565 "%s: wlan not suspended GTKOffload request is stored",
9566 __func__);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309567 }
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05309568
9569 return eHAL_STATUS_SUCCESS;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309570}
9571#endif /*WLAN_FEATURE_GTK_OFFLOAD*/
9572
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05309573/*
9574 * FUNCTION: wlan_hdd_cfg80211_set_mac_acl
9575 * This function is used to set access control policy
9576 */
9577static int wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy,
9578 struct net_device *dev, const struct cfg80211_acl_data *params)
9579{
9580 int i;
9581 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
9582 hdd_hostapd_state_t *pHostapdState;
9583 tsap_Config_t *pConfig;
9584 v_CONTEXT_t pVosContext = NULL;
9585 hdd_context_t *pHddCtx;
9586 int status;
9587
9588 ENTER();
9589
9590 if (NULL == pAdapter)
9591 {
9592 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
9593 "%s: HDD adapter is Null", __func__);
9594 return -ENODEV;
9595 }
9596
9597 if (NULL == params)
9598 {
9599 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
9600 "%s: params is Null", __func__);
9601 return -EINVAL;
9602 }
9603
9604 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9605 status = wlan_hdd_validate_context(pHddCtx);
9606
9607 if (0 != status)
9608 {
9609 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9610 "%s: HDD context is not valid", __func__);
9611 return status;
9612 }
9613
9614 pVosContext = pHddCtx->pvosContext;
9615 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
9616
9617 if (NULL == pHostapdState)
9618 {
9619 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
9620 "%s: pHostapdState is Null", __func__);
9621 return -EINVAL;
9622 }
9623
9624 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"acl policy: = %d"
9625 "no acl entries = %d", params->acl_policy, params->n_acl_entries);
9626
9627 if (WLAN_HDD_SOFTAP == pAdapter->device_mode)
9628 {
9629 pConfig = &pAdapter->sessionCtx.ap.sapConfig;
9630
9631 /* default value */
9632 pConfig->num_accept_mac = 0;
9633 pConfig->num_deny_mac = 0;
9634
9635 /**
9636 * access control policy
9637 * @NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED: Deny stations which are
9638 * listed in hostapd.deny file.
9639 * @NL80211_ACL_POLICY_DENY_UNLESS_LISTED: Allow stations which are
9640 * listed in hostapd.accept file.
9641 */
9642 if (NL80211_ACL_POLICY_DENY_UNLESS_LISTED == params->acl_policy)
9643 {
9644 pConfig->SapMacaddr_acl = eSAP_DENY_UNLESS_ACCEPTED;
9645 }
9646 else if (NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED == params->acl_policy)
9647 {
9648 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
9649 }
9650 else
9651 {
9652 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9653 "%s:Acl Policy : %d is not supported",
9654 __func__, params->acl_policy);
9655 return -ENOTSUPP;
9656 }
9657
9658 if (eSAP_DENY_UNLESS_ACCEPTED == pConfig->SapMacaddr_acl)
9659 {
9660 pConfig->num_accept_mac = params->n_acl_entries;
9661 for (i = 0; i < params->n_acl_entries; i++)
9662 {
9663 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9664 "** Add ACL MAC entry %i in WhiletList :"
9665 MAC_ADDRESS_STR, i,
9666 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
9667
9668 vos_mem_copy(&pConfig->accept_mac[i], params->mac_addrs[i].addr,
9669 sizeof(qcmacaddr));
9670 }
9671 }
9672 else if (eSAP_ACCEPT_UNLESS_DENIED == pConfig->SapMacaddr_acl)
9673 {
9674 pConfig->num_deny_mac = params->n_acl_entries;
9675 for (i = 0; i < params->n_acl_entries; i++)
9676 {
9677 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9678 "** Add ACL MAC entry %i in BlackList :"
9679 MAC_ADDRESS_STR, i,
9680 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
9681
9682 vos_mem_copy(&pConfig->deny_mac[i], params->mac_addrs[i].addr,
9683 sizeof(qcmacaddr));
9684 }
9685 }
9686
9687 if (VOS_STATUS_SUCCESS != WLANSAP_SetMacACL(pVosContext, pConfig))
9688 {
9689 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9690 "%s: SAP Set Mac Acl fail", __func__);
9691 return -EINVAL;
9692 }
9693 }
9694 else
9695 {
9696 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309697 "%s: Invalid device_mode = %s (%d)",
9698 __func__, hdd_device_modetoString(pAdapter->device_mode),
9699 pAdapter->device_mode);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05309700 return -EINVAL;
9701 }
9702
9703 return 0;
9704}
9705
Leo Chang9056f462013-08-01 19:21:11 -07009706#ifdef WLAN_NL80211_TESTMODE
9707#ifdef FEATURE_WLAN_LPHB
Leo Changd9df8aa2013-09-26 13:32:26 -07009708void wlan_hdd_cfg80211_lphb_ind_handler
Leo Chang9056f462013-08-01 19:21:11 -07009709(
9710 void *pAdapter,
9711 void *indCont
9712)
9713{
Leo Changd9df8aa2013-09-26 13:32:26 -07009714 tSirLPHBInd *lphbInd;
9715 struct sk_buff *skb;
c_hpothu73f35e62014-04-18 13:40:08 +05309716 hdd_context_t *pHddCtxt;
Leo Chang9056f462013-08-01 19:21:11 -07009717
9718 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -07009719 "LPHB indication arrived");
Leo Chang9056f462013-08-01 19:21:11 -07009720
c_hpothu73f35e62014-04-18 13:40:08 +05309721 if (pAdapter == NULL)
9722 {
9723 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9724 "%s: pAdapter is NULL\n",__func__);
9725 return;
9726 }
9727
Leo Chang9056f462013-08-01 19:21:11 -07009728 if (NULL == indCont)
9729 {
9730 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -07009731 "LPHB IND, invalid argument");
Leo Chang9056f462013-08-01 19:21:11 -07009732 return;
9733 }
9734
c_hpothu73f35e62014-04-18 13:40:08 +05309735 pHddCtxt = (hdd_context_t *)pAdapter;
Leo Changd9df8aa2013-09-26 13:32:26 -07009736 lphbInd = (tSirLPHBInd *)indCont;
Leo Chang9056f462013-08-01 19:21:11 -07009737 skb = cfg80211_testmode_alloc_event_skb(
c_hpothu73f35e62014-04-18 13:40:08 +05309738 pHddCtxt->wiphy,
Leo Changd9df8aa2013-09-26 13:32:26 -07009739 sizeof(tSirLPHBInd),
Leo Chang9056f462013-08-01 19:21:11 -07009740 GFP_ATOMIC);
9741 if (!skb)
9742 {
9743 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9744 "LPHB timeout, NL buffer alloc fail");
9745 return;
9746 }
9747
Leo Changac3ba772013-10-07 09:47:04 -07009748 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_CMD, WLAN_HDD_TM_CMD_WLAN_HB))
Leo Changd9df8aa2013-09-26 13:32:26 -07009749 {
9750 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9751 "WLAN_HDD_TM_ATTR_CMD put fail");
9752 goto nla_put_failure;
9753 }
Leo Changac3ba772013-10-07 09:47:04 -07009754 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_TYPE, lphbInd->protocolType))
Leo Changd9df8aa2013-09-26 13:32:26 -07009755 {
9756 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9757 "WLAN_HDD_TM_ATTR_TYPE put fail");
9758 goto nla_put_failure;
9759 }
Leo Changac3ba772013-10-07 09:47:04 -07009760 if(nla_put(skb, WLAN_HDD_TM_ATTR_DATA,
Leo Changd9df8aa2013-09-26 13:32:26 -07009761 sizeof(tSirLPHBInd), lphbInd))
9762 {
9763 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9764 "WLAN_HDD_TM_ATTR_DATA put fail");
9765 goto nla_put_failure;
9766 }
Leo Chang9056f462013-08-01 19:21:11 -07009767 cfg80211_testmode_event(skb, GFP_ATOMIC);
9768 return;
9769
9770nla_put_failure:
9771 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9772 "NLA Put fail");
9773 kfree_skb(skb);
9774
9775 return;
9776}
9777#endif /* FEATURE_WLAN_LPHB */
9778
9779static int wlan_hdd_cfg80211_testmode(struct wiphy *wiphy, void *data, int len)
9780{
9781 struct nlattr *tb[WLAN_HDD_TM_ATTR_MAX + 1];
9782 int err = 0;
9783#ifdef FEATURE_WLAN_LPHB
9784 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Leo Changd9df8aa2013-09-26 13:32:26 -07009785 eHalStatus smeStatus;
Leo Chang9056f462013-08-01 19:21:11 -07009786#endif /* FEATURE_WLAN_LPHB */
9787
9788 err = nla_parse(tb, WLAN_HDD_TM_ATTR_MAX, data, len, wlan_hdd_tm_policy);
9789 if (err)
9790 {
9791 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9792 "%s Testmode INV ATTR", __func__);
9793 return err;
9794 }
9795
9796 if (!tb[WLAN_HDD_TM_ATTR_CMD])
9797 {
9798 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9799 "%s Testmode INV CMD", __func__);
9800 return -EINVAL;
9801 }
9802
9803 switch (nla_get_u32(tb[WLAN_HDD_TM_ATTR_CMD]))
9804 {
9805#ifdef FEATURE_WLAN_LPHB
9806 /* Low Power Heartbeat configuration request */
9807 case WLAN_HDD_TM_CMD_WLAN_HB:
9808 {
9809 int buf_len;
9810 void *buf;
9811 tSirLPHBReq *hb_params = NULL;
Amar Singhal05852702014-02-04 14:40:00 -08009812 tSirLPHBReq *hb_params_temp = NULL;
Leo Chang9056f462013-08-01 19:21:11 -07009813
9814 if (!tb[WLAN_HDD_TM_ATTR_DATA])
9815 {
9816 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9817 "%s Testmode INV DATA", __func__);
9818 return -EINVAL;
9819 }
9820
9821 buf = nla_data(tb[WLAN_HDD_TM_ATTR_DATA]);
9822 buf_len = nla_len(tb[WLAN_HDD_TM_ATTR_DATA]);
Amar Singhal05852702014-02-04 14:40:00 -08009823
9824 hb_params_temp =(tSirLPHBReq *)buf;
9825 if ((hb_params_temp->cmd == LPHB_SET_TCP_PARAMS_INDID) &&
9826 (hb_params_temp->params.lphbTcpParamReq.timePeriodSec == 0))
9827 return -EINVAL;
9828
Leo Chang9056f462013-08-01 19:21:11 -07009829 hb_params = (tSirLPHBReq *)vos_mem_malloc(sizeof(tSirLPHBReq));
9830 if (NULL == hb_params)
9831 {
9832 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9833 "%s Request Buffer Alloc Fail", __func__);
9834 return -EINVAL;
9835 }
9836
9837 vos_mem_copy(hb_params, buf, buf_len);
Leo Changd9df8aa2013-09-26 13:32:26 -07009838 smeStatus = sme_LPHBConfigReq((tHalHandle)(pHddCtx->hHal),
9839 hb_params,
9840 wlan_hdd_cfg80211_lphb_ind_handler);
9841 if (eHAL_STATUS_SUCCESS != smeStatus)
Leo Chang9056f462013-08-01 19:21:11 -07009842 {
Leo Changd9df8aa2013-09-26 13:32:26 -07009843 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9844 "LPHB Config Fail, disable");
Leo Chang9056f462013-08-01 19:21:11 -07009845 vos_mem_free(hb_params);
9846 }
Leo Chang9056f462013-08-01 19:21:11 -07009847 return 0;
9848 }
9849#endif /* FEATURE_WLAN_LPHB */
9850 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309851 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9852 "%s: unsupported event",__func__);
Leo Chang9056f462013-08-01 19:21:11 -07009853 return -EOPNOTSUPP;
9854 }
9855
9856 return err;
9857}
9858#endif /* CONFIG_NL80211_TESTMODE */
9859
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +05309860static int wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
9861 struct net_device *dev,
9862 int idx, struct survey_info *survey)
9863{
9864 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
9865 hdd_context_t *pHddCtx;
Mihir Sheted9072e02013-08-21 17:02:29 +05309866 hdd_station_ctx_t *pHddStaCtx;
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +05309867 tHalHandle halHandle;
Mihir Sheted9072e02013-08-21 17:02:29 +05309868 v_U32_t channel = 0, freq = 0; /* Initialization Required */
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +05309869 v_S7_t snr,rssi;
9870 int status, i, j, filled = 0;
9871
9872 ENTER();
9873
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +05309874 if (NULL == pAdapter)
9875 {
9876 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
9877 "%s: HDD adapter is Null", __func__);
9878 return -ENODEV;
9879 }
9880
9881 if (NULL == wiphy)
9882 {
9883 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
9884 "%s: wiphy is Null", __func__);
9885 return -ENODEV;
9886 }
9887
9888 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9889 status = wlan_hdd_validate_context(pHddCtx);
9890
9891 if (0 != status)
9892 {
9893 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9894 "%s: HDD context is not valid", __func__);
9895 return status;
9896 }
9897
Mihir Sheted9072e02013-08-21 17:02:29 +05309898 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9899
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +05309900 if (0 == pHddCtx->cfg_ini->fEnableSNRMonitoring ||
Mihir Sheted9072e02013-08-21 17:02:29 +05309901 0 != pAdapter->survey_idx ||
9902 eConnectionState_Associated != pHddStaCtx->conn_info.connState)
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +05309903 {
9904 /* The survey dump ops when implemented completely is expected to
9905 * return a survey of all channels and the ops is called by the
9906 * kernel with incremental values of the argument 'idx' till it
9907 * returns -ENONET. But we can only support the survey for the
9908 * operating channel for now. survey_idx is used to track
9909 * that the ops is called only once and then return -ENONET for
9910 * the next iteration
9911 */
9912 pAdapter->survey_idx = 0;
9913 return -ENONET;
9914 }
9915
9916 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
9917
9918 wlan_hdd_get_snr(pAdapter, &snr);
9919 wlan_hdd_get_rssi(pAdapter, &rssi);
9920
9921 sme_GetOperationChannel(halHandle, &channel, pAdapter->sessionId);
9922 hdd_wlan_get_freq(channel, &freq);
9923
9924
9925 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
9926 {
9927 if (NULL == wiphy->bands[i])
9928 {
9929 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
9930 "%s: wiphy->bands[i] is NULL, i = %d", __func__, i);
9931 continue;
9932 }
9933
9934 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
9935 {
9936 struct ieee80211_supported_band *band = wiphy->bands[i];
9937
9938 if (band->channels[j].center_freq == (v_U16_t)freq)
9939 {
9940 survey->channel = &band->channels[j];
9941 /* The Rx BDs contain SNR values in dB for the received frames
9942 * while the supplicant expects noise. So we calculate and
9943 * return the value of noise (dBm)
9944 * SNR (dB) = RSSI (dBm) - NOISE (dBm)
9945 */
9946 survey->noise = rssi - snr;
9947 survey->filled = SURVEY_INFO_NOISE_DBM;
9948 filled = 1;
9949 }
9950 }
9951 }
9952
9953 if (filled)
9954 pAdapter->survey_idx = 1;
9955 else
9956 {
9957 pAdapter->survey_idx = 0;
9958 return -ENONET;
9959 }
9960
9961 return 0;
9962}
9963
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05309964/*
9965 * FUNCTION: wlan_hdd_cfg80211_resume_wlan
9966 * this is called when cfg80211 driver resume
9967 * driver updates latest sched_scan scan result(if any) to cfg80211 database
9968 */
9969int wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
9970{
9971 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
9972 hdd_adapter_t *pAdapter;
9973 hdd_adapter_list_node_t *pAdapterNode, *pNext;
9974 VOS_STATUS status = VOS_STATUS_SUCCESS;
9975
9976 ENTER();
9977
9978 if ( NULL == pHddCtx )
9979 {
9980 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
9981 "%s: HddCtx validation failed", __func__);
9982 return 0;
9983 }
9984
9985 if (pHddCtx->isLogpInProgress)
9986 {
9987 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9988 "%s: LOGP in Progress. Ignore!!!", __func__);
9989 return 0;
9990 }
9991
Mihir Shete18156292014-03-11 15:38:30 +05309992 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05309993 {
9994 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9995 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
9996 return 0;
9997 }
9998
9999 spin_lock(&pHddCtx->schedScan_lock);
10000 pHddCtx->isWiphySuspended = FALSE;
10001 if (TRUE != pHddCtx->isSchedScanUpdatePending)
10002 {
10003 spin_unlock(&pHddCtx->schedScan_lock);
10004 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
10005 "%s: Return resume is not due to PNO indication", __func__);
10006 return 0;
10007 }
10008 // Reset flag to avoid updatating cfg80211 data old results again
10009 pHddCtx->isSchedScanUpdatePending = FALSE;
10010 spin_unlock(&pHddCtx->schedScan_lock);
10011
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053010012
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053010013 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
10014
10015 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
10016 {
10017 pAdapter = pAdapterNode->pAdapter;
10018 if ( (NULL != pAdapter) &&
10019 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) )
10020 {
10021 if (0 != wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter))
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053010022 {
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053010023 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
10024 "%s: NO SCAN result", __func__);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053010025 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053010026 else
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053010027 {
10028 /* Acquire wakelock to handle the case where APP's tries to
10029 * suspend immediately after updating the scan results. Whis
10030 * results in app's is in suspended state and not able to
10031 * process the connect request to AP
10032 */
10033 hdd_prevent_suspend_timeout(2000);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053010034 cfg80211_sched_scan_results(pHddCtx->wiphy);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053010035 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053010036
10037 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
10038 "%s : cfg80211 scan result database updated", __func__);
10039
10040 return 0;
10041
10042 }
10043 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
10044 pAdapterNode = pNext;
10045 }
10046
10047 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
10048 "%s: Failed to find Adapter", __func__);
10049 return 0;
10050}
10051
10052/*
10053 * FUNCTION: wlan_hdd_cfg80211_suspend_wlan
10054 * this is called when cfg80211 driver suspends
10055 */
10056int wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
10057 struct cfg80211_wowlan *wow)
10058{
10059 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
10060
10061 ENTER();
10062 if (NULL == pHddCtx)
10063 {
10064 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
10065 "%s: HddCtx validation failed", __func__);
10066 return 0;
10067 }
10068
10069 pHddCtx->isWiphySuspended = TRUE;
10070
10071 EXIT();
10072
10073 return 0;
10074}
10075
Jeff Johnson295189b2012-06-20 16:38:30 -070010076/* cfg80211_ops */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010077static struct cfg80211_ops wlan_hdd_cfg80211_ops =
Jeff Johnson295189b2012-06-20 16:38:30 -070010078{
10079 .add_virtual_intf = wlan_hdd_add_virtual_intf,
10080 .del_virtual_intf = wlan_hdd_del_virtual_intf,
10081 .change_virtual_intf = wlan_hdd_cfg80211_change_iface,
10082 .change_station = wlan_hdd_change_station,
10083#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
10084 .add_beacon = wlan_hdd_cfg80211_add_beacon,
10085 .del_beacon = wlan_hdd_cfg80211_del_beacon,
10086 .set_beacon = wlan_hdd_cfg80211_set_beacon,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010087#else
10088 .start_ap = wlan_hdd_cfg80211_start_ap,
10089 .change_beacon = wlan_hdd_cfg80211_change_beacon,
10090 .stop_ap = wlan_hdd_cfg80211_stop_ap,
Jeff Johnson295189b2012-06-20 16:38:30 -070010091#endif
10092 .change_bss = wlan_hdd_cfg80211_change_bss,
10093 .add_key = wlan_hdd_cfg80211_add_key,
10094 .get_key = wlan_hdd_cfg80211_get_key,
10095 .del_key = wlan_hdd_cfg80211_del_key,
10096 .set_default_key = wlan_hdd_cfg80211_set_default_key,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080010097#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
Jeff Johnson295189b2012-06-20 16:38:30 -070010098 .set_channel = wlan_hdd_cfg80211_set_channel,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080010099#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010100 .scan = wlan_hdd_cfg80211_scan,
10101 .connect = wlan_hdd_cfg80211_connect,
10102 .disconnect = wlan_hdd_cfg80211_disconnect,
10103 .join_ibss = wlan_hdd_cfg80211_join_ibss,
10104 .leave_ibss = wlan_hdd_cfg80211_leave_ibss,
10105 .set_wiphy_params = wlan_hdd_cfg80211_set_wiphy_params,
10106 .set_tx_power = wlan_hdd_cfg80211_set_txpower,
10107 .get_tx_power = wlan_hdd_cfg80211_get_txpower,
Jeff Johnson295189b2012-06-20 16:38:30 -070010108 .remain_on_channel = wlan_hdd_cfg80211_remain_on_channel,
10109 .cancel_remain_on_channel = wlan_hdd_cfg80211_cancel_remain_on_channel,
DARAM SUDHA39eede62014-02-12 11:16:40 +053010110 .mgmt_tx = wlan_hdd_mgmt_tx,
Jeff Johnson295189b2012-06-20 16:38:30 -070010111#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
10112 .mgmt_tx_cancel_wait = wlan_hdd_cfg80211_mgmt_tx_cancel_wait,
10113 .set_default_mgmt_key = wlan_hdd_set_default_mgmt_key,
10114 .set_txq_params = wlan_hdd_set_txq_params,
10115#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010116 .get_station = wlan_hdd_cfg80211_get_station,
10117 .set_power_mgmt = wlan_hdd_cfg80211_set_power_mgmt,
10118 .del_station = wlan_hdd_cfg80211_del_station,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010119 .add_station = wlan_hdd_cfg80211_add_station,
10120#ifdef FEATURE_WLAN_LFR
10121 .set_pmksa = wlan_hdd_cfg80211_set_pmksa,
10122 .del_pmksa = wlan_hdd_cfg80211_del_pmksa,
10123 .flush_pmksa = wlan_hdd_cfg80211_flush_pmksa,
10124#endif
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070010125#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
10126 .update_ft_ies = wlan_hdd_cfg80211_update_ft_ies,
10127#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080010128#ifdef FEATURE_WLAN_TDLS
10129 .tdls_mgmt = wlan_hdd_cfg80211_tdls_mgmt,
10130 .tdls_oper = wlan_hdd_cfg80211_tdls_oper,
10131#endif
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053010132#ifdef WLAN_FEATURE_GTK_OFFLOAD
10133 .set_rekey_data = wlan_hdd_cfg80211_set_rekey_data,
10134#endif /* WLAN_FEATURE_GTK_OFFLOAD */
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053010135#ifdef FEATURE_WLAN_SCAN_PNO
10136 .sched_scan_start = wlan_hdd_cfg80211_sched_scan_start,
10137 .sched_scan_stop = wlan_hdd_cfg80211_sched_scan_stop,
10138#endif /*FEATURE_WLAN_SCAN_PNO */
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053010139 .resume = wlan_hdd_cfg80211_resume_wlan,
10140 .suspend = wlan_hdd_cfg80211_suspend_wlan,
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053010141 .set_mac_acl = wlan_hdd_cfg80211_set_mac_acl,
Leo Chang9056f462013-08-01 19:21:11 -070010142#ifdef WLAN_NL80211_TESTMODE
10143 .testmode_cmd = wlan_hdd_cfg80211_testmode,
10144#endif
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053010145 .dump_survey = wlan_hdd_cfg80211_dump_survey,
Jeff Johnson295189b2012-06-20 16:38:30 -070010146};
10147