blob: dc167d392c04a4ad7f388ccf0727dd51c14e6d88 [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 Lanctot40142442014-05-20 13:39:25 -07001914 v_BOOL_t MFPCapable = VOS_FALSE;
1915 v_BOOL_t MFPRequired = VOS_FALSE;
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;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05302482 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07002483
2484 ENTER();
2485
2486 if (NULL == pAdapter)
2487 {
2488 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002489 "%s: HDD adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002490 return -ENODEV;
2491 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07002492
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302493 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2494 TRACE_CODE_HDD_CFG80211_STOP_AP,
2495 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302496 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2497 status = wlan_hdd_validate_context(pHddCtx);
2498
2499 if (0 != status)
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07002500 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302501 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2502 "%s: HDD context is not valid", __func__);
2503 return status;
Jeff Johnson4416a782013-03-25 14:17:50 -07002504 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07002505
2506 staAdapter = hdd_get_adapter(pAdapter->pHddCtx, WLAN_HDD_INFRA_STATION);
2507 if (NULL == staAdapter)
2508 {
2509 staAdapter = hdd_get_adapter(pAdapter->pHddCtx, WLAN_HDD_P2P_CLIENT);
2510 if (NULL == staAdapter)
2511 {
Rajesh Chauhan52d885b2013-11-01 10:54:25 -07002512 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
2513 "%s: HDD adapter context for STA/P2P-CLI is Null",
2514 __func__);
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07002515 }
2516 }
2517
2518 pScanInfo = &pHddCtx->scan_info;
2519
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05302520 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
2521 __func__, hdd_device_modetoString(pAdapter->device_mode),
2522 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07002523
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05302524 ret = wlan_hdd_scan_abort(pAdapter);
2525
2526 if (ret <= 0)
Jeff Johnsone7245742012-09-05 17:12:55 -07002527 {
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05302528 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2529 FL("Timeout occurred while waiting for abortscan %ld"), ret);
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302530
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05302531 if (pHddCtx->isLogpInProgress)
Jeff Johnsone7245742012-09-05 17:12:55 -07002532 {
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05302533 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2534 "%s: LOGP in Progress. Ignore!!!", __func__);
Yue Ma4f55ef32014-01-23 16:45:33 -08002535
Jeff Johnsone7245742012-09-05 17:12:55 -07002536 VOS_ASSERT(pScanInfo->mScanPending);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05302537 return -EAGAIN;
Jeff Johnsone7245742012-09-05 17:12:55 -07002538 }
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05302539 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -07002540 }
2541
Arun Kumar Khandavallia3bd8002014-01-17 16:21:19 +05302542 hdd_hostapd_stop(dev);
2543
Jeff Johnson295189b2012-06-20 16:38:30 -07002544 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07002545 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07002546 )
2547 {
2548 beacon_data_t *old;
2549
2550 old = pAdapter->sessionCtx.ap.beacon;
2551
2552 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302553 {
2554 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2555 FL("session(%d) beacon data points to NULL"),
2556 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07002557 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302558 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002559
Jeff Johnson295189b2012-06-20 16:38:30 -07002560 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07002561
2562 mutex_lock(&pHddCtx->sap_lock);
2563 if(test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
2564 {
Jeff Johnson4416a782013-03-25 14:17:50 -07002565 if ( VOS_STATUS_SUCCESS == (status = WLANSAP_StopBss(pHddCtx->pvosContext) ) )
Jeff Johnson295189b2012-06-20 16:38:30 -07002566 {
2567 hdd_hostapd_state_t *pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
2568
2569 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
2570
2571 if (!VOS_IS_STATUS_SUCCESS(status))
2572 {
2573 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08002574 ("ERROR: HDD vos wait for single_event failed!!"));
Jeff Johnson295189b2012-06-20 16:38:30 -07002575 VOS_ASSERT(0);
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302576 }
2577 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002578 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
2579 }
2580 mutex_unlock(&pHddCtx->sap_lock);
2581
2582 if(status != VOS_STATUS_SUCCESS)
2583 {
2584 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08002585 "%s:Error!!! Stopping the BSS",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002586 return -EINVAL;
2587 }
2588
Jeff Johnson4416a782013-03-25 14:17:50 -07002589 if (ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -07002590 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 0,NULL, eANI_BOOLEAN_FALSE)
2591 ==eHAL_STATUS_FAILURE)
2592 {
2593 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08002594 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07002595 }
2596
Jeff Johnson4416a782013-03-25 14:17:50 -07002597 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -07002598 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
2599 eANI_BOOLEAN_FALSE) )
2600 {
2601 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08002602 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07002603 }
2604
2605 // Reset WNI_CFG_PROBE_RSP Flags
2606 wlan_hdd_reset_prob_rspies(pAdapter);
2607
2608 pAdapter->sessionCtx.ap.beacon = NULL;
2609 kfree(old);
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07002610#ifdef WLAN_FEATURE_P2P_DEBUG
2611 if((pAdapter->device_mode == WLAN_HDD_P2P_GO) &&
2612 (globalP2PConnectionStatus == P2P_GO_COMPLETED_STATE))
2613 {
2614 hddLog(LOGE,"[P2P State] From GO completed to Inactive state "
2615 "GO got removed");
2616 globalP2PConnectionStatus = P2P_NOT_ACTIVE;
2617 }
2618#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07002619 }
2620 EXIT();
2621 return status;
2622}
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002623
2624#if (LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
2625
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302626static int wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
2627 struct net_device *dev,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002628 struct cfg80211_ap_settings *params)
2629{
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302630 hdd_adapter_t *pAdapter;
2631 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302632 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002633
2634 ENTER();
2635
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302636 if (NULL == dev)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07002637 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302638 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302639 "%s: Device is Null", __func__);
2640 return -ENODEV;
2641 }
2642
2643 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2644 if (NULL == pAdapter)
2645 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302646 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302647 "%s: HDD adapter is Null", __func__);
2648 return -ENODEV;
2649 }
2650
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302651 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2652 TRACE_CODE_HDD_CFG80211_START_AP, pAdapter->sessionId,
2653 params-> beacon_interval));
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302654 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
2655 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302656 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302657 "%s: HDD adapter magic is invalid", __func__);
2658 return -ENODEV;
2659 }
2660
2661 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302662 status = wlan_hdd_validate_context(pHddCtx);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302663
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302664 if (0 != status)
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302665 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302666 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2667 "%s: HDD context is not valid", __func__);
2668 return status;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302669 }
2670
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05302671 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device mode = %s (%d)",
2672 __func__, hdd_device_modetoString(pAdapter->device_mode),
2673 pAdapter->device_mode);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302674
2675 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002676 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002677 )
2678 {
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302679 beacon_data_t *old, *new;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002680
2681 old = pAdapter->sessionCtx.ap.beacon;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302682
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002683 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302684 {
2685 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
2686 FL("already beacon info added to session(%d)"),
2687 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002688 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302689 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002690
2691 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter, &new, &params->beacon, params->dtim_period);
2692
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302693 if (status != 0)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002694 {
2695 hddLog(VOS_TRACE_LEVEL_FATAL,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302696 "%s:Error!!! Allocating the new beacon", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002697 return -EINVAL;
2698 }
2699 pAdapter->sessionCtx.ap.beacon = new;
Viral Modi3a32cc52013-02-08 11:14:52 -08002700#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
Yue Maf49ba872013-08-19 12:04:25 -07002701 wlan_hdd_cfg80211_set_channel(wiphy, dev,
2702#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
2703 params->channel, params->channel_type);
2704#else
2705 params->chandef.chan, cfg80211_get_chandef_type(&(params->chandef)));
2706#endif
Viral Modi3a32cc52013-02-08 11:14:52 -08002707#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002708 status = wlan_hdd_cfg80211_start_bss(pAdapter, &params->beacon, params->ssid,
2709 params->ssid_len, params->hidden_ssid);
2710 }
2711
2712 EXIT();
2713 return status;
2714}
2715
2716
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302717static int wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002718 struct net_device *dev,
2719 struct cfg80211_beacon_data *params)
2720{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302721 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302722 hdd_context_t *pHddCtx;
2723 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002724
2725 ENTER();
2726
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302727 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2728 TRACE_CODE_HDD_CFG80211_CHANGE_BEACON,
2729 pAdapter->sessionId, pAdapter->device_mode));
Arif Hussain6d2a3322013-11-17 19:50:10 -08002730 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002731 __func__, pAdapter->device_mode);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302732
2733 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2734 status = wlan_hdd_validate_context(pHddCtx);
2735
2736 if (0 != status)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07002737 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302738 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2739 "%s: HDD context is not valid", __func__);
2740 return status;
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07002741 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002742
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302743 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002744 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302745 )
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002746 {
2747 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302748
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002749 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302750
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002751 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302752 {
2753 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2754 FL("session(%d) beacon data points to NULL"),
2755 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002756 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302757 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002758
2759 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter, &new, params, 0);
2760
2761 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302762 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08002763 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002764 return -EINVAL;
2765 }
2766
2767 pAdapter->sessionCtx.ap.beacon = new;
2768
2769 status = wlan_hdd_cfg80211_start_bss(pAdapter, params, NULL, 0, 0);
2770 }
2771
2772 EXIT();
2773 return status;
2774}
2775
2776#endif //(LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
2777
Jeff Johnson295189b2012-06-20 16:38:30 -07002778
2779static int wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
2780 struct net_device *dev,
2781 struct bss_parameters *params)
2782{
2783 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2784
2785 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302786
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302787 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2788 TRACE_CODE_HDD_CFG80211_CHANGE_BSS,
2789 pAdapter->sessionId, params->ap_isolate));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05302790 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
2791 __func__, hdd_device_modetoString(pAdapter->device_mode),
2792 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07002793
2794 if((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07002795 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302796 )
Jeff Johnson295189b2012-06-20 16:38:30 -07002797 {
2798 /* ap_isolate == -1 means that in change bss, upper layer doesn't
2799 * want to update this parameter */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302800 if (-1 != params->ap_isolate)
Jeff Johnson295189b2012-06-20 16:38:30 -07002801 {
2802 pAdapter->sessionCtx.ap.apDisableIntraBssFwd = !!params->ap_isolate;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302803 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002804 }
2805
2806 EXIT();
2807 return 0;
2808}
2809
Kiet Lam10841362013-11-01 11:36:50 +05302810/* FUNCTION: wlan_hdd_change_country_code_cd
2811* to wait for contry code completion
2812*/
2813void* wlan_hdd_change_country_code_cb(void *pAdapter)
2814{
2815 hdd_adapter_t *call_back_pAdapter = pAdapter;
2816 complete(&call_back_pAdapter->change_country_code);
2817 return NULL;
2818}
2819
Jeff Johnson295189b2012-06-20 16:38:30 -07002820/*
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +05302821 * FUNCTION: __wlan_hdd_cfg80211_change_iface
Jeff Johnson295189b2012-06-20 16:38:30 -07002822 * This function is used to set the interface type (INFRASTRUCTURE/ADHOC)
2823 */
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +05302824int __wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07002825 struct net_device *ndev,
2826 enum nl80211_iftype type,
2827 u32 *flags,
2828 struct vif_params *params
2829 )
2830{
2831 struct wireless_dev *wdev;
2832 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Rajesh Chauhana0516c62014-01-30 16:11:18 -08002833 hdd_context_t *pHddCtx;
Mohit Khanna0f232092012-09-11 14:46:08 -07002834 hdd_adapter_t *pP2pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07002835 tCsrRoamProfile *pRoamProfile = NULL;
2836 eCsrRoamBssType LastBSSType;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302837 hdd_config_t *pConfig = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07002838 eMib_dot11DesiredBssType connectedBssType;
2839 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302840 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07002841
2842 ENTER();
2843
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302844 if (!pAdapter)
Rajesh Chauhana0516c62014-01-30 16:11:18 -08002845 {
2846 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2847 "%s: Adapter context is null", __func__);
2848 return VOS_STATUS_E_FAILURE;
2849 }
2850
2851 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2852 if (!pHddCtx)
2853 {
2854 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2855 "%s: HDD context is null", __func__);
2856 return VOS_STATUS_E_FAILURE;
2857 }
2858
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302859 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2860 TRACE_CODE_HDD_CFG80211_CHANGE_IFACE,
2861 pAdapter->sessionId, type));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302862 status = wlan_hdd_validate_context(pHddCtx);
2863
2864 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -07002865 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302866 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2867 "%s: HDD context is not valid", __func__);
2868 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -07002869 }
2870
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05302871 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
2872 __func__, hdd_device_modetoString(pAdapter->device_mode),
2873 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07002874
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302875 pConfig = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -07002876 wdev = ndev->ieee80211_ptr;
2877
2878#ifdef WLAN_BTAMP_FEATURE
2879 if((NL80211_IFTYPE_P2P_CLIENT == type)||
2880 (NL80211_IFTYPE_ADHOC == type)||
2881 (NL80211_IFTYPE_AP == type)||
2882 (NL80211_IFTYPE_P2P_GO == type))
2883 {
2884 pHddCtx->isAmpAllowed = VOS_FALSE;
2885 // stop AMP traffic
2886 status = WLANBAP_StopAmp();
2887 if(VOS_STATUS_SUCCESS != status )
2888 {
2889 pHddCtx->isAmpAllowed = VOS_TRUE;
2890 hddLog(VOS_TRACE_LEVEL_FATAL,
2891 "%s: Failed to stop AMP", __func__);
2892 return -EINVAL;
2893 }
2894 }
2895#endif //WLAN_BTAMP_FEATURE
2896 /* Reset the current device mode bit mask*/
2897 wlan_hdd_clear_concurrency_mode(pHddCtx, pAdapter->device_mode);
2898
2899 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -07002900 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnsone7245742012-09-05 17:12:55 -07002901 || (pAdapter->device_mode == WLAN_HDD_P2P_DEVICE)
Jeff Johnson295189b2012-06-20 16:38:30 -07002902 )
2903 {
2904 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -08002905 if (!pWextState)
2906 {
2907 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2908 "%s: pWextState is null", __func__);
2909 return VOS_STATUS_E_FAILURE;
2910 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002911 pRoamProfile = &pWextState->roamProfile;
2912 LastBSSType = pRoamProfile->BSSType;
2913
2914 switch (type)
2915 {
2916 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -07002917 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -07002918 hddLog(VOS_TRACE_LEVEL_INFO,
2919 "%s: setting interface Type to INFRASTRUCTURE", __func__);
2920 pRoamProfile->BSSType = eCSR_BSS_TYPE_INFRASTRUCTURE;
Jeff Johnsone7245742012-09-05 17:12:55 -07002921#ifdef WLAN_FEATURE_11AC
2922 if(pConfig->dot11Mode == eHDD_DOT11_MODE_AUTO)
2923 {
2924 pConfig->dot11Mode = eHDD_DOT11_MODE_11ac;
2925 }
2926#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302927 pRoamProfile->phyMode =
Jeff Johnsone7245742012-09-05 17:12:55 -07002928 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07002929 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08002930 //Check for sub-string p2p to confirm its a p2p interface
2931 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302932 {
Gopichand Nakkala864d3552012-12-31 16:08:51 -08002933 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
2934 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
2935 }
2936 else
2937 {
2938 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -07002939 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -08002940 }
Madan Mohan Koyyalamudi81746922013-07-17 14:38:51 +05302941#ifdef FEATURE_WLAN_TDLS
2942 /* The open adapter for the p2p shall skip initializations in
2943 * tdls_init if the device mode is WLAN_HDD_P2P_DEVICE, for
2944 * TDLS is supported only on WLAN_HDD_P2P_CLIENT. Hence invoke
2945 * tdls_init when the change_iface sets the device mode to
2946 * WLAN_HDD_P2P_CLIENT.
2947 */
2948
2949 if ( pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
2950 {
2951 if (0 != wlan_hdd_tdls_init (pAdapter))
2952 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302953 hddLog(VOS_TRACE_LEVEL_ERROR,
2954 "%s: tdls initialization failed", __func__);
Madan Mohan Koyyalamudi81746922013-07-17 14:38:51 +05302955 return -EINVAL;
2956 }
2957 }
2958#endif
2959
Jeff Johnson295189b2012-06-20 16:38:30 -07002960 break;
2961 case NL80211_IFTYPE_ADHOC:
2962 hddLog(VOS_TRACE_LEVEL_INFO,
2963 "%s: setting interface Type to ADHOC", __func__);
2964 pRoamProfile->BSSType = eCSR_BSS_TYPE_START_IBSS;
2965 pRoamProfile->phyMode =
2966 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Shailender Karmuchia734f332013-04-19 14:02:48 -07002967 pAdapter->device_mode = WLAN_HDD_IBSS;
Jeff Johnson295189b2012-06-20 16:38:30 -07002968 wdev->iftype = type;
2969 break;
2970
2971 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -07002972 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07002973 {
2974 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
2975 "%s: setting interface Type to %s", __func__,
2976 (type == NL80211_IFTYPE_AP) ? "SoftAP" : "P2pGo");
2977
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08002978 //Cancel any remain on channel for GO mode
2979 if (NL80211_IFTYPE_P2P_GO == type)
2980 {
2981 wlan_hdd_cancel_existing_remain_on_channel(pAdapter);
2982 }
Mohit Khanna0f232092012-09-11 14:46:08 -07002983 if (NL80211_IFTYPE_AP == type)
2984 {
2985 /* As Loading WLAN Driver one interface being created for p2p device
2986 * address. This will take one HW STA and the max number of clients
2987 * that can connect to softAP will be reduced by one. so while changing
2988 * the interface type to NL80211_IFTYPE_AP (SoftAP) remove p2p0
2989 * interface as it is not required in SoftAP mode.
2990 */
2991
2992 // Get P2P Adapter
2993 pP2pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_DEVICE);
2994
2995 if (pP2pAdapter)
2996 {
2997 hdd_stop_adapter(pHddCtx, pP2pAdapter);
2998 hdd_deinit_adapter(pHddCtx, pP2pAdapter);
2999 hdd_close_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
3000 }
3001 }
Swaroop Goltia2e32212014-04-09 23:37:33 +05303002 //Disable IMPS & BMPS for SAP/GO
3003 if(VOS_STATUS_E_FAILURE ==
3004 hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_P2P_GO))
3005 {
3006 //Fail to Exit BMPS
3007 VOS_ASSERT(0);
3008 }
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05303009#ifdef FEATURE_WLAN_TDLS
Mohit Khanna0f232092012-09-11 14:46:08 -07003010
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05303011 /* A Mutex Lock is introduced while changing the mode to
3012 * protect the concurrent access for the Adapters by TDLS
3013 * module.
3014 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05303015 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05303016#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07003017 //De-init the adapter.
3018 hdd_stop_adapter( pHddCtx, pAdapter );
3019 hdd_deinit_adapter( pHddCtx, pAdapter );
3020 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
Jeff Johnson295189b2012-06-20 16:38:30 -07003021 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
3022 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05303023#ifdef FEATURE_WLAN_TDLS
3024 mutex_unlock(&pHddCtx->tdls_lock);
3025#endif
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -07003026 if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) &&
3027 (pConfig->apRandomBssidEnabled))
3028 {
3029 /* To meet Android requirements create a randomized
3030 MAC address of the form 02:1A:11:Fx:xx:xx */
3031 get_random_bytes(&ndev->dev_addr[3], 3);
3032 ndev->dev_addr[0] = 0x02;
3033 ndev->dev_addr[1] = 0x1A;
3034 ndev->dev_addr[2] = 0x11;
3035 ndev->dev_addr[3] |= 0xF0;
3036 memcpy(pAdapter->macAddressCurrent.bytes, ndev->dev_addr,
3037 VOS_MAC_ADDR_SIZE);
Arif Hussain24bafea2013-11-15 15:10:03 -08003038 pr_info("wlan: Generated HotSpot BSSID " MAC_ADDRESS_STR"\n",
3039 MAC_ADDR_ARRAY(ndev->dev_addr));
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -07003040 }
3041
Jeff Johnson295189b2012-06-20 16:38:30 -07003042 hdd_set_ap_ops( pAdapter->dev );
3043
Kiet Lam10841362013-11-01 11:36:50 +05303044 /* This is for only SAP mode where users can
3045 * control country through ini.
3046 * P2P GO follows station country code
3047 * acquired during the STA scanning. */
3048 if((NL80211_IFTYPE_AP == type) &&
3049 (memcmp(pConfig->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0))
3050 {
3051 int status = 0;
3052 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_INFO,
3053 "%s: setting country code from INI ", __func__);
3054 init_completion(&pAdapter->change_country_code);
3055 status = (int)sme_ChangeCountryCode(pHddCtx->hHal,
3056 (void *)(tSmeChangeCountryCallback)
3057 wlan_hdd_change_country_code_cb,
3058 pConfig->apCntryCode, pAdapter,
3059 pHddCtx->pvosContext,
Abhishek Singha306a442013-11-07 18:39:01 +05303060 eSIR_FALSE,
3061 eSIR_TRUE);
Kiet Lam10841362013-11-01 11:36:50 +05303062 if (eHAL_STATUS_SUCCESS == status)
3063 {
3064 /* Wait for completion */
c_hpothu6ff1c3c2013-10-01 19:01:57 +05303065 ret = wait_for_completion_interruptible_timeout(
Kiet Lam10841362013-11-01 11:36:50 +05303066 &pAdapter->change_country_code,
3067 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05303068 if (ret <= 0)
Kiet Lam10841362013-11-01 11:36:50 +05303069 {
3070 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05303071 FL("SME Timed out while setting country code %ld"),
3072 ret);
Yue Ma4f55ef32014-01-23 16:45:33 -08003073
3074 if (pHddCtx->isLogpInProgress)
3075 {
3076 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3077 "%s: LOGP in Progress. Ignore!!!", __func__);
3078 return -EAGAIN;
3079 }
Kiet Lam10841362013-11-01 11:36:50 +05303080 }
3081 }
3082 else
3083 {
3084 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08003085 "%s: SME Change Country code failed",__func__);
Kiet Lam10841362013-11-01 11:36:50 +05303086 return -EINVAL;
3087 }
3088 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003089 status = hdd_init_ap_mode(pAdapter);
3090 if(status != VOS_STATUS_SUCCESS)
3091 {
3092 hddLog(VOS_TRACE_LEVEL_FATAL,
3093 "%s: Error initializing the ap mode", __func__);
3094 return -EINVAL;
3095 }
3096 hdd_set_conparam(1);
3097
Jeff Johnson295189b2012-06-20 16:38:30 -07003098 /*interface type changed update in wiphy structure*/
3099 if(wdev)
3100 {
3101 wdev->iftype = type;
3102 pHddCtx->change_iface = type;
3103 }
3104 else
3105 {
3106 hddLog(VOS_TRACE_LEVEL_ERROR,
3107 "%s: ERROR !!!! Wireless dev is NULL", __func__);
3108 return -EINVAL;
3109 }
3110 goto done;
3111 }
3112
3113 default:
3114 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
3115 __func__);
3116 return -EOPNOTSUPP;
3117 }
3118 }
3119 else if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07003120 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07003121 )
3122 {
3123 switch(type)
3124 {
3125 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -07003126 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -07003127 case NL80211_IFTYPE_ADHOC:
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05303128#ifdef FEATURE_WLAN_TDLS
3129
3130 /* A Mutex Lock is introduced while changing the mode to
3131 * protect the concurrent access for the Adapters by TDLS
3132 * module.
3133 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05303134 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05303135#endif
Jeff Johnson32d95a32012-09-10 13:15:23 -07003136 hdd_stop_adapter( pHddCtx, pAdapter );
3137 hdd_deinit_adapter( pHddCtx, pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07003138 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08003139 //Check for sub-string p2p to confirm its a p2p interface
3140 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala864d3552012-12-31 16:08:51 -08003141 {
3142 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
3143 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
3144 }
3145 else
3146 {
3147 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -07003148 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -08003149 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003150 hdd_set_conparam(0);
3151 pHddCtx->change_iface = type;
Jeff Johnson295189b2012-06-20 16:38:30 -07003152 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
3153 hdd_set_station_ops( pAdapter->dev );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05303154#ifdef FEATURE_WLAN_TDLS
3155 mutex_unlock(&pHddCtx->tdls_lock);
3156#endif
Sunil Dutt66485cb2013-12-19 19:05:03 +05303157 status = hdd_init_station_mode( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07003158 if( VOS_STATUS_SUCCESS != status )
3159 return -EOPNOTSUPP;
Jeff Johnsone7245742012-09-05 17:12:55 -07003160 /* In case of JB, for P2P-GO, only change interface will be called,
3161 * This is the right place to enable back bmps_imps()
3162 */
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05303163 if (pHddCtx->hdd_wlan_suspended)
3164 {
3165 hdd_set_pwrparams(pHddCtx);
3166 }
Jeff Johnsone7245742012-09-05 17:12:55 -07003167 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07003168 goto done;
3169 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -07003170 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07003171 wdev->iftype = type;
Jeff Johnson295189b2012-06-20 16:38:30 -07003172 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
3173 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Jeff Johnson295189b2012-06-20 16:38:30 -07003174 goto done;
3175 default:
3176 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
3177 __func__);
3178 return -EOPNOTSUPP;
3179
3180 }
3181
3182 }
3183 else
3184 {
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05303185 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: unsupported device mode(%s (%d))",
3186 __func__, hdd_device_modetoString(pAdapter->device_mode),
3187 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07003188 return -EOPNOTSUPP;
3189 }
3190
3191
3192 if(pRoamProfile)
3193 {
3194 if ( LastBSSType != pRoamProfile->BSSType )
3195 {
3196 /*interface type changed update in wiphy structure*/
3197 wdev->iftype = type;
3198
3199 /*the BSS mode changed, We need to issue disconnect
3200 if connected or in IBSS disconnect state*/
3201 if ( hdd_connGetConnectedBssType(
3202 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), &connectedBssType ) ||
3203 ( eCSR_BSS_TYPE_START_IBSS == LastBSSType ) )
3204 {
3205 /*need to issue a disconnect to CSR.*/
3206 INIT_COMPLETION(pAdapter->disconnect_comp_var);
3207 if( eHAL_STATUS_SUCCESS ==
3208 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
3209 pAdapter->sessionId,
3210 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
3211 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05303212 ret = wait_for_completion_interruptible_timeout(
3213 &pAdapter->disconnect_comp_var,
3214 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
3215 if (ret <= 0)
3216 {
3217 hddLog(VOS_TRACE_LEVEL_ERROR,
3218 FL("wait on disconnect_comp_var failed %ld"), ret);
3219 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003220 }
3221 }
3222 }
3223 }
3224
3225done:
3226 /*set bitmask based on updated value*/
3227 wlan_hdd_set_concurrency_mode(pHddCtx, pAdapter->device_mode);
Leo Chang6fe1f922013-06-07 19:21:24 -07003228
3229 /* Only STA mode support TM now
3230 * all other mode, TM feature should be disabled */
3231 if ( (pHddCtx->cfg_ini->thermalMitigationEnable) &&
3232 (~VOS_STA & pHddCtx->concurrency_mode) )
3233 {
3234 hddDevTmLevelChangedHandler(pHddCtx->parent_dev, 0);
3235 }
3236
Jeff Johnson295189b2012-06-20 16:38:30 -07003237#ifdef WLAN_BTAMP_FEATURE
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303238 if((NL80211_IFTYPE_STATION == type) && (pHddCtx->concurrency_mode <= 1) &&
Jeff Johnson295189b2012-06-20 16:38:30 -07003239 (pHddCtx->no_of_sessions[WLAN_HDD_INFRA_STATION] <=1))
3240 {
3241 //we are ok to do AMP
3242 pHddCtx->isAmpAllowed = VOS_TRUE;
3243 }
3244#endif //WLAN_BTAMP_FEATURE
3245 EXIT();
3246 return 0;
3247}
3248
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +05303249/*
3250 * FUNCTION: wlan_hdd_cfg80211_change_iface
3251 * wrapper function to protect the actual implementation from SSR.
3252 */
3253int wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
3254 struct net_device *ndev,
3255 enum nl80211_iftype type,
3256 u32 *flags,
3257 struct vif_params *params
3258 )
3259{
3260 int ret;
3261
3262 vos_ssr_protect(__func__);
3263 ret = __wlan_hdd_cfg80211_change_iface(wiphy, ndev, type, flags, params);
3264 vos_ssr_unprotect(__func__);
3265
3266 return ret;
3267}
3268
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003269#ifdef FEATURE_WLAN_TDLS
3270static int wlan_hdd_tdls_add_station(struct wiphy *wiphy,
3271 struct net_device *dev, u8 *mac, bool update, tCsrStaParams *StaParams)
3272{
3273 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3274 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3275 VOS_STATUS status;
Hoonki Lee5305c3a2013-04-29 23:28:59 -07003276 hddTdlsPeer_t *pTdlsPeer;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05303277 long ret;
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05303278 tANI_U16 numCurrTdlsPeers;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003279
3280 ENTER();
3281
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05303282 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003283 {
3284 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3285 "Invalid arguments");
3286 return -EINVAL;
3287 }
Hoonki Lee27511902013-03-14 18:19:06 -07003288
3289 if ((eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode) ||
3290 (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode))
3291 {
3292 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
3293 "%s: TDLS mode is disabled OR not enabled in FW."
3294 MAC_ADDRESS_STR " Request declined.",
3295 __func__, MAC_ADDR_ARRAY(mac));
3296 return -ENOTSUPP;
3297 }
3298
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003299 if (pHddCtx->isLogpInProgress)
3300 {
3301 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3302 "%s:LOGP in Progress. Ignore!!!", __func__);
Gopichand Nakkala05922802013-03-14 12:23:19 -07003303 wlan_hdd_tdls_set_link_status(pAdapter, mac, eTDLS_LINK_IDLE);
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003304 return -EBUSY;
3305 }
3306
Naresh Jayaram9c6f4462014-02-13 12:20:31 +05303307 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, mac);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07003308
3309 if ( NULL == pTdlsPeer ) {
3310 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
3311 "%s: " MAC_ADDRESS_STR " (update %d) not exist. return invalid",
3312 __func__, MAC_ADDR_ARRAY(mac), update);
3313 return -EINVAL;
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07003314 }
Hoonki Lee5305c3a2013-04-29 23:28:59 -07003315
3316 /* in add station, we accept existing valid staId if there is */
3317 if ((0 == update) &&
3318 ((pTdlsPeer->link_status >= eTDLS_LINK_CONNECTING) ||
3319 (TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003320 {
Hoonki Lee5305c3a2013-04-29 23:28:59 -07003321 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003322 "%s: " MAC_ADDRESS_STR
Hoonki Lee5305c3a2013-04-29 23:28:59 -07003323 " link_status %d. staId %d. add station ignored.",
3324 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, pTdlsPeer->staId);
3325 return 0;
3326 }
3327 /* in change station, we accept only when staId is valid */
3328 if ((1 == update) &&
3329 ((pTdlsPeer->link_status > eTDLS_LINK_CONNECTING) ||
3330 (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
3331 {
3332 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
3333 "%s: " MAC_ADDRESS_STR
3334 " link status %d. staId %d. change station %s.",
3335 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, pTdlsPeer->staId,
3336 (TDLS_STA_INDEX_VALID(pTdlsPeer->staId)) ? "ignored" : "declined");
3337 return (TDLS_STA_INDEX_VALID(pTdlsPeer->staId)) ? 0 : -EPERM;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003338 }
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07003339
3340 /* when others are on-going, we want to change link_status to idle */
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05303341 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, mac, TRUE))
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003342 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07003343 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3344 "%s: " MAC_ADDRESS_STR
3345 " TDLS setup is ongoing. Request declined.",
3346 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala05922802013-03-14 12:23:19 -07003347 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003348 }
3349
3350 /* first to check if we reached to maximum supported TDLS peer.
3351 TODO: for now, return -EPERM looks working fine,
3352 but need to check if any other errno fit into this category.*/
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05303353 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
3354 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003355 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07003356 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3357 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05303358 " TDLS Max peer already connected. Request declined."
3359 " Num of peers (%d), Max allowed (%d).",
3360 __func__, MAC_ADDR_ARRAY(mac), numCurrTdlsPeers,
3361 HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -07003362 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003363 }
3364 else
3365 {
3366 hddTdlsPeer_t *pTdlsPeer;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05303367 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, mac, TRUE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003368 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003369 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07003370 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3371 "%s: " MAC_ADDRESS_STR " already connected. Request declined.",
3372 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003373 return -EPERM;
3374 }
3375 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003376 if (0 == update)
3377 wlan_hdd_tdls_set_link_status(pAdapter, mac, eTDLS_LINK_CONNECTING);
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003378
Jeff Johnsond75fe012013-04-06 10:53:06 -07003379 /* debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05303380 if (NULL != StaParams)
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003381 {
3382 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
3383 "%s: TDLS Peer Parameters.", __func__);
Hoonki Lee66b75f32013-04-16 18:30:07 -07003384 if(StaParams->htcap_present)
3385 {
3386 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
3387 "ht_capa->cap_info: %0x", StaParams->HTCap.capInfo);
3388 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
3389 "ht_capa->extended_capabilities: %0x",
3390 StaParams->HTCap.extendedHtCapInfo);
3391 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003392 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
3393 "params->capability: %0x",StaParams->capability);
3394 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07003395 "params->ext_capab_len: %0x",StaParams->extn_capability[0]);
Hoonki Lee66b75f32013-04-16 18:30:07 -07003396 if(StaParams->vhtcap_present)
3397 {
3398 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
3399 "rxMcsMap %x rxHighest %x txMcsMap %x txHighest %x",
3400 StaParams->VHTCap.suppMcs.rxMcsMap, StaParams->VHTCap.suppMcs.rxHighest,
3401 StaParams->VHTCap.suppMcs.txMcsMap, StaParams->VHTCap.suppMcs.txHighest);
3402 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003403 {
3404 int i = 0;
Hoonki Lee5305c3a2013-04-29 23:28:59 -07003405 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "Supported rates:");
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003406 for (i = 0; i < sizeof(StaParams->supported_rates); i++)
3407 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
3408 "[%d]: %x ", i, StaParams->supported_rates[i]);
3409 }
Jeff Johnsond75fe012013-04-06 10:53:06 -07003410 } /* end debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05303411 else if ((1 == update) && (NULL == StaParams))
3412 {
3413 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3414 "%s : update is true, but staParams is NULL. Error!", __func__);
3415 return -EPERM;
3416 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003417
3418 INIT_COMPLETION(pAdapter->tdls_add_station_comp);
3419
3420 if (!update)
3421 {
3422 status = sme_AddTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
3423 pAdapter->sessionId, mac);
3424 }
3425 else
3426 {
3427 status = sme_ChangeTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
3428 pAdapter->sessionId, mac, StaParams);
3429 }
3430
c_hpothu6ff1c3c2013-10-01 19:01:57 +05303431 ret = wait_for_completion_interruptible_timeout(&pAdapter->tdls_add_station_comp,
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003432 msecs_to_jiffies(WAIT_TIME_TDLS_ADD_STA));
3433
c_hpothu6ff1c3c2013-10-01 19:01:57 +05303434 if (ret <= 0)
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003435 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07003436 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05303437 "%s: timeout waiting for tdls add station indication %ld",
3438 __func__, ret);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07003439 return -EPERM;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003440 }
c_hpothu6ff1c3c2013-10-01 19:01:57 +05303441
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003442 if ( eHAL_STATUS_SUCCESS != pAdapter->tdlsAddStaStatus)
3443 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07003444 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003445 "%s: Add Station is unsucessful", __func__);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07003446 return -EPERM;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003447 }
3448
3449 return 0;
Gopichand Nakkala05922802013-03-14 12:23:19 -07003450
3451error:
3452 wlan_hdd_tdls_set_link_status(pAdapter, mac, eTDLS_LINK_IDLE);
3453 return -EPERM;
3454
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003455}
3456#endif
3457
Jeff Johnson295189b2012-06-20 16:38:30 -07003458static int wlan_hdd_change_station(struct wiphy *wiphy,
3459 struct net_device *dev,
3460 u8 *mac,
3461 struct station_parameters *params)
3462{
3463 VOS_STATUS status = VOS_STATUS_SUCCESS;
3464 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Gopichand Nakkala29149562013-05-10 21:43:41 +05303465 hdd_context_t *pHddCtx;
3466 hdd_station_ctx_t *pHddStaCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07003467 v_MACADDR_t STAMacAddress;
Gopichand Nakkalab0856222013-03-12 22:39:05 -07003468#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003469 tCsrStaParams StaParams = {0};
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003470 tANI_U8 isBufSta = 0;
Naresh Jayaram3180aa42014-02-12 21:47:26 +05303471 tANI_U8 isOffChannelSupported = 0;
Gopichand Nakkalab0856222013-03-12 22:39:05 -07003472#endif
Jeff Johnsone7245742012-09-05 17:12:55 -07003473 ENTER();
3474
Gopichand Nakkala29149562013-05-10 21:43:41 +05303475 if ((NULL == pAdapter))
3476 {
3477 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
3478 "invalid adapter ");
3479 return -EINVAL;
3480 }
3481
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05303482 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
3483 TRACE_CODE_HDD_CHANGE_STATION,
3484 pAdapter->sessionId, params->listen_interval));
Gopichand Nakkala29149562013-05-10 21:43:41 +05303485 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
3486 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3487
3488 if ((NULL == pHddCtx) || (NULL == pHddStaCtx))
3489 {
3490 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
3491 "invalid HDD state or HDD station context");
3492 return -EINVAL;
3493 }
3494
3495 if (pHddCtx->isLogpInProgress)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07003496 {
3497 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3498 "%s:LOGP in Progress. Ignore!!!", __func__);
3499 return -EAGAIN;
3500 }
3501
Jeff Johnson295189b2012-06-20 16:38:30 -07003502 vos_mem_copy(STAMacAddress.bytes, mac, sizeof(v_MACADDR_t));
3503
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003504 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
3505 || (pAdapter->device_mode == WLAN_HDD_P2P_GO))
Jeff Johnson295189b2012-06-20 16:38:30 -07003506 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003507 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED))
Jeff Johnson295189b2012-06-20 16:38:30 -07003508 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303509 status = hdd_softap_change_STA_state( pAdapter, &STAMacAddress,
Jeff Johnson295189b2012-06-20 16:38:30 -07003510 WLANTL_STA_AUTHENTICATED);
3511
Gopichand Nakkala29149562013-05-10 21:43:41 +05303512 if (status != VOS_STATUS_SUCCESS)
3513 {
3514 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3515 "%s: Not able to change TL state to AUTHENTICATED", __func__);
3516 return -EINVAL;
3517 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003518 }
3519 }
Hoonki Leea6d49be2013-04-05 09:43:25 -07003520 else if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
3521 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)) {
Gopichand Nakkala29149562013-05-10 21:43:41 +05303522#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003523 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
3524 StaParams.capability = params->capability;
3525 StaParams.uapsd_queues = params->uapsd_queues;
3526 StaParams.max_sp = params->max_sp;
3527
Naresh Jayaram3180aa42014-02-12 21:47:26 +05303528 /* Convert (first channel , number of channels) tuple to
3529 * the total list of channels. This goes with the assumption
3530 * that if the first channel is < 14, then the next channels
3531 * are an incremental of 1 else an incremental of 4 till the number
3532 * of channels.
3533 */
3534 if (0 != params->supported_channels_len) {
3535 int i = 0,j = 0,k = 0, no_of_channels = 0 ;
3536 for ( i = 0 ; i < params->supported_channels_len ; i+=2)
3537 {
3538 int wifi_chan_index;
3539 StaParams.supported_channels[j] = params->supported_channels[i];
3540 wifi_chan_index =
3541 ((StaParams.supported_channels[j] <= HDD_CHANNEL_14 ) ? 1 : 4 );
3542 no_of_channels = params->supported_channels[i+1];
3543 for(k=1; k <= no_of_channels; k++)
3544 {
3545 StaParams.supported_channels[j+1] =
3546 StaParams.supported_channels[j] + wifi_chan_index;
3547 j+=1;
3548 }
3549 }
3550 StaParams.supported_channels_len = j;
3551 }
3552 vos_mem_copy(StaParams.supported_oper_classes,
3553 params->supported_oper_classes,
3554 params->supported_oper_classes_len);
3555 StaParams.supported_oper_classes_len =
3556 params->supported_oper_classes_len;
3557
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003558 if (0 != params->ext_capab_len)
3559 vos_mem_copy(StaParams.extn_capability, params->ext_capab,
3560 sizeof(StaParams.extn_capability));
3561
3562 if (NULL != params->ht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -07003563 {
3564 StaParams.htcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003565 vos_mem_copy(&StaParams.HTCap, params->ht_capa, sizeof(tSirHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -07003566 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003567
3568 StaParams.supported_rates_len = params->supported_rates_len;
3569
3570 /* Note : The Maximum sizeof supported_rates sent by the Supplicant is 32.
3571 * The supported_rates array , for all the structures propogating till Add Sta
3572 * to the firmware has to be modified , if the supplicant (ieee80211) is
3573 * modified to send more rates.
3574 */
3575
3576 /* To avoid Data Currption , set to max length to SIR_MAC_MAX_SUPP_RATES
3577 */
3578 if (StaParams.supported_rates_len > SIR_MAC_MAX_SUPP_RATES)
3579 StaParams.supported_rates_len = SIR_MAC_MAX_SUPP_RATES;
3580
3581 if (0 != StaParams.supported_rates_len) {
3582 int i = 0;
3583 vos_mem_copy(StaParams.supported_rates, params->supported_rates,
3584 StaParams.supported_rates_len);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07003585 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003586 "Supported Rates with Length %d", StaParams.supported_rates_len);
3587 for (i=0; i < StaParams.supported_rates_len; i++)
Hoonki Lee5305c3a2013-04-29 23:28:59 -07003588 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003589 "[%d]: %0x", i, StaParams.supported_rates[i]);
3590 }
3591
3592 if (NULL != params->vht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -07003593 {
3594 StaParams.vhtcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003595 vos_mem_copy(&StaParams.VHTCap, params->vht_capa, sizeof(tSirVHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -07003596 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003597
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003598 if (0 != params->ext_capab_len ) {
3599 /*Define A Macro : TODO Sunil*/
3600 if ((1<<4) & StaParams.extn_capability[3]) {
3601 isBufSta = 1;
3602 }
Naresh Jayaram3180aa42014-02-12 21:47:26 +05303603 /* TDLS Channel Switching Support */
3604 if ((1<<6) & StaParams.extn_capability[3]) {
3605 isOffChannelSupported = 1;
3606 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003607 }
Naresh Jayaram3180aa42014-02-12 21:47:26 +05303608 status = wlan_hdd_tdls_set_peer_caps( pAdapter, mac,
3609 &StaParams, isBufSta,
3610 isOffChannelSupported);
3611
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05303612 if (VOS_STATUS_SUCCESS != status) {
3613 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3614 "%s: wlan_hdd_tdls_set_peer_caps failed!", __func__);
3615 return -EINVAL;
3616 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003617 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 1, &StaParams);
3618
3619 if (VOS_STATUS_SUCCESS != status) {
3620 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3621 "%s: sme_ChangeTdlsPeerSta failed!", __func__);
3622 return -EINVAL;
3623 }
3624 }
Gopichand Nakkalab0856222013-03-12 22:39:05 -07003625#endif
Gopichand Nakkala6239acd2013-06-14 14:48:00 +05303626 }
Jeff Johnsone7245742012-09-05 17:12:55 -07003627 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07003628 return status;
3629}
3630
3631/*
Jeff Johnson295189b2012-06-20 16:38:30 -07003632 * FUNCTION: wlan_hdd_cfg80211_add_key
3633 * This function is used to initialize the key information
3634 */
3635#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003636static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07003637 struct net_device *ndev,
3638 u8 key_index, bool pairwise,
3639 const u8 *mac_addr,
3640 struct key_params *params
3641 )
3642#else
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003643static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07003644 struct net_device *ndev,
3645 u8 key_index, const u8 *mac_addr,
3646 struct key_params *params
3647 )
3648#endif
3649{
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003650 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -07003651 tCsrRoamSetKey setKey;
3652 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05303653 int status;
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003654 v_U32_t roamId= 0xFF;
3655 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07003656 hdd_hostapd_state_t *pHostapdState;
3657 VOS_STATUS vos_status;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07003658 eHalStatus halStatus;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05303659 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07003660
3661 ENTER();
3662
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05303663 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
3664 TRACE_CODE_HDD_CFG80211_ADD_KEY,
3665 pAdapter->sessionId, params->key_len));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05303666 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
3667 status = wlan_hdd_validate_context(pHddCtx);
3668
3669 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07003670 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05303671 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3672 "%s: HDD context is not valid", __func__);
3673 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07003674 }
3675
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05303676 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
3677 __func__, hdd_device_modetoString(pAdapter->device_mode),
3678 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07003679
3680 if (CSR_MAX_NUM_KEY <= key_index)
3681 {
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003682 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07003683 key_index);
3684
3685 return -EINVAL;
3686 }
3687
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003688 if (CSR_MAX_KEY_LEN < params->key_len)
3689 {
3690 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key length %d", __func__,
3691 params->key_len);
3692
3693 return -EINVAL;
3694 }
3695
3696 hddLog(VOS_TRACE_LEVEL_INFO,
3697 "%s: called with key index = %d & key length %d",
3698 __func__, key_index, params->key_len);
Jeff Johnson295189b2012-06-20 16:38:30 -07003699
3700 /*extract key idx, key len and key*/
3701 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
3702 setKey.keyId = key_index;
3703 setKey.keyLength = params->key_len;
3704 vos_mem_copy(&setKey.Key[0],params->key, params->key_len);
3705
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003706 switch (params->cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -07003707 {
3708 case WLAN_CIPHER_SUITE_WEP40:
3709 setKey.encType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
3710 break;
3711
3712 case WLAN_CIPHER_SUITE_WEP104:
3713 setKey.encType = eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
3714 break;
3715
3716 case WLAN_CIPHER_SUITE_TKIP:
3717 {
3718 u8 *pKey = &setKey.Key[0];
3719 setKey.encType = eCSR_ENCRYPT_TYPE_TKIP;
3720
3721 vos_mem_zero(pKey, CSR_MAX_KEY_LEN);
3722
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003723 /*Supplicant sends the 32bytes key in this order
Jeff Johnson295189b2012-06-20 16:38:30 -07003724
3725 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003726 | Tk1 |TX-MIC | RX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -07003727 |--------------|----------|----------|
3728 <---16bytes---><--8bytes--><--8bytes-->
3729
3730 */
3731 /*Sme expects the 32 bytes key to be in the below order
3732
3733 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003734 | Tk1 |RX-MIC | TX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -07003735 |--------------|----------|----------|
3736 <---16bytes---><--8bytes--><--8bytes-->
3737 */
3738 /* Copy the Temporal Key 1 (TK1) */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003739 vos_mem_copy(pKey, params->key, 16);
Jeff Johnson295189b2012-06-20 16:38:30 -07003740
3741 /*Copy the rx mic first*/
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003742 vos_mem_copy(&pKey[16], &params->key[24], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -07003743
3744 /*Copy the tx mic */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003745 vos_mem_copy(&pKey[24], &params->key[16], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -07003746
3747
3748 break;
3749 }
3750
3751 case WLAN_CIPHER_SUITE_CCMP:
3752 setKey.encType = eCSR_ENCRYPT_TYPE_AES;
3753 break;
3754
3755#ifdef FEATURE_WLAN_WAPI
3756 case WLAN_CIPHER_SUITE_SMS4:
3757 {
3758 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
3759 wlan_hdd_cfg80211_set_key_wapi(pAdapter, key_index, mac_addr,
3760 params->key, params->key_len);
3761 return 0;
3762 }
3763#endif
Chet Lanctot186b5732013-03-18 10:26:30 -07003764
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003765#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -07003766 case WLAN_CIPHER_SUITE_KRK:
3767 setKey.encType = eCSR_ENCRYPT_TYPE_KRK;
3768 break;
3769#endif
Chet Lanctot186b5732013-03-18 10:26:30 -07003770
3771#ifdef WLAN_FEATURE_11W
3772 case WLAN_CIPHER_SUITE_AES_CMAC:
3773 setKey.encType = eCSR_ENCRYPT_TYPE_AES_CMAC;
Chet Lanctot3b5158a2013-03-31 16:45:21 -07003774 break;
Chet Lanctot186b5732013-03-18 10:26:30 -07003775#endif
3776
Jeff Johnson295189b2012-06-20 16:38:30 -07003777 default:
Jeff Johnson0299d0a2013-10-30 12:37:43 -07003778 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unsupported cipher type %u",
Jeff Johnson295189b2012-06-20 16:38:30 -07003779 __func__, params->cipher);
3780 return -EOPNOTSUPP;
3781 }
3782
3783 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: encryption type %d",
3784 __func__, setKey.encType);
3785
Shailender Karmuchi642e9812013-05-30 14:34:49 -07003786 if (
Jeff Johnson295189b2012-06-20 16:38:30 -07003787#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
3788 (!pairwise)
3789#else
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003790 (!mac_addr || is_broadcast_ether_addr(mac_addr))
Jeff Johnson295189b2012-06-20 16:38:30 -07003791#endif
Shailender Karmuchi642e9812013-05-30 14:34:49 -07003792 )
3793 {
3794 /* set group key*/
3795 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3796 "%s- %d: setting Broadcast key",
3797 __func__, __LINE__);
3798 setKey.keyDirection = eSIR_RX_ONLY;
3799 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
3800 }
3801 else
3802 {
3803 /* set pairwise key*/
3804 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3805 "%s- %d: setting pairwise key",
3806 __func__, __LINE__);
3807 setKey.keyDirection = eSIR_TX_RX;
3808 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
3809 }
3810 if ((WLAN_HDD_IBSS == pAdapter->device_mode) && !pairwise)
3811 {
3812 setKey.keyDirection = eSIR_TX_RX;
3813 /*Set the group key*/
3814 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
3815 pAdapter->sessionId, &setKey, &roamId );
Jeff Johnson295189b2012-06-20 16:38:30 -07003816
Shailender Karmuchi642e9812013-05-30 14:34:49 -07003817 if ( 0 != status )
3818 {
3819 hddLog(VOS_TRACE_LEVEL_ERROR,
3820 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
3821 return -EINVAL;
3822 }
3823 /*Save the keys here and call sme_RoamSetKey for setting
3824 the PTK after peer joins the IBSS network*/
3825 vos_mem_copy(&pAdapter->sessionCtx.station.ibss_enc_key,
3826 &setKey, sizeof(tCsrRoamSetKey));
3827 return status;
3828 }
Gopichand Nakkala29149562013-05-10 21:43:41 +05303829 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP) ||
3830 (pAdapter->device_mode == WLAN_HDD_P2P_GO))
3831 {
Jeff Johnson295189b2012-06-20 16:38:30 -07003832 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003833 if( pHostapdState->bssState == BSS_START )
3834 {
c_hpothu7c55da62014-01-23 18:34:02 +05303835 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3836 vos_status = wlan_hdd_check_ula_done(pAdapter);
3837
3838 if ( vos_status != VOS_STATUS_SUCCESS )
3839 {
3840 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3841 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
3842 __LINE__, vos_status );
3843
3844 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
3845
3846 return -EINVAL;
3847 }
3848
Jeff Johnson295189b2012-06-20 16:38:30 -07003849 status = WLANSAP_SetKeySta( pVosContext, &setKey);
3850
3851 if ( status != eHAL_STATUS_SUCCESS )
3852 {
3853 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3854 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
3855 __LINE__, status );
3856 }
3857 }
3858
3859 /* Saving WEP keys */
3860 else if( eCSR_ENCRYPT_TYPE_WEP40_STATICKEY == setKey.encType ||
3861 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY == setKey.encType )
3862 {
3863 //Save the wep key in ap context. Issue setkey after the BSS is started.
3864 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
3865 vos_mem_copy(&pAPCtx->wepKey[key_index], &setKey, sizeof(tCsrRoamSetKey));
3866 }
3867 else
3868 {
3869 //Save the key in ap context. Issue setkey after the BSS is started.
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003870 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07003871 vos_mem_copy(&pAPCtx->groupKey, &setKey, sizeof(tCsrRoamSetKey));
3872 }
3873 }
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003874 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION) ||
3875 (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT) )
Jeff Johnson295189b2012-06-20 16:38:30 -07003876 {
3877 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
3878 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3879
Gopichand Nakkala3d295922013-05-07 16:19:14 +05303880#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
3881 if (!pairwise)
3882#else
3883 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
3884#endif
3885 {
3886 /* set group key*/
3887 if (pHddStaCtx->roam_info.deferKeyComplete)
3888 {
3889 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3890 "%s- %d: Perform Set key Complete",
3891 __func__, __LINE__);
3892 hdd_PerformRoamSetKeyComplete(pAdapter);
3893 }
3894 }
3895
Jeff Johnson295189b2012-06-20 16:38:30 -07003896 pWextState->roamProfile.Keys.KeyLength[key_index] = (u8)params->key_len;
3897
Venkata Prathyusha Kuntupalliee2ce712013-01-17 14:09:24 -08003898 pWextState->roamProfile.Keys.defaultIndex = key_index;
3899
3900
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003901 vos_mem_copy(&pWextState->roamProfile.Keys.KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -07003902 params->key, params->key_len);
3903
Gopichand Nakkala3d295922013-05-07 16:19:14 +05303904
Jeff Johnson295189b2012-06-20 16:38:30 -07003905 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
3906
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303907 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -07003908 "%s: set key for peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303909 __func__, setKey.peerMac[0], setKey.peerMac[1],
3910 setKey.peerMac[2], setKey.peerMac[3],
3911 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -07003912 setKey.keyDirection);
3913
3914 vos_status = wlan_hdd_check_ula_done(pAdapter);
3915
3916 if ( vos_status != VOS_STATUS_SUCCESS )
3917 {
3918 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3919 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
3920 __LINE__, vos_status );
3921
3922 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
3923
3924 return -EINVAL;
3925
3926 }
3927
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07003928#ifdef WLAN_FEATURE_VOWIFI_11R
Gopichand Nakkala3d295922013-05-07 16:19:14 +05303929 /* The supplicant may attempt to set the PTK once pre-authentication
3930 is done. Save the key in the UMAC and include it in the ADD BSS
3931 request */
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07003932 halStatus = sme_FTUpdateKey( WLAN_HDD_GET_HAL_CTX(pAdapter), &setKey);
Gopichand Nakkala3d295922013-05-07 16:19:14 +05303933 if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_SUCCESS )
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07003934 {
Gopichand Nakkala3d295922013-05-07 16:19:14 +05303935 hddLog(VOS_TRACE_LEVEL_INFO_MED,
3936 "%s: Update PreAuth Key success", __func__);
3937 return 0;
3938 }
3939 else if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_FAILED )
3940 {
3941 hddLog(VOS_TRACE_LEVEL_ERROR,
3942 "%s: Update PreAuth Key failed", __func__);
Gopichand Nakkalad7d13652013-02-15 01:48:00 +05303943 return -EINVAL;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07003944 }
3945#endif /* WLAN_FEATURE_VOWIFI_11R */
Jeff Johnson295189b2012-06-20 16:38:30 -07003946
3947 /* issue set key request to SME*/
3948 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
3949 pAdapter->sessionId, &setKey, &roamId );
3950
3951 if ( 0 != status )
3952 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303953 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07003954 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
3955 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
3956 return -EINVAL;
3957 }
3958
3959
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303960 /* in case of IBSS as there was no information available about WEP keys during
3961 * IBSS join, group key intialized with NULL key, so re-initialize group key
Jeff Johnson295189b2012-06-20 16:38:30 -07003962 * with correct value*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303963 if ( (eCSR_BSS_TYPE_START_IBSS == pWextState->roamProfile.BSSType) &&
3964 !( ( IW_AUTH_KEY_MGMT_802_1X
3965 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X))
Jeff Johnson295189b2012-06-20 16:38:30 -07003966 && (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType)
3967 )
3968 &&
3969 ( (WLAN_CIPHER_SUITE_WEP40 == params->cipher)
3970 || (WLAN_CIPHER_SUITE_WEP104 == params->cipher)
3971 )
3972 )
3973 {
3974 setKey.keyDirection = eSIR_RX_ONLY;
3975 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
3976
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303977 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -07003978 "%s: set key peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303979 __func__, setKey.peerMac[0], setKey.peerMac[1],
3980 setKey.peerMac[2], setKey.peerMac[3],
3981 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -07003982 setKey.keyDirection);
3983
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303984 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07003985 pAdapter->sessionId, &setKey, &roamId );
3986
3987 if ( 0 != status )
3988 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303989 hddLog(VOS_TRACE_LEVEL_ERROR,
3990 "%s: sme_RoamSetKey failed for group key (IBSS), returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07003991 __func__, status);
3992 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
3993 return -EINVAL;
3994 }
3995 }
3996 }
3997
3998 return 0;
3999}
4000
4001/*
4002 * FUNCTION: wlan_hdd_cfg80211_get_key
4003 * This function is used to get the key information
4004 */
4005#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304006static int wlan_hdd_cfg80211_get_key(
4007 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07004008 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304009 u8 key_index, bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -07004010 const u8 *mac_addr, void *cookie,
4011 void (*callback)(void *cookie, struct key_params*)
4012 )
4013#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304014static int wlan_hdd_cfg80211_get_key(
4015 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07004016 struct net_device *ndev,
4017 u8 key_index, const u8 *mac_addr, void *cookie,
4018 void (*callback)(void *cookie, struct key_params*)
4019 )
4020#endif
4021{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304022 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -07004023 hdd_wext_state_t *pWextState= WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
4024 tCsrRoamProfile *pRoamProfile = &(pWextState->roamProfile);
4025 struct key_params params;
4026
4027 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304028
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05304029 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
4030 __func__, hdd_device_modetoString(pAdapter->device_mode),
4031 pAdapter->device_mode);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304032
Jeff Johnson295189b2012-06-20 16:38:30 -07004033 memset(&params, 0, sizeof(params));
4034
4035 if (CSR_MAX_NUM_KEY <= key_index)
4036 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05304037 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid key index %d"), key_index);
Jeff Johnson295189b2012-06-20 16:38:30 -07004038 return -EINVAL;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304039 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004040
4041 switch(pRoamProfile->EncryptionType.encryptionType[0])
4042 {
4043 case eCSR_ENCRYPT_TYPE_NONE:
4044 params.cipher = IW_AUTH_CIPHER_NONE;
4045 break;
4046
4047 case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY:
4048 case eCSR_ENCRYPT_TYPE_WEP40:
4049 params.cipher = WLAN_CIPHER_SUITE_WEP40;
4050 break;
4051
4052 case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY:
4053 case eCSR_ENCRYPT_TYPE_WEP104:
4054 params.cipher = WLAN_CIPHER_SUITE_WEP104;
4055 break;
4056
4057 case eCSR_ENCRYPT_TYPE_TKIP:
4058 params.cipher = WLAN_CIPHER_SUITE_TKIP;
4059 break;
4060
4061 case eCSR_ENCRYPT_TYPE_AES:
4062 params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
4063 break;
4064
4065 default:
4066 params.cipher = IW_AUTH_CIPHER_NONE;
4067 break;
4068 }
4069
c_hpothuaaf19692014-05-17 17:01:48 +05304070 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
4071 TRACE_CODE_HDD_CFG80211_GET_KEY,
4072 pAdapter->sessionId, params.cipher));
4073
Jeff Johnson295189b2012-06-20 16:38:30 -07004074 params.key_len = pRoamProfile->Keys.KeyLength[key_index];
4075 params.seq_len = 0;
4076 params.seq = NULL;
4077 params.key = &pRoamProfile->Keys.KeyMaterial[key_index][0];
4078 callback(cookie, &params);
4079 return 0;
4080}
4081
4082/*
4083 * FUNCTION: wlan_hdd_cfg80211_del_key
4084 * This function is used to delete the key information
4085 */
4086#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304087static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07004088 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304089 u8 key_index,
4090 bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -07004091 const u8 *mac_addr
4092 )
4093#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304094static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07004095 struct net_device *ndev,
4096 u8 key_index,
4097 const u8 *mac_addr
4098 )
4099#endif
4100{
4101 int status = 0;
4102
4103 //This code needs to be revisited. There is sme_removeKey API, we should
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304104 //plan to use that. After the change to use correct index in setkey,
Jeff Johnson295189b2012-06-20 16:38:30 -07004105 //it is observed that this is invalidating peer
4106 //key index whenever re-key is done. This is affecting data link.
4107 //It should be ok to ignore del_key.
4108#if 0
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304109 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
4110 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07004111 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
4112 tCsrRoamSetKey setKey;
4113 v_U32_t roamId= 0xFF;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304114
Jeff Johnson295189b2012-06-20 16:38:30 -07004115 ENTER();
4116
4117 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device_mode = %d\n",
4118 __func__,pAdapter->device_mode);
4119
4120 if (CSR_MAX_NUM_KEY <= key_index)
4121 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304122 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07004123 key_index);
4124
4125 return -EINVAL;
4126 }
4127
4128 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
4129 setKey.keyId = key_index;
4130
4131 if (mac_addr)
4132 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
4133 else
4134 vos_mem_copy(setKey.peerMac, groupmacaddr, WNI_CFG_BSSID_LEN);
4135
4136 setKey.encType = eCSR_ENCRYPT_TYPE_NONE;
4137
4138 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07004139 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304140 )
4141 {
4142
4143 hdd_hostapd_state_t *pHostapdState =
Jeff Johnson295189b2012-06-20 16:38:30 -07004144 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
4145 if( pHostapdState->bssState == BSS_START)
4146 {
4147 status = WLANSAP_SetKeySta( pVosContext, &setKey);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304148
Jeff Johnson295189b2012-06-20 16:38:30 -07004149 if ( status != eHAL_STATUS_SUCCESS )
4150 {
4151 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4152 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
4153 __LINE__, status );
4154 }
4155 }
4156 }
4157 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304158 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnson295189b2012-06-20 16:38:30 -07004159 )
4160 {
4161 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4162
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304163 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
4164
4165 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -07004166 "%s: delete key for peerMac %2x:%2x:%2x:%2x:%2x:%2x",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304167 __func__, setKey.peerMac[0], setKey.peerMac[1],
4168 setKey.peerMac[2], setKey.peerMac[3],
Jeff Johnson295189b2012-06-20 16:38:30 -07004169 setKey.peerMac[4], setKey.peerMac[5]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304170 if(pAdapter->sessionCtx.station.conn_info.connState ==
4171 eConnectionState_Associated)
Jeff Johnson295189b2012-06-20 16:38:30 -07004172 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304173 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07004174 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304175
Jeff Johnson295189b2012-06-20 16:38:30 -07004176 if ( 0 != status )
4177 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304178 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07004179 "%s: sme_RoamSetKey failure, returned %d",
4180 __func__, status);
4181 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
4182 return -EINVAL;
4183 }
4184 }
4185 }
4186#endif
Jeff Johnsone7245742012-09-05 17:12:55 -07004187 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07004188 return status;
4189}
4190
4191/*
4192 * FUNCTION: wlan_hdd_cfg80211_set_default_key
4193 * This function is used to set the default tx key index
4194 */
4195#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
4196static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
4197 struct net_device *ndev,
4198 u8 key_index,
4199 bool unicast, bool multicast)
4200#else
4201static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
4202 struct net_device *ndev,
4203 u8 key_index)
4204#endif
4205{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304206 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05304207 int status;
Gopichand Nakkala29149562013-05-10 21:43:41 +05304208 hdd_wext_state_t *pWextState;
4209 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05304210 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07004211
4212 ENTER();
4213
Gopichand Nakkala29149562013-05-10 21:43:41 +05304214 if ((NULL == pAdapter))
4215 {
4216 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
4217 "invalid adapter");
4218 return -EINVAL;
4219 }
4220
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05304221 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
4222 TRACE_CODE_HDD_CFG80211_SET_DEFAULT_KEY,
4223 pAdapter->sessionId, key_index));
4224
Gopichand Nakkala29149562013-05-10 21:43:41 +05304225 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
4226 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4227
4228 if ((NULL == pWextState) || (NULL == pHddStaCtx))
4229 {
4230 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
4231 "invalid Wext state or HDD context");
4232 return -EINVAL;
4233 }
4234
Arif Hussain6d2a3322013-11-17 19:50:10 -08004235 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d key_index = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07004236 __func__,pAdapter->device_mode, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304237
Jeff Johnson295189b2012-06-20 16:38:30 -07004238 if (CSR_MAX_NUM_KEY <= key_index)
4239 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304240 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07004241 key_index);
4242
4243 return -EINVAL;
4244 }
4245
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05304246 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
4247 status = wlan_hdd_validate_context(pHddCtx);
4248
4249 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004250 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05304251 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4252 "%s: HDD context is not valid", __func__);
4253 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004254 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304255
Jeff Johnson295189b2012-06-20 16:38:30 -07004256 if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -07004257 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304258 )
Jeff Johnson295189b2012-06-20 16:38:30 -07004259 {
Gopichand Nakkala29149562013-05-10 21:43:41 +05304260 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
Arif Hussain6943f522013-11-04 20:10:10 -08004261 pHddStaCtx->conn_info.ucEncryptionType) &&
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304262 (eCSR_ENCRYPT_TYPE_AES !=
Arif Hussain6943f522013-11-04 20:10:10 -08004263 pHddStaCtx->conn_info.ucEncryptionType)
Jeff Johnson295189b2012-06-20 16:38:30 -07004264 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304265 {
4266 /* if default key index is not same as previous one,
Jeff Johnson295189b2012-06-20 16:38:30 -07004267 * then update the default key index */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304268
Jeff Johnson295189b2012-06-20 16:38:30 -07004269 tCsrRoamSetKey setKey;
4270 v_U32_t roamId= 0xFF;
4271 tCsrKeys *Keys = &pWextState->roamProfile.Keys;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304272
4273 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: default tx key index %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07004274 __func__, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304275
Jeff Johnson295189b2012-06-20 16:38:30 -07004276 Keys->defaultIndex = (u8)key_index;
4277 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
4278 setKey.keyId = key_index;
4279 setKey.keyLength = Keys->KeyLength[key_index];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304280
4281 vos_mem_copy(&setKey.Key[0],
4282 &Keys->KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -07004283 Keys->KeyLength[key_index]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304284
Gopichand Nakkala29149562013-05-10 21:43:41 +05304285 setKey.keyDirection = eSIR_TX_RX;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304286
4287 vos_mem_copy(setKey.peerMac,
Jeff Johnson295189b2012-06-20 16:38:30 -07004288 &pHddStaCtx->conn_info.bssId[0],
4289 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304290
Gopichand Nakkala29149562013-05-10 21:43:41 +05304291 if (Keys->KeyLength[key_index] == CSR_WEP40_KEY_LEN &&
4292 pWextState->roamProfile.EncryptionType.encryptionType[0] ==
4293 eCSR_ENCRYPT_TYPE_WEP104)
4294 {
4295 /*In the case of dynamic wep supplicant hardcodes DWEP type to eCSR_ENCRYPT_TYPE_WEP104
4296 even though ap is configured for WEP-40 encryption. In this canse the key length
4297 is 5 but the encryption type is 104 hence checking the key langht(5) and encryption
4298 type(104) and switching encryption type to 40*/
4299 pWextState->roamProfile.EncryptionType.encryptionType[0] =
4300 eCSR_ENCRYPT_TYPE_WEP40;
4301 pWextState->roamProfile.mcEncryptionType.encryptionType[0] =
4302 eCSR_ENCRYPT_TYPE_WEP40;
4303 }
4304
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304305 setKey.encType =
Jeff Johnson295189b2012-06-20 16:38:30 -07004306 pWextState->roamProfile.EncryptionType.encryptionType[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304307
Jeff Johnson295189b2012-06-20 16:38:30 -07004308 /* issue set key request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304309 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07004310 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304311
Jeff Johnson295189b2012-06-20 16:38:30 -07004312 if ( 0 != status )
4313 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304314 hddLog(VOS_TRACE_LEVEL_ERROR,
4315 "%s: sme_RoamSetKey failed, returned %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07004316 status);
4317 return -EINVAL;
4318 }
4319 }
4320 }
4321
4322 /* In SoftAp mode setting key direction for default mode */
4323 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
4324 {
4325 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
4326 pWextState->roamProfile.EncryptionType.encryptionType[0]) &&
4327 (eCSR_ENCRYPT_TYPE_AES !=
4328 pWextState->roamProfile.EncryptionType.encryptionType[0])
4329 )
4330 {
4331 /* Saving key direction for default key index to TX default */
4332 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
4333 pAPCtx->wepKey[key_index].keyDirection = eSIR_TX_DEFAULT;
4334 }
4335 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304336
Jeff Johnson295189b2012-06-20 16:38:30 -07004337 return status;
4338}
4339
Jeff Johnson295189b2012-06-20 16:38:30 -07004340/*
4341 * FUNCTION: wlan_hdd_cfg80211_inform_bss
4342 * This function is used to inform the BSS details to nl80211 interface.
4343 */
4344static struct cfg80211_bss* wlan_hdd_cfg80211_inform_bss(
4345 hdd_adapter_t *pAdapter, tCsrRoamConnectedProfile *roamProfile)
4346{
4347 struct net_device *dev = pAdapter->dev;
4348 struct wireless_dev *wdev = dev->ieee80211_ptr;
4349 struct wiphy *wiphy = wdev->wiphy;
4350 tSirBssDescription *pBssDesc = roamProfile->pBssDesc;
4351 int chan_no;
4352 int ie_length;
4353 const char *ie;
4354 unsigned int freq;
4355 struct ieee80211_channel *chan;
4356 int rssi = 0;
4357 struct cfg80211_bss *bss = NULL;
4358
4359 ENTER();
4360
4361 if( NULL == pBssDesc )
4362 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08004363 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pBssDesc is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004364 return bss;
4365 }
4366
4367 chan_no = pBssDesc->channelId;
4368 ie_length = GET_IE_LEN_IN_BSS_DESC( pBssDesc->length );
4369 ie = ((ie_length != 0) ? (const char *)&pBssDesc->ieFields: NULL);
4370
4371 if( NULL == ie )
4372 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08004373 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: IE of BSS descriptor is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004374 return bss;
4375 }
4376
4377#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
4378 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
4379 {
4380 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
4381 }
4382 else
4383 {
4384 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
4385 }
4386#else
4387 freq = ieee80211_channel_to_frequency(chan_no);
4388#endif
4389
4390 chan = __ieee80211_get_channel(wiphy, freq);
4391
Santhosh Kumar Padmaa45fdb12014-04-15 15:54:38 +05304392 if (!chan) {
4393 hddLog(VOS_TRACE_LEVEL_ERROR, "%s chan pointer is NULL", __func__);
4394 return NULL;
4395 }
4396
Jeff Johnson295189b2012-06-20 16:38:30 -07004397 bss = cfg80211_get_bss(wiphy, chan, pBssDesc->bssId,
4398 &roamProfile->SSID.ssId[0], roamProfile->SSID.length,
4399 WLAN_CAPABILITY_ESS, WLAN_CAPABILITY_ESS);
4400 if (bss == NULL)
4401 {
4402 rssi = (VOS_MIN ((pBssDesc->rssi + pBssDesc->sinr), 0))*100;
4403
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304404 return (cfg80211_inform_bss(wiphy, chan, pBssDesc->bssId,
4405 le64_to_cpu(*(__le64 *)pBssDesc->timeStamp),
Jeff Johnson295189b2012-06-20 16:38:30 -07004406 pBssDesc->capabilityInfo,
4407 pBssDesc->beaconInterval, ie, ie_length,
4408 rssi, GFP_KERNEL ));
4409}
4410 else
4411 {
4412 return bss;
4413 }
4414}
4415
4416
4417
4418/*
4419 * FUNCTION: wlan_hdd_cfg80211_inform_bss_frame
4420 * This function is used to inform the BSS details to nl80211 interface.
4421 */
4422struct cfg80211_bss*
4423wlan_hdd_cfg80211_inform_bss_frame( hdd_adapter_t *pAdapter,
4424 tSirBssDescription *bss_desc
4425 )
4426{
4427 /*
4428 cfg80211_inform_bss() is not updating ie field of bss entry, if entry
4429 already exists in bss data base of cfg80211 for that particular BSS ID.
4430 Using cfg80211_inform_bss_frame to update the bss entry instead of
4431 cfg80211_inform_bss, But this call expects mgmt packet as input. As of
4432 now there is no possibility to get the mgmt(probe response) frame from PE,
4433 converting bss_desc to ieee80211_mgmt(probe response) and passing to
4434 cfg80211_inform_bss_frame.
4435 */
4436 struct net_device *dev = pAdapter->dev;
4437 struct wireless_dev *wdev = dev->ieee80211_ptr;
4438 struct wiphy *wiphy = wdev->wiphy;
4439 int chan_no = bss_desc->channelId;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08004440#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
4441 qcom_ie_age *qie_age = NULL;
4442 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length ) + sizeof(qcom_ie_age);
4443#else
Jeff Johnson295189b2012-06-20 16:38:30 -07004444 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length );
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08004445#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07004446 const char *ie =
4447 ((ie_length != 0) ? (const char *)&bss_desc->ieFields: NULL);
4448 unsigned int freq;
4449 struct ieee80211_channel *chan;
Abhishek Singh1e2bfa32014-01-02 15:44:15 +05304450 struct ieee80211_mgmt *mgmt = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07004451 struct cfg80211_bss *bss_status = NULL;
4452 size_t frame_len = sizeof (struct ieee80211_mgmt) + ie_length;
4453 int rssi = 0;
Wilson Yangf80a0542013-10-07 13:02:37 -07004454 hdd_context_t *pHddCtx;
4455 int status;
Jeff Johnsone7245742012-09-05 17:12:55 -07004456#ifdef WLAN_OPEN_SOURCE
4457 struct timespec ts;
4458#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07004459
Wilson Yangf80a0542013-10-07 13:02:37 -07004460 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
4461 status = wlan_hdd_validate_context(pHddCtx);
4462
4463 /*bss_update is not allowed during wlan driver loading or unloading*/
Mihir Shete18156292014-03-11 15:38:30 +05304464 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Wilson Yangf80a0542013-10-07 13:02:37 -07004465 {
4466 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4467 "%s:Loading_unloading in Progress. Ignore!!!",__func__);
4468 return NULL;
4469 }
4470
4471
4472 if (0 != status)
4473 {
4474 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4475 "%s: HDD context is not valid", __func__);
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -07004476 return NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -07004477 }
4478
Abhishek Singh1e2bfa32014-01-02 15:44:15 +05304479 mgmt = kzalloc((sizeof (struct ieee80211_mgmt) + ie_length), GFP_KERNEL);
Wilson Yangf80a0542013-10-07 13:02:37 -07004480 if (!mgmt)
4481 {
4482 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4483 "%s: memory allocation failed ", __func__);
4484 return NULL;
4485 }
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -07004486
Jeff Johnson295189b2012-06-20 16:38:30 -07004487 memcpy(mgmt->bssid, bss_desc->bssId, ETH_ALEN);
Jeff Johnsone7245742012-09-05 17:12:55 -07004488
4489#ifdef WLAN_OPEN_SOURCE
4490 /* Android does not want the timestamp from the frame.
4491 Instead it wants a monotonic increasing value */
4492 get_monotonic_boottime(&ts);
4493 mgmt->u.probe_resp.timestamp =
4494 ((u64)ts.tv_sec * 1000000) + (ts.tv_nsec / 1000);
4495#else
4496 /* keep old behavior for non-open source (for now) */
Jeff Johnson295189b2012-06-20 16:38:30 -07004497 memcpy(&mgmt->u.probe_resp.timestamp, bss_desc->timeStamp,
4498 sizeof (bss_desc->timeStamp));
Jeff Johnsone7245742012-09-05 17:12:55 -07004499
4500#endif
4501
Jeff Johnson295189b2012-06-20 16:38:30 -07004502 mgmt->u.probe_resp.beacon_int = bss_desc->beaconInterval;
4503 mgmt->u.probe_resp.capab_info = bss_desc->capabilityInfo;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08004504
4505#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
4506 /* GPS Requirement: need age ie per entry. Using vendor specific. */
4507 /* Assuming this is the last IE, copy at the end */
4508 ie_length -=sizeof(qcom_ie_age);
4509 qie_age = (qcom_ie_age *)(mgmt->u.probe_resp.variable + ie_length);
4510 qie_age->element_id = QCOM_VENDOR_IE_ID;
4511 qie_age->len = QCOM_VENDOR_IE_AGE_LEN;
4512 qie_age->oui_1 = QCOM_OUI1;
4513 qie_age->oui_2 = QCOM_OUI2;
4514 qie_age->oui_3 = QCOM_OUI3;
4515 qie_age->type = QCOM_VENDOR_IE_AGE_TYPE;
4516 qie_age->age = vos_timer_get_system_ticks() - bss_desc->nReceivedTime;
4517#endif
4518
Jeff Johnson295189b2012-06-20 16:38:30 -07004519 memcpy(mgmt->u.probe_resp.variable, ie, ie_length);
Gopichand Nakkalad908ec82013-05-16 19:32:19 +05304520 if (bss_desc->fProbeRsp)
4521 {
4522 mgmt->frame_control |=
4523 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_RESP);
4524 }
4525 else
4526 {
4527 mgmt->frame_control |=
4528 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_BEACON);
4529 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004530
4531#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304532 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ) &&
Jeff Johnson295189b2012-06-20 16:38:30 -07004533 (wiphy->bands[IEEE80211_BAND_2GHZ] != NULL))
4534 {
4535 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
4536 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304537 else if ((chan_no > ARRAY_SIZE(hdd_channels_2_4_GHZ)) &&
Jeff Johnson295189b2012-06-20 16:38:30 -07004538 (wiphy->bands[IEEE80211_BAND_5GHZ] != NULL))
4539
4540 {
4541 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
4542 }
4543 else
4544 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05304545 hddLog(VOS_TRACE_LEVEL_ERROR, "%s Invalid chan_no:%d",
4546 __func__, chan_no);
Jeff Johnson295189b2012-06-20 16:38:30 -07004547 kfree(mgmt);
4548 return NULL;
4549 }
4550#else
4551 freq = ieee80211_channel_to_frequency(chan_no);
4552#endif
4553 chan = __ieee80211_get_channel(wiphy, freq);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -08004554 /*when the band is changed on the fly using the GUI, three things are done
4555 * 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)
4556 * as part of the scan abort, message willbe queued to PE and we proceed with flushing and changinh the band.
4557 * pe will stop the scanning further and report back the results what ever it had till now by calling the call back function.
4558 * if the time between update band and scandone call back is sufficent enough the band change reflects in SME, SME validates the channels
4559 * and discards the channels correponding to previous band and calls back with zero bss results.
4560 * 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
4561 * all the channels correponding to previous band.this is due to race condition.but those channels are invalid to the new band and so
4562 * this function __ieee80211_get_channel will return NULL.Each time we report scan result with this pointer null warning kernel trace is printed.
4563 * if the scan results contain large number of APs continuosly kernel warning trace is printed and it will lead to apps watch dog bark.
4564 * So drop the bss and continue to next bss.
4565 */
4566 if(chan == NULL)
4567 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05304568 hddLog(VOS_TRACE_LEVEL_ERROR, "%s chan pointer is NULL", __func__);
Chilam Ngc4244af2013-04-01 15:37:32 -07004569 kfree(mgmt);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -08004570 return NULL;
4571 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004572 /*To keep the rssi icon of the connected AP in the scan window
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304573 *and the rssi icon of the wireless networks in sync
Jeff Johnson295189b2012-06-20 16:38:30 -07004574 * */
4575 if (( eConnectionState_Associated ==
4576 pAdapter->sessionCtx.station.conn_info.connState ) &&
4577 ( VOS_TRUE == vos_mem_compare(bss_desc->bssId,
4578 pAdapter->sessionCtx.station.conn_info.bssId,
4579 WNI_CFG_BSSID_LEN)))
4580 {
4581 /* supplicant takes the signal strength in terms of mBm(100*dBm) */
4582 rssi = (pAdapter->rssi * 100);
4583 }
4584 else
4585 {
4586 rssi = (VOS_MIN ((bss_desc->rssi + bss_desc->sinr), 0))*100;
4587 }
4588
Nirav Shah20ac06f2013-12-12 18:14:06 +05304589 hddLog(VOS_TRACE_LEVEL_INFO, "%s: BSSID:" MAC_ADDRESS_STR " Channel:%d"
4590 "RSSI:%d", __func__, MAC_ADDR_ARRAY(mgmt->bssid),
4591 chan->center_freq, (int)(rssi/100));
4592
Jeff Johnson295189b2012-06-20 16:38:30 -07004593 bss_status = cfg80211_inform_bss_frame(wiphy, chan, mgmt,
4594 frame_len, rssi, GFP_KERNEL);
4595 kfree(mgmt);
4596 return bss_status;
4597}
4598
4599/*
4600 * FUNCTION: wlan_hdd_cfg80211_update_bss_db
4601 * This function is used to update the BSS data base of CFG8011
4602 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304603struct cfg80211_bss* wlan_hdd_cfg80211_update_bss_db( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07004604 tCsrRoamInfo *pRoamInfo
4605 )
4606{
4607 tCsrRoamConnectedProfile roamProfile;
4608 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
4609 struct cfg80211_bss *bss = NULL;
4610
4611 ENTER();
4612
4613 memset(&roamProfile, 0, sizeof(tCsrRoamConnectedProfile));
4614 sme_RoamGetConnectProfile(hHal, pAdapter->sessionId, &roamProfile);
4615
4616 if (NULL != roamProfile.pBssDesc)
4617 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304618 bss = wlan_hdd_cfg80211_inform_bss(pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07004619 &roamProfile);
4620
4621 if (NULL == bss)
4622 {
4623 hddLog(VOS_TRACE_LEVEL_INFO, "%s: cfg80211_inform_bss return NULL",
4624 __func__);
4625 }
4626
4627 sme_RoamFreeConnectProfile(hHal, &roamProfile);
4628 }
4629 else
4630 {
4631 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: roamProfile.pBssDesc is NULL",
4632 __func__);
4633 }
4634 return bss;
4635}
4636
4637/*
4638 * FUNCTION: wlan_hdd_cfg80211_update_bss
4639 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304640static int wlan_hdd_cfg80211_update_bss( struct wiphy *wiphy,
4641 hdd_adapter_t *pAdapter
Jeff Johnson295189b2012-06-20 16:38:30 -07004642 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304643{
Jeff Johnson295189b2012-06-20 16:38:30 -07004644 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
4645 tCsrScanResultInfo *pScanResult;
4646 eHalStatus status = 0;
4647 tScanResultHandle pResult;
4648 struct cfg80211_bss *bss_status = NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -07004649 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07004650
4651 ENTER();
4652
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05304653 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
4654 TRACE_CODE_HDD_CFG80211_UPDATE_BSS,
4655 NO_SESSION, pAdapter->sessionId));
4656
Wilson Yangf80a0542013-10-07 13:02:37 -07004657 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
4658
4659 if (pHddCtx->isLogpInProgress)
Jeff Johnson295189b2012-06-20 16:38:30 -07004660 {
Wilson Yangf80a0542013-10-07 13:02:37 -07004661 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
4662 "%s:LOGP in Progress. Ignore!!!",__func__);
4663 return -EAGAIN;
Jeff Johnson295189b2012-06-20 16:38:30 -07004664 }
4665
Wilson Yangf80a0542013-10-07 13:02:37 -07004666
4667 /*bss_update is not allowed during wlan driver loading or unloading*/
Mihir Shete18156292014-03-11 15:38:30 +05304668 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Wilson Yangf80a0542013-10-07 13:02:37 -07004669 {
4670 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4671 "%s:Loading_unloading in Progress. Ignore!!!",__func__);
4672 return VOS_STATUS_E_PERM;
4673 }
4674
4675
Jeff Johnson295189b2012-06-20 16:38:30 -07004676 /*
4677 * start getting scan results and populate cgf80211 BSS database
4678 */
4679 status = sme_ScanGetResult(hHal, pAdapter->sessionId, NULL, &pResult);
4680
4681 /* no scan results */
4682 if (NULL == pResult)
4683 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05304684 hddLog(VOS_TRACE_LEVEL_INFO, "%s: No scan result Status %d",
4685 __func__, status);
Jeff Johnson295189b2012-06-20 16:38:30 -07004686 return status;
4687 }
4688
4689 pScanResult = sme_ScanResultGetFirst(hHal, pResult);
4690
4691 while (pScanResult)
4692 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304693 /*
4694 * cfg80211_inform_bss() is not updating ie field of bss entry, if
4695 * entry already exists in bss data base of cfg80211 for that
4696 * particular BSS ID. Using cfg80211_inform_bss_frame to update the
4697 * bss entry instead of cfg80211_inform_bss, But this call expects
4698 * mgmt packet as input. As of now there is no possibility to get
4699 * the mgmt(probe response) frame from PE, converting bss_desc to
Jeff Johnson295189b2012-06-20 16:38:30 -07004700 * ieee80211_mgmt(probe response) and passing to c
4701 * fg80211_inform_bss_frame.
4702 * */
4703
4704 bss_status = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
4705 &pScanResult->BssDescriptor);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304706
Jeff Johnson295189b2012-06-20 16:38:30 -07004707
4708 if (NULL == bss_status)
4709 {
4710 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -08004711 "%s: NULL returned by cfg80211_inform_bss", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004712 }
4713 else
4714 {
Yue Maf49ba872013-08-19 12:04:25 -07004715 cfg80211_put_bss(
4716#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0))
4717 wiphy,
4718#endif
4719 bss_status);
Jeff Johnson295189b2012-06-20 16:38:30 -07004720 }
4721
4722 pScanResult = sme_ScanResultGetNext(hHal, pResult);
4723 }
4724
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304725 sme_ScanResultPurge(hHal, pResult);
Jeff Johnson295189b2012-06-20 16:38:30 -07004726
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304727 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07004728}
4729
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004730void
4731hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel)
4732{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304733 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussaina7c8e412013-11-20 11:06:42 -08004734 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(macAddr));
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004735} /****** end hddPrintMacAddr() ******/
4736
4737void
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07004738hddPrintPmkId(tANI_U8 *pmkId, tANI_U8 logLevel)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004739{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304740 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussain6d2a3322013-11-17 19:50:10 -08004741 "%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X",
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07004742 pmkId[0], pmkId[1], pmkId[2], pmkId[3], pmkId[4],
4743 pmkId[5], pmkId[6], pmkId[7], pmkId[8], pmkId[9], pmkId[10],
4744 pmkId[11], pmkId[12], pmkId[13], pmkId[14], pmkId[15]);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004745} /****** end hddPrintPmkId() ******/
4746
4747//hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel);
4748//hddPrintMacAddr(macAddr, VOS_TRACE_LEVEL_FATAL);
4749
4750//void sirDumpBuf(tpAniSirGlobal pMac, tANI_U8 modId, tANI_U32 level, tANI_U8 *buf, tANI_U32 size);
4751//sirDumpBuf(pMac, VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, pmkid, 16);
4752
4753#define dump_bssid(bssid) \
4754 { \
Jeff Johnsone7245742012-09-05 17:12:55 -07004755 hddLog(VOS_TRACE_LEVEL_INFO, "BSSID (MAC) address:\t"); \
4756 hddPrintMacAddr(bssid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004757 }
4758
4759#define dump_pmkid(pMac, pmkid) \
4760 { \
Jeff Johnsone7245742012-09-05 17:12:55 -07004761 hddLog(VOS_TRACE_LEVEL_INFO, "PMKSA-ID:\t"); \
4762 hddPrintPmkId(pmkid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004763 }
4764
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -07004765#if defined(FEATURE_WLAN_LFR) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004766/*
4767 * FUNCTION: wlan_hdd_cfg80211_pmksa_candidate_notify
4768 * This function is used to notify the supplicant of a new PMKSA candidate.
4769 */
4770int wlan_hdd_cfg80211_pmksa_candidate_notify(
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304771 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004772 int index, bool preauth )
4773{
Jeff Johnsone7245742012-09-05 17:12:55 -07004774#ifdef FEATURE_WLAN_OKC
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004775 struct net_device *dev = pAdapter->dev;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004776 hdd_context_t *pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004777
4778 ENTER();
Jeff Johnsone7245742012-09-05 17:12:55 -07004779 hddLog(VOS_TRACE_LEVEL_INFO, "%s is going to notify supplicant of:", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004780
4781 if( NULL == pRoamInfo )
4782 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08004783 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pRoamInfo is NULL", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004784 return -EINVAL;
4785 }
4786
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004787 if (eANI_BOOLEAN_TRUE == hdd_is_okc_mode_enabled(pHddCtx))
4788 {
4789 dump_bssid(pRoamInfo->bssid);
4790 cfg80211_pmksa_candidate_notify(dev, index,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004791 pRoamInfo->bssid, preauth, GFP_KERNEL);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004792 }
Jeff Johnsone7245742012-09-05 17:12:55 -07004793#endif /* FEATURE_WLAN_OKC */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304794 return 0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004795}
4796#endif //FEATURE_WLAN_LFR
4797
Yue Maef608272013-04-08 23:09:17 -07004798#ifdef FEATURE_WLAN_LFR_METRICS
4799/*
4800 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth
4801 * 802.11r/LFR metrics reporting function to report preauth initiation
4802 *
4803 */
4804#define MAX_LFR_METRICS_EVENT_LENGTH 100
4805VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth(hdd_adapter_t *pAdapter,
4806 tCsrRoamInfo *pRoamInfo)
4807{
4808 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
4809 union iwreq_data wrqu;
4810
4811 ENTER();
4812
4813 if (NULL == pAdapter)
4814 {
4815 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
4816 return VOS_STATUS_E_FAILURE;
4817 }
4818
4819 /* create the event */
4820 memset(&wrqu, 0, sizeof(wrqu));
4821 memset(metrics_notification, 0, sizeof(metrics_notification));
4822
4823 wrqu.data.pointer = metrics_notification;
4824 wrqu.data.length = scnprintf(metrics_notification,
4825 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_INIT "
4826 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
4827
4828 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
4829
4830 EXIT();
4831
4832 return VOS_STATUS_SUCCESS;
4833}
4834
4835/*
4836 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth_status
4837 * 802.11r/LFR metrics reporting function to report preauth completion
4838 * or failure
4839 */
4840VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth_status(
4841 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo, bool preauth_status)
4842{
4843 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
4844 union iwreq_data wrqu;
4845
4846 ENTER();
4847
4848 if (NULL == pAdapter)
4849 {
4850 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
4851 return VOS_STATUS_E_FAILURE;
4852 }
4853
4854 /* create the event */
4855 memset(&wrqu, 0, sizeof(wrqu));
4856 memset(metrics_notification, 0, sizeof(metrics_notification));
4857
4858 scnprintf(metrics_notification, sizeof(metrics_notification),
4859 "QCOM: LFR_PREAUTH_STATUS "MAC_ADDRESS_STR,
4860 MAC_ADDR_ARRAY(pRoamInfo->bssid));
4861
4862 if (1 == preauth_status)
4863 strncat(metrics_notification, " TRUE", 5);
4864 else
4865 strncat(metrics_notification, " FALSE", 6);
4866
4867 wrqu.data.pointer = metrics_notification;
4868 wrqu.data.length = strlen(metrics_notification);
4869
4870 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
4871
4872 EXIT();
4873
4874 return VOS_STATUS_SUCCESS;
4875}
4876
4877/*
4878 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_handover
4879 * 802.11r/LFR metrics reporting function to report handover initiation
4880 *
4881 */
4882VOS_STATUS wlan_hdd_cfg80211_roam_metrics_handover(hdd_adapter_t * pAdapter,
4883 tCsrRoamInfo *pRoamInfo)
4884{
4885 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
4886 union iwreq_data wrqu;
4887
4888 ENTER();
4889
4890 if (NULL == pAdapter)
4891 {
4892 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
4893 return VOS_STATUS_E_FAILURE;
4894 }
4895
4896 /* create the event */
4897 memset(&wrqu, 0, sizeof(wrqu));
4898 memset(metrics_notification, 0, sizeof(metrics_notification));
4899
4900 wrqu.data.pointer = metrics_notification;
4901 wrqu.data.length = scnprintf(metrics_notification,
4902 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_HANDOVER "
4903 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
4904
4905 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
4906
4907 EXIT();
4908
4909 return VOS_STATUS_SUCCESS;
4910}
4911#endif
4912
Jeff Johnson295189b2012-06-20 16:38:30 -07004913/*
4914 * FUNCTION: hdd_cfg80211_scan_done_callback
4915 * scanning callback function, called after finishing scan
4916 *
4917 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304918static eHalStatus hdd_cfg80211_scan_done_callback(tHalHandle halHandle,
Jeff Johnson295189b2012-06-20 16:38:30 -07004919 void *pContext, tANI_U32 scanId, eCsrScanStatus status)
4920{
4921 struct net_device *dev = (struct net_device *) pContext;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304922 //struct wireless_dev *wdev = dev->ieee80211_ptr;
Jeff Johnson295189b2012-06-20 16:38:30 -07004923 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07004924 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
4925 hdd_scaninfo_t *pScanInfo = &pHddCtx->scan_info;
Jeff Johnson295189b2012-06-20 16:38:30 -07004926 struct cfg80211_scan_request *req = NULL;
4927 int ret = 0;
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +05304928 bool aborted = false;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05304929 long waitRet = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07004930
4931 ENTER();
4932
4933 hddLog(VOS_TRACE_LEVEL_INFO,
4934 "%s called with halHandle = %p, pContext = %p,"
Arif Hussain6d2a3322013-11-17 19:50:10 -08004935 "scanID = %d, returned status = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07004936 __func__, halHandle, pContext, (int) scanId, (int) status);
4937
Kiet Lamac06e2c2013-10-23 16:25:07 +05304938 pScanInfo->mScanPendingCounter = 0;
4939
Jeff Johnson295189b2012-06-20 16:38:30 -07004940 //Block on scan req completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +05304941 waitRet = wait_for_completion_interruptible_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07004942 &pScanInfo->scan_req_completion_event,
4943 msecs_to_jiffies(WLAN_WAIT_TIME_SCAN_REQ));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05304944 if (waitRet <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -07004945 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05304946 hddLog(VOS_TRACE_LEVEL_ERROR,
4947 "%s wait on scan_req_completion_event failed %ld",__func__, waitRet);
Jeff Johnson295189b2012-06-20 16:38:30 -07004948 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -07004949 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -07004950 }
4951
Yue Maef608272013-04-08 23:09:17 -07004952 if (pScanInfo->mScanPending != VOS_TRUE)
Jeff Johnson295189b2012-06-20 16:38:30 -07004953 {
4954 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -07004955 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -07004956 }
4957
4958 /* Check the scanId */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304959 if (pScanInfo->scanId != scanId)
Jeff Johnson295189b2012-06-20 16:38:30 -07004960 {
4961 hddLog(VOS_TRACE_LEVEL_INFO,
4962 "%s called with mismatched scanId pScanInfo->scanId = %d "
Arif Hussain6d2a3322013-11-17 19:50:10 -08004963 "scanId = %d", __func__, (int) pScanInfo->scanId,
Jeff Johnson295189b2012-06-20 16:38:30 -07004964 (int) scanId);
4965 }
4966
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304967 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07004968 pAdapter);
4969
4970 if (0 > ret)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304971 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004972
4973
4974 /* If any client wait scan result through WEXT
4975 * send scan done event to client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07004976 if (pHddCtx->scan_info.waitScanResult)
Jeff Johnson295189b2012-06-20 16:38:30 -07004977 {
4978 /* The other scan request waiting for current scan finish
4979 * Send event to notify current scan finished */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07004980 if(WEXT_SCAN_PENDING_DELAY == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -07004981 {
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07004982 vos_event_set(&pHddCtx->scan_info.scan_finished_event);
Jeff Johnson295189b2012-06-20 16:38:30 -07004983 }
4984 /* Send notify to WEXT client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07004985 else if(WEXT_SCAN_PENDING_PIGGYBACK == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -07004986 {
4987 struct net_device *dev = pAdapter->dev;
4988 union iwreq_data wrqu;
4989 int we_event;
4990 char *msg;
4991
4992 memset(&wrqu, '\0', sizeof(wrqu));
4993 we_event = SIOCGIWSCAN;
4994 msg = NULL;
4995 wireless_send_event(dev, we_event, &wrqu, msg);
4996 }
4997 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07004998 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07004999
5000 /* Get the Scan Req */
5001 req = pAdapter->request;
5002
5003 if (!req)
5004 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08005005 hddLog(VOS_TRACE_LEVEL_ERROR, "request is became NULL");
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07005006 pScanInfo->mScanPending = VOS_FALSE;
Jeff Johnsone7245742012-09-05 17:12:55 -07005007 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -07005008 }
5009
5010 /*
5011 * setting up 0, just in case.
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305012 */
Jeff Johnson295189b2012-06-20 16:38:30 -07005013 req->n_ssids = 0;
5014 req->n_channels = 0;
5015 req->ie = 0;
5016
Jeff Johnson295189b2012-06-20 16:38:30 -07005017 pAdapter->request = NULL;
Jeff Johnsone7245742012-09-05 17:12:55 -07005018 /* Scan is no longer pending */
5019 pScanInfo->mScanPending = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07005020
Madan Mohan Koyyalamudib764bf82012-10-11 16:38:51 -07005021 /*
5022 * cfg80211_scan_done informing NL80211 about completion
5023 * of scanning
5024 */
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +05305025 if (status == eCSR_SCAN_ABORT || status == eCSR_SCAN_FAILURE)
5026 {
5027 aborted = true;
5028 }
5029 cfg80211_scan_done(req, aborted);
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -08005030 complete(&pScanInfo->abortscan_event_var);
Jeff Johnson295189b2012-06-20 16:38:30 -07005031
Jeff Johnsone7245742012-09-05 17:12:55 -07005032allow_suspend:
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07005033 /* release the wake lock at the end of the scan*/
5034 hdd_allow_suspend();
Jeff Johnsone7245742012-09-05 17:12:55 -07005035
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -07005036 /* Acquire wakelock to handle the case where APP's tries to suspend
5037 * immediatly after the driver gets connect request(i.e after scan)
5038 * from supplicant, this result in app's is suspending and not able
5039 * to process the connect request to AP */
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +05305040 hdd_prevent_suspend_timeout(1000);
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -07005041
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07005042#ifdef FEATURE_WLAN_TDLS
5043 wlan_hdd_tdls_scan_done_callback(pAdapter);
5044#endif
5045
Jeff Johnson295189b2012-06-20 16:38:30 -07005046 EXIT();
5047 return 0;
5048}
5049
5050/*
Rashmi Ramannab1429032014-04-26 14:59:09 +05305051 * FUNCTION: hdd_isConnectionInProgress
5052 * Go through each adapter and check if Connection is in progress
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08005053 *
5054 */
Rashmi Ramannab1429032014-04-26 14:59:09 +05305055v_BOOL_t hdd_isConnectionInProgress( hdd_context_t *pHddCtx )
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08005056{
5057 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
5058 hdd_station_ctx_t *pHddStaCtx = NULL;
5059 hdd_adapter_t *pAdapter = NULL;
5060 VOS_STATUS status = 0;
5061 v_U8_t staId = 0;
5062 v_U8_t *staMac = NULL;
5063
c_hpothu9b781ba2013-12-30 20:57:45 +05305064 if (TRUE == pHddCtx->btCoexModeSet)
5065 {
5066 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Rashmi Ramannab1429032014-04-26 14:59:09 +05305067 FL("BTCoex Mode operation in progress"));
5068 return VOS_TRUE;
c_hpothu9b781ba2013-12-30 20:57:45 +05305069 }
5070
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08005071 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
5072
5073 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
5074 {
5075 pAdapter = pAdapterNode->pAdapter;
5076
5077 if( pAdapter )
5078 {
5079 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05305080 "%s: Adapter with device mode %s (%d) exists",
5081 __func__, hdd_device_modetoString(pAdapter->device_mode),
5082 pAdapter->device_mode);
Rashmi Ramannab1429032014-04-26 14:59:09 +05305083 if (((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
5084 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
5085 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode)) &&
5086 (eConnectionState_Connecting ==
5087 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
5088 {
5089 hddLog(VOS_TRACE_LEVEL_ERROR,
5090 "%s: %p(%d) Connection is in progress", __func__,
5091 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
5092 return VOS_TRUE;
5093 }
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08005094 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05305095 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
5096 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08005097 {
5098 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
5099 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05305100 (VOS_FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08005101 {
5102 staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]);
5103 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain24bafea2013-11-15 15:10:03 -08005104 "%s: client " MAC_ADDRESS_STR
5105 " is in the middle of WPS/EAPOL exchange.", __func__,
5106 MAC_ADDR_ARRAY(staMac));
Rashmi Ramannab1429032014-04-26 14:59:09 +05305107 return VOS_TRUE;
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08005108 }
5109 }
5110 else if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) ||
5111 (WLAN_HDD_P2P_GO == pAdapter->device_mode))
5112 {
5113 for (staId = 0; staId < WLAN_MAX_STA_COUNT; staId++)
5114 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305115 if ((pAdapter->aStaInfo[staId].isUsed) &&
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08005116 (WLANTL_STA_CONNECTED == pAdapter->aStaInfo[staId].tlSTAState))
5117 {
5118 staMac = (v_U8_t *) &(pAdapter->aStaInfo[staId].macAddrSTA.bytes[0]);
5119
5120 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain24bafea2013-11-15 15:10:03 -08005121 "%s: client " MAC_ADDRESS_STR " of SoftAP/P2P-GO is in the "
5122 "middle of WPS/EAPOL exchange.", __func__,
5123 MAC_ADDR_ARRAY(staMac));
Rashmi Ramannab1429032014-04-26 14:59:09 +05305124 return VOS_TRUE;
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08005125 }
5126 }
5127 }
5128 }
5129 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
5130 pAdapterNode = pNext;
5131 }
Rashmi Ramannab1429032014-04-26 14:59:09 +05305132 return VOS_FALSE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305133}
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08005134
5135/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +05305136 * FUNCTION: __wlan_hdd_cfg80211_scan
Jeff Johnson295189b2012-06-20 16:38:30 -07005137 * this scan respond to scan trigger and update cfg80211 scan database
5138 * later, scan dump command can be used to recieve scan results
5139 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +05305140int __wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -08005141#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
5142 struct net_device *dev,
5143#endif
5144 struct cfg80211_scan_request *request)
5145{
Siddharth Bhal0c162d02014-05-06 19:50:42 +05305146 hdd_adapter_t *pAdapter = NULL;
5147 hdd_context_t *pHddCtx = NULL;
5148 hdd_wext_state_t *pwextBuf = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305149 hdd_config_t *cfg_param = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07005150 tCsrScanRequest scanRequest;
5151 tANI_U8 *channelList = NULL, i;
5152 v_U32_t scanId = 0;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305153 int status;
5154 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07005155 v_U8_t* pP2pIe = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07005156
Siddharth Bhal0c162d02014-05-06 19:50:42 +05305157#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
5158 struct net_device *dev = NULL;
5159 if (NULL == request)
5160 {
5161 hddLog(VOS_TRACE_LEVEL_ERROR,
5162 "%s: scan req param null", __func__);
5163 return -EINVAL;
5164 }
5165 dev = request->wdev->netdev;
5166#endif
5167
5168 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
5169 pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
5170 pwextBuf = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
5171
Jeff Johnson295189b2012-06-20 16:38:30 -07005172 ENTER();
5173
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05305174
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05305175 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
5176 __func__, hdd_device_modetoString(pAdapter->device_mode),
5177 pAdapter->device_mode);
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08005178
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305179 status = wlan_hdd_validate_context(pHddCtx);
5180
5181 if (0 != status)
5182 {
5183 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5184 "%s: HDD context is not valid", __func__);
5185 return status;
5186 }
5187
Siddharth Bhal0c162d02014-05-06 19:50:42 +05305188 if (NULL == pwextBuf)
5189 {
5190 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: invalid WEXT state\n",
5191 __func__);
5192 return -EIO;
5193 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305194 cfg_param = pHddCtx->cfg_ini;
5195 pScanInfo = &pHddCtx->scan_info;
5196
Jeff Johnson295189b2012-06-20 16:38:30 -07005197#ifdef WLAN_BTAMP_FEATURE
5198 //Scan not supported when AMP traffic is on.
Gopichand Nakkala681989c2013-03-06 22:27:48 -08005199 if (VOS_TRUE == WLANBAP_AmpSessionOn())
Jeff Johnson295189b2012-06-20 16:38:30 -07005200 {
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08005201 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07005202 "%s: No scanning when AMP is on", __func__);
5203 return -EOPNOTSUPP;
5204 }
5205#endif
5206 //Scan on any other interface is not supported.
Gopichand Nakkala681989c2013-03-06 22:27:48 -08005207 if (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07005208 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -08005209 hddLog(VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05305210 "%s: Not scanning on device_mode = %s (%d)",
5211 __func__, hdd_device_modetoString(pAdapter->device_mode),
5212 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07005213 return -EOPNOTSUPP;
5214 }
5215
5216 if (TRUE == pScanInfo->mScanPending)
5217 {
Kiet Lamac06e2c2013-10-23 16:25:07 +05305218 if ( MAX_PENDING_LOG > pScanInfo->mScanPendingCounter++ )
5219 {
5220 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: mScanPending is TRUE", __func__);
5221 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08005222 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -07005223 }
5224
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305225 //Don't Allow Scan and return busy if Remain On
Jeff Johnson32d95a32012-09-10 13:15:23 -07005226 //Channel and action frame is pending
5227 //Otherwise Cancel Remain On Channel and allow Scan
5228 //If no action frame pending
Gopichand Nakkala681989c2013-03-06 22:27:48 -08005229 if (0 != wlan_hdd_check_remain_on_channel(pAdapter))
Jeff Johnson32d95a32012-09-10 13:15:23 -07005230 {
Kiet Lamac06e2c2013-10-23 16:25:07 +05305231 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Remain On Channel Pending", __func__);
Jeff Johnson32d95a32012-09-10 13:15:23 -07005232 return -EBUSY;
5233 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08005234#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07005235 /* if tdls disagree scan right now, return immediately.
5236 tdls will schedule the scan when scan is allowed. (return SUCCESS)
5237 or will reject the scan if any TDLS is in progress. (return -EBUSY)
5238 */
5239 status = wlan_hdd_tdls_scan_callback (pAdapter,
5240 wiphy,
5241#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
5242 dev,
Gopichand Nakkalac3c42b92013-03-20 19:42:34 -07005243#endif
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07005244 request);
5245 if(status <= 0)
5246 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05305247 if(!status)
5248 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS in progress."
5249 "scan rejected %d", __func__, status);
5250 else
5251 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS teardown is ongoing %d",
5252 __func__, status);
5253
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07005254 return status;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08005255 }
5256#endif
Jeff Johnson32d95a32012-09-10 13:15:23 -07005257
Jeff Johnson295189b2012-06-20 16:38:30 -07005258 if (mutex_lock_interruptible(&pHddCtx->tmInfo.tmOperationLock))
5259 {
5260 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_ERROR,
Jeff Johnson1250df42012-12-10 14:31:52 -08005261 "%s: Acquire lock fail", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005262 return -EAGAIN;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305263 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005264 if (TRUE == pHddCtx->tmInfo.tmAction.enterImps)
5265 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05305266 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07005267 "%s: MAX TM Level Scan not allowed", __func__);
5268 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305269 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -07005270 }
5271 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
5272
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08005273 /* Check if scan is allowed at this point of time.
5274 */
Rashmi Ramannab1429032014-04-26 14:59:09 +05305275 if (hdd_isConnectionInProgress(pHddCtx))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08005276 {
5277 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Scan not allowed", __func__);
5278 return -EBUSY;
5279 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305280
Jeff Johnson295189b2012-06-20 16:38:30 -07005281 vos_mem_zero( &scanRequest, sizeof(scanRequest));
5282
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05305283 hddLog(VOS_TRACE_LEVEL_INFO, "scan request for ssid = %d",
5284 (int)request->n_ssids);
5285
5286 /* Even though supplicant doesn't provide any SSIDs, n_ssids is set to 1.
5287 * Becasue of this, driver is assuming that this is not wildcard scan and so
5288 * is not aging out the scan results.
5289 */
5290 if (request->ssids && '\0' == request->ssids->ssid[0])
Jeff Johnson295189b2012-06-20 16:38:30 -07005291 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05305292 request->n_ssids = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07005293 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05305294
5295 if ((request->ssids) && (0 < request->n_ssids))
5296 {
5297 tCsrSSIDInfo *SsidInfo;
5298 int j;
5299 scanRequest.SSIDs.numOfSSIDs = request->n_ssids;
5300 /* Allocate num_ssid tCsrSSIDInfo structure */
5301 SsidInfo = scanRequest.SSIDs.SSIDList =
5302 ( tCsrSSIDInfo *)vos_mem_malloc(
5303 request->n_ssids*sizeof(tCsrSSIDInfo));
5304
5305 if(NULL == scanRequest.SSIDs.SSIDList)
5306 {
5307 hddLog(VOS_TRACE_LEVEL_ERROR,
5308 "%s: memory alloc failed SSIDInfo buffer", __func__);
5309 return -ENOMEM;
5310 }
5311
5312 /* copy all the ssid's and their length */
5313 for(j = 0; j < request->n_ssids; j++, SsidInfo++)
5314 {
5315 /* get the ssid length */
5316 SsidInfo->SSID.length = request->ssids[j].ssid_len;
5317 vos_mem_copy(SsidInfo->SSID.ssId, &request->ssids[j].ssid[0],
5318 SsidInfo->SSID.length);
5319 SsidInfo->SSID.ssId[SsidInfo->SSID.length] = '\0';
5320 hddLog(VOS_TRACE_LEVEL_INFO, "SSID number %d: %s",
5321 j, SsidInfo->SSID.ssId);
5322 }
5323 /* set the scan type to active */
5324 scanRequest.scanType = eSIR_ACTIVE_SCAN;
5325 }
5326 else if(WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -07005327 {
Siddharth Bhal0c162d02014-05-06 19:50:42 +05305328 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
5329 TRACE_CODE_HDD_CFG80211_SCAN,
5330 pAdapter->sessionId, 0));
Jeff Johnson295189b2012-06-20 16:38:30 -07005331 /* set the scan type to active */
5332 scanRequest.scanType = eSIR_ACTIVE_SCAN;
Jeff Johnson295189b2012-06-20 16:38:30 -07005333 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05305334 else
5335 {
5336 /*Set the scan type to default type, in this case it is ACTIVE*/
5337 scanRequest.scanType = pScanInfo->scan_mode;
5338 }
5339 scanRequest.minChnTime = cfg_param->nActiveMinChnTime;
5340 scanRequest.maxChnTime = cfg_param->nActiveMaxChnTime;
Jeff Johnson295189b2012-06-20 16:38:30 -07005341
5342 /* set BSSType to default type */
5343 scanRequest.BSSType = eCSR_BSS_TYPE_ANY;
5344
5345 /*TODO: scan the requested channels only*/
5346
5347 /*Right now scanning all the channels */
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05305348 if (MAX_CHANNEL < request->n_channels)
Jeff Johnson295189b2012-06-20 16:38:30 -07005349 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05305350 hddLog(VOS_TRACE_LEVEL_WARN,
5351 "No of Scan Channels exceeded limit: %d", request->n_channels);
5352 request->n_channels = MAX_CHANNEL;
5353 }
5354
5355 hddLog(VOS_TRACE_LEVEL_INFO,
5356 "No of Scan Channels: %d", request->n_channels);
5357
5358
5359 if( request->n_channels )
5360 {
5361 char chList [(request->n_channels*5)+1];
5362 int len;
5363 channelList = vos_mem_malloc( request->n_channels );
5364 if( NULL == channelList )
c_hpothu53512302014-04-15 18:49:53 +05305365 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05305366 hddLog(VOS_TRACE_LEVEL_ERROR,
5367 "%s: memory alloc failed channelList", __func__);
5368 status = -ENOMEM;
5369 goto free_mem;
c_hpothu53512302014-04-15 18:49:53 +05305370 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05305371
5372 for( i = 0, len = 0; i < request->n_channels ; i++ )
5373 {
5374 channelList[i] = request->channels[i]->hw_value;
5375 len += snprintf(chList+len, 5, "%d ", channelList[i]);
5376 }
5377
Nirav Shah20ac06f2013-12-12 18:14:06 +05305378 hddLog(VOS_TRACE_LEVEL_INFO,
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05305379 "Channel-List: %s ", chList);
5380 }
c_hpothu53512302014-04-15 18:49:53 +05305381
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05305382 scanRequest.ChannelInfo.numOfChannels = request->n_channels;
5383 scanRequest.ChannelInfo.ChannelList = channelList;
5384
5385 /* set requestType to full scan */
5386 scanRequest.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
5387
5388 /* Flush the scan results(only p2p beacons) for STA scan and P2P
5389 * search (Flush on both full scan and social scan but not on single
5390 * channel scan).P2P search happens on 3 social channels (1, 6, 11)
5391 */
5392
5393 /* Supplicant does single channel scan after 8-way handshake
5394 * and in that case driver shoudnt flush scan results. If
5395 * driver flushes the scan results here and unfortunately if
5396 * the AP doesnt respond to our probe req then association
5397 * fails which is not desired
5398 */
5399
5400 if( request->n_channels != WLAN_HDD_P2P_SINGLE_CHANNEL_SCAN )
5401 {
5402 hddLog(VOS_TRACE_LEVEL_DEBUG, "Flushing P2P Results");
5403 sme_ScanFlushP2PResult( WLAN_HDD_GET_HAL_CTX(pAdapter),
5404 pAdapter->sessionId );
5405 }
5406
5407 if( request->ie_len )
5408 {
5409 /* save this for future association (join requires this) */
5410 /*TODO: Array needs to be converted to dynamic allocation,
5411 * as multiple ie.s can be sent in cfg80211_scan_request structure
5412 * CR 597966
5413 */
5414 memset( &pScanInfo->scanAddIE, 0, sizeof(pScanInfo->scanAddIE) );
5415 memcpy( pScanInfo->scanAddIE.addIEdata, request->ie, request->ie_len);
5416 pScanInfo->scanAddIE.length = request->ie_len;
5417
5418 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
5419 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
5420 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -07005421 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05305422 if ( request->ie_len <= SIR_MAC_MAX_IE_LENGTH)
Jeff Johnson295189b2012-06-20 16:38:30 -07005423 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05305424 pwextBuf->roamProfile.nAddIEScanLength = request->ie_len;
5425 memcpy( pwextBuf->roamProfile.addIEScan,
5426 request->ie, request->ie_len);
5427 }
5428 else
5429 {
5430 hddLog(VOS_TRACE_LEVEL_ERROR, "Scan Ie length is invalid:"
5431 "%zu", request->ie_len);
Jeff Johnson295189b2012-06-20 16:38:30 -07005432 }
5433
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05305434 }
5435 scanRequest.uIEFieldLen = pScanInfo->scanAddIE.length;
5436 scanRequest.pIEField = pScanInfo->scanAddIE.addIEdata;
5437
5438 pP2pIe = wlan_hdd_get_p2p_ie_ptr((v_U8_t*)request->ie,
5439 request->ie_len);
5440 if (pP2pIe != NULL)
5441 {
5442#ifdef WLAN_FEATURE_P2P_DEBUG
5443 if (((globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED) ||
5444 (globalP2PConnectionStatus == P2P_GO_NEG_PROCESS)) &&
5445 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Nirav Shah20ac06f2013-12-12 18:14:06 +05305446 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05305447 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_1;
5448 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
5449 "Go nego completed to Connection is started");
5450 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
5451 "for 8way Handshake");
Nirav Shah20ac06f2013-12-12 18:14:06 +05305452 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05305453 else if((globalP2PConnectionStatus == P2P_CLIENT_DISCONNECTED_STATE) &&
5454 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -07005455 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05305456 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_2;
5457 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
5458 "Disconnected state to Connection is started");
5459 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
5460 "for 4way Handshake");
5461 }
5462#endif
5463
5464 /* no_cck will be set during p2p find to disable 11b rates */
5465 if(TRUE == request->no_cck)
5466 {
5467 hddLog(VOS_TRACE_LEVEL_INFO,
5468 "%s: This is a P2P Search", __func__);
5469 scanRequest.p2pSearch = 1;
5470
5471 if( request->n_channels == WLAN_HDD_P2P_SOCIAL_CHANNELS )
Agarwal Ashish4f616132013-12-30 23:32:50 +05305472 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05305473 /* set requestType to P2P Discovery */
5474 scanRequest.requestType = eCSR_SCAN_P2P_DISCOVERY;
5475 }
5476
5477 /*
5478 Skip Dfs Channel in case of P2P Search
5479 if it is set in ini file
5480 */
5481 if(cfg_param->skipDfsChnlInP2pSearch)
5482 {
5483 scanRequest.skipDfsChnlInP2pSearch = 1;
Agarwal Ashish4f616132013-12-30 23:32:50 +05305484 }
5485 else
5486 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05305487 scanRequest.skipDfsChnlInP2pSearch = 0;
Agarwal Ashish4f616132013-12-30 23:32:50 +05305488 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005489
Agarwal Ashish4f616132013-12-30 23:32:50 +05305490 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005491 }
5492 }
5493
5494 INIT_COMPLETION(pScanInfo->scan_req_completion_event);
5495
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07005496 /* acquire the wakelock to avoid the apps suspend during the scan. To
5497 * address the following issues.
5498 * 1) Disconnected scenario: we are not allowing the suspend as WLAN is not in
5499 * BMPS/IMPS this result in android trying to suspend aggressively and backing off
5500 * for long time, this result in apps running at full power for long time.
5501 * 2) Connected scenario: If we allow the suspend during the scan, RIVA will
5502 * be stuck in full power because of resume BMPS
5503 */
5504 hdd_prevent_suspend();
Jeff Johnsone7245742012-09-05 17:12:55 -07005505
Nirav Shah20ac06f2013-12-12 18:14:06 +05305506 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
5507 "requestType %d, scanType %d, minChnTime %d, maxChnTime %d,"
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05305508 "p2pSearch %d, skipDfsChnlInP2pSearch %d",
5509 scanRequest.requestType, scanRequest.scanType,
5510 scanRequest.minChnTime, scanRequest.maxChnTime,
Nirav Shah20ac06f2013-12-12 18:14:06 +05305511 scanRequest.p2pSearch, scanRequest.skipDfsChnlInP2pSearch);
5512
Jeff Johnsone7245742012-09-05 17:12:55 -07005513 status = sme_ScanRequest( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07005514 pAdapter->sessionId, &scanRequest, &scanId,
5515 &hdd_cfg80211_scan_done_callback, dev );
Jeff Johnsone7245742012-09-05 17:12:55 -07005516
Jeff Johnson295189b2012-06-20 16:38:30 -07005517 if (eHAL_STATUS_SUCCESS != status)
5518 {
5519 hddLog(VOS_TRACE_LEVEL_ERROR,
5520 "%s: sme_ScanRequest returned error %d", __func__, status);
5521 complete(&pScanInfo->scan_req_completion_event);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -07005522 if(eHAL_STATUS_RESOURCES == status)
5523 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05305524 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: HO is in progress."
5525 "So defer the scan by informing busy",__func__);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -07005526 status = -EBUSY;
5527 } else {
5528 status = -EIO;
5529 }
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07005530 hdd_allow_suspend();
Jeff Johnson295189b2012-06-20 16:38:30 -07005531 goto free_mem;
5532 }
5533
5534 pScanInfo->mScanPending = TRUE;
5535 pAdapter->request = request;
5536 pScanInfo->scanId = scanId;
5537
5538 complete(&pScanInfo->scan_req_completion_event);
5539
5540free_mem:
5541 if( scanRequest.SSIDs.SSIDList )
5542 {
5543 vos_mem_free(scanRequest.SSIDs.SSIDList);
5544 }
5545
5546 if( channelList )
5547 vos_mem_free( channelList );
5548
5549 EXIT();
5550
5551 return status;
5552}
5553
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +05305554int wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
5555#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
5556 struct net_device *dev,
5557#endif
5558 struct cfg80211_scan_request *request)
5559{
5560 int ret;
5561
5562 vos_ssr_protect(__func__);
5563 ret = __wlan_hdd_cfg80211_scan(wiphy,
5564#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
5565 dev,
5566#endif
5567 request);
5568 vos_ssr_unprotect(__func__);
5569
5570 return ret;
5571}
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07005572
5573void hdd_select_cbmode( hdd_adapter_t *pAdapter,v_U8_t operationChannel)
5574{
5575 v_U8_t iniDot11Mode =
5576 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->dot11Mode;
5577 eHddDot11Mode hddDot11Mode = iniDot11Mode;
5578
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +05305579 hddLog(LOG1, FL("Channel Bonding Mode Selected is %u"),
5580 iniDot11Mode);
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07005581 switch ( iniDot11Mode )
5582 {
5583 case eHDD_DOT11_MODE_AUTO:
5584 case eHDD_DOT11_MODE_11ac:
5585 case eHDD_DOT11_MODE_11ac_ONLY:
5586#ifdef WLAN_FEATURE_11AC
5587 hddDot11Mode = eHDD_DOT11_MODE_11ac;
5588#else
5589 hddDot11Mode = eHDD_DOT11_MODE_11n;
5590#endif
5591 break;
5592 case eHDD_DOT11_MODE_11n:
5593 case eHDD_DOT11_MODE_11n_ONLY:
5594 hddDot11Mode = eHDD_DOT11_MODE_11n;
5595 break;
5596 default:
5597 hddDot11Mode = iniDot11Mode;
5598 break;
5599 }
5600 /* This call decides required channel bonding mode */
5601 sme_SelectCBMode((WLAN_HDD_GET_CTX(pAdapter)->hHal),
5602 hdd_cfg_xlate_to_csr_phy_mode(hddDot11Mode),
5603 operationChannel);
5604}
5605
Jeff Johnson295189b2012-06-20 16:38:30 -07005606/*
5607 * FUNCTION: wlan_hdd_cfg80211_connect_start
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305608 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -07005609 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305610int wlan_hdd_cfg80211_connect_start( hdd_adapter_t *pAdapter,
Jeff Johnson32d95a32012-09-10 13:15:23 -07005611 const u8 *ssid, size_t ssid_len, const u8 *bssid, u8 operatingChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -07005612{
5613 int status = 0;
5614 hdd_wext_state_t *pWextState;
Yue Mae36e3552014-03-05 17:06:20 -08005615 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07005616 v_U32_t roamId;
5617 tCsrRoamProfile *pRoamProfile;
Jeff Johnson295189b2012-06-20 16:38:30 -07005618 eCsrAuthType RSNAuthType;
5619
5620 ENTER();
5621
5622 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Yue Mae36e3552014-03-05 17:06:20 -08005623 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
5624
5625 status = wlan_hdd_validate_context(pHddCtx);
5626 if (status)
5627 {
5628 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5629 "%s: HDD context is not valid!", __func__);
5630 return status;
5631 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305632
Jeff Johnson295189b2012-06-20 16:38:30 -07005633 if (SIR_MAC_MAX_SSID_LENGTH < ssid_len)
5634 {
5635 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wrong SSID len", __func__);
5636 return -EINVAL;
5637 }
5638
5639 pRoamProfile = &pWextState->roamProfile;
5640
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305641 if (pRoamProfile)
Jeff Johnson295189b2012-06-20 16:38:30 -07005642 {
Jeff Johnsone7245742012-09-05 17:12:55 -07005643 hdd_station_ctx_t *pHddStaCtx;
5644 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07005645
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305646 if (HDD_WMM_USER_MODE_NO_QOS ==
Jeff Johnson295189b2012-06-20 16:38:30 -07005647 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->WmmMode)
5648 {
5649 /*QoS not enabled in cfg file*/
5650 pRoamProfile->uapsd_mask = 0;
5651 }
5652 else
5653 {
5654 /*QoS enabled, update uapsd mask from cfg file*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305655 pRoamProfile->uapsd_mask =
Jeff Johnson295189b2012-06-20 16:38:30 -07005656 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask;
5657 }
5658
5659 pRoamProfile->SSIDs.numOfSSIDs = 1;
5660 pRoamProfile->SSIDs.SSIDList->SSID.length = ssid_len;
5661 vos_mem_zero(pRoamProfile->SSIDs.SSIDList->SSID.ssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305662 sizeof(pRoamProfile->SSIDs.SSIDList->SSID.ssId));
Jeff Johnson295189b2012-06-20 16:38:30 -07005663 vos_mem_copy((void *)(pRoamProfile->SSIDs.SSIDList->SSID.ssId),
5664 ssid, ssid_len);
5665
5666 if (bssid)
5667 {
5668 pRoamProfile->BSSIDs.numOfBSSIDs = 1;
5669 vos_mem_copy((void *)(pRoamProfile->BSSIDs.bssid), bssid,
5670 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305671 /* Save BSSID in seperate variable as well, as RoamProfile
5672 BSSID is getting zeroed out in the association process. And in
Jeff Johnson295189b2012-06-20 16:38:30 -07005673 case of join failure we should send valid BSSID to supplicant
5674 */
5675 vos_mem_copy((void *)(pWextState->req_bssId), bssid,
5676 WNI_CFG_BSSID_LEN);
5677 }
Dhanashri Atre51981c62013-06-13 11:47:57 -07005678 else
5679 {
5680 vos_mem_zero((void *)(pRoamProfile->BSSIDs.bssid),WNI_CFG_BSSID_LEN);
5681 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005682
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +05305683 hddLog(LOG1, FL("Connect to SSID: %s opertating Channel: %u"),
5684 pRoamProfile->SSIDs.SSIDList->SSID.ssId, operatingChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -07005685 if ((IW_AUTH_WPA_VERSION_WPA == pWextState->wpaVersion) ||
5686 (IW_AUTH_WPA_VERSION_WPA2 == pWextState->wpaVersion))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305687 {
Jeff Johnson295189b2012-06-20 16:38:30 -07005688 /*set gen ie*/
5689 hdd_SetGENIEToCsr(pAdapter, &RSNAuthType);
5690 /*set auth*/
5691 hdd_set_csr_auth_type(pAdapter, RSNAuthType);
5692 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005693#ifdef FEATURE_WLAN_WAPI
5694 if (pAdapter->wapi_info.nWapiMode)
5695 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005696 hddLog(LOG1, "%s: Setting WAPI AUTH Type and Encryption Mode values", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005697 switch (pAdapter->wapi_info.wapiAuthMode)
5698 {
5699 case WAPI_AUTH_MODE_PSK:
5700 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005701 hddLog(LOG1, "%s: WAPI AUTH TYPE: PSK: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07005702 pAdapter->wapi_info.wapiAuthMode);
5703 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_PSK;
5704 break;
5705 }
5706 case WAPI_AUTH_MODE_CERT:
5707 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005708 hddLog(LOG1, "%s: WAPI AUTH TYPE: CERT: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07005709 pAdapter->wapi_info.wapiAuthMode);
5710 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE;
5711 break;
5712 }
5713 } // End of switch
5714 if ( pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_PSK ||
5715 pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_CERT)
5716 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005717 hddLog(LOG1, "%s: WAPI PAIRWISE/GROUP ENCRYPTION: WPI", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005718 pRoamProfile->AuthType.numEntries = 1;
5719 pRoamProfile->EncryptionType.numEntries = 1;
5720 pRoamProfile->EncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
5721 pRoamProfile->mcEncryptionType.numEntries = 1;
5722 pRoamProfile->mcEncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
5723 }
5724 }
5725#endif /* FEATURE_WLAN_WAPI */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05305726#ifdef WLAN_FEATURE_GTK_OFFLOAD
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05305727 /* Initializing gtkOffloadReqParams */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05305728 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
5729 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
5730 {
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05305731 memset(&pHddStaCtx->gtkOffloadReqParams, 0,
5732 sizeof (tSirGtkOffloadParams));
5733 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_DISABLE;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05305734 }
5735#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005736 pRoamProfile->csrPersona = pAdapter->device_mode;
5737
Jeff Johnson32d95a32012-09-10 13:15:23 -07005738 if( operatingChannel )
5739 {
5740 pRoamProfile->ChannelInfo.ChannelList = &operatingChannel;
5741 pRoamProfile->ChannelInfo.numOfChannels = 1;
5742 }
Chet Lanctot186b5732013-03-18 10:26:30 -07005743 else
5744 {
5745 pRoamProfile->ChannelInfo.ChannelList = NULL;
5746 pRoamProfile->ChannelInfo.numOfChannels = 0;
5747 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07005748 if ( (WLAN_HDD_IBSS == pAdapter->device_mode) && operatingChannel)
5749 {
5750 hdd_select_cbmode(pAdapter,operatingChannel);
5751 }
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +05305752
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08005753 /* change conn_state to connecting before sme_RoamConnect(), because sme_RoamConnect()
5754 * has a direct path to call hdd_smeRoamCallback(), which will change the conn_state
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305755 * If direct path, conn_state will be accordingly changed to NotConnected or Associated
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08005756 * by either hdd_AssociationCompletionHandler() or hdd_DisConnectHandler() in sme_RoamCallback()
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -08005757 * if sme_RomConnect is to be queued, Connecting state will remain until it is completed.
5758 */
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05305759 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
5760 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode)
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -08005761 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
5762 eConnectionState_Connecting);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305763
5764 status = sme_RoamConnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07005765 pAdapter->sessionId, pRoamProfile, &roamId);
5766
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05305767 if ((eHAL_STATUS_SUCCESS != status) &&
5768 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
5769 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +05305770
5771 {
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08005772 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: sme_RoamConnect (session %d) failed with "
5773 "status %d. -> NotConnected", __func__, pAdapter->sessionId, status);
5774 /* change back to NotAssociated */
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +05305775 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08005776 eConnectionState_NotConnected);
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +05305777 }
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -08005778
5779 pRoamProfile->ChannelInfo.ChannelList = NULL;
5780 pRoamProfile->ChannelInfo.numOfChannels = 0;
5781
Jeff Johnson295189b2012-06-20 16:38:30 -07005782 }
5783 else
5784 {
5785 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid Roam profile", __func__);
5786 return -EINVAL;
5787 }
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08005788 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07005789 return status;
5790}
5791
5792/*
5793 * FUNCTION: wlan_hdd_set_cfg80211_auth_type
5794 * This function is used to set the authentication type (OPEN/SHARED).
5795 *
5796 */
5797static int wlan_hdd_cfg80211_set_auth_type(hdd_adapter_t *pAdapter,
5798 enum nl80211_auth_type auth_type)
5799{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305800 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07005801 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
5802
5803 ENTER();
5804
5805 /*set authentication type*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305806 switch (auth_type)
Jeff Johnson295189b2012-06-20 16:38:30 -07005807 {
Jeff Johnson295189b2012-06-20 16:38:30 -07005808 case NL80211_AUTHTYPE_AUTOMATIC:
Gopichand Nakkala29149562013-05-10 21:43:41 +05305809 hddLog(VOS_TRACE_LEVEL_INFO,
5810 "%s: set authentication type to AUTOSWITCH", __func__);
5811 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_AUTOSWITCH;
5812 break;
5813
5814 case NL80211_AUTHTYPE_OPEN_SYSTEM:
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07005815#ifdef WLAN_FEATURE_VOWIFI_11R
5816 case NL80211_AUTHTYPE_FT:
5817#endif /* WLAN_FEATURE_VOWIFI_11R */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305818 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -07005819 "%s: set authentication type to OPEN", __func__);
5820 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
5821 break;
5822
5823 case NL80211_AUTHTYPE_SHARED_KEY:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305824 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -07005825 "%s: set authentication type to SHARED", __func__);
5826 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_SHARED_KEY;
5827 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005828#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -07005829 case NL80211_AUTHTYPE_NETWORK_EAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305830 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -07005831 "%s: set authentication type to CCKM WPA", __func__);
5832 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_CCKM_WPA;//eCSR_AUTH_TYPE_CCKM_RSN needs to be handled as well if required.
5833 break;
5834#endif
5835
5836
5837 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305838 hddLog(VOS_TRACE_LEVEL_ERROR,
5839 "%s: Unsupported authentication type %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07005840 auth_type);
5841 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_UNKNOWN;
5842 return -EINVAL;
5843 }
5844
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305845 pWextState->roamProfile.AuthType.authType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -07005846 pHddStaCtx->conn_info.authType;
5847 return 0;
5848}
5849
5850/*
5851 * FUNCTION: wlan_hdd_set_akm_suite
5852 * This function is used to set the key mgmt type(PSK/8021x).
5853 *
5854 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305855static int wlan_hdd_set_akm_suite( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07005856 u32 key_mgmt
5857 )
5858{
5859 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
5860 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305861
Jeff Johnson295189b2012-06-20 16:38:30 -07005862 /*set key mgmt type*/
5863 switch(key_mgmt)
5864 {
5865 case WLAN_AKM_SUITE_PSK:
Gopichand Nakkala356fb102013-03-06 12:34:04 +05305866#ifdef WLAN_FEATURE_VOWIFI_11R
5867 case WLAN_AKM_SUITE_FT_PSK:
5868#endif
5869 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to PSK",
Jeff Johnson295189b2012-06-20 16:38:30 -07005870 __func__);
5871 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_PSK;
5872 break;
5873
5874 case WLAN_AKM_SUITE_8021X:
Gopichand Nakkala356fb102013-03-06 12:34:04 +05305875#ifdef WLAN_FEATURE_VOWIFI_11R
5876 case WLAN_AKM_SUITE_FT_8021X:
5877#endif
5878 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to 8021x",
Jeff Johnson295189b2012-06-20 16:38:30 -07005879 __func__);
5880 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
5881 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005882#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -07005883#define WLAN_AKM_SUITE_CCKM 0x00409600 /* Should be in ieee802_11_defs.h */
5884#define IW_AUTH_KEY_MGMT_CCKM 8 /* Should be in linux/wireless.h */
5885 case WLAN_AKM_SUITE_CCKM:
5886 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to CCKM",
5887 __func__);
5888 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_CCKM;
5889 break;
5890#endif
Leela Venkata Kiran Kumar Reddy Chiralae208a832014-04-27 22:34:25 -07005891#ifndef WLAN_AKM_SUITE_OSEN
5892#define WLAN_AKM_SUITE_OSEN 0x506f9a01 /* Should be in ieee802_11_defs.h */
5893 case WLAN_AKM_SUITE_OSEN:
5894 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to OSEN",
5895 __func__);
5896 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
5897 break;
5898#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005899
5900 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305901 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported key mgmt type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07005902 __func__, key_mgmt);
5903 return -EINVAL;
5904
5905 }
5906 return 0;
5907}
5908
5909/*
5910 * FUNCTION: wlan_hdd_cfg80211_set_cipher
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305911 * This function is used to set the encryption type
Jeff Johnson295189b2012-06-20 16:38:30 -07005912 * (NONE/WEP40/WEP104/TKIP/CCMP).
5913 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305914static int wlan_hdd_cfg80211_set_cipher( hdd_adapter_t *pAdapter,
5915 u32 cipher,
Jeff Johnson295189b2012-06-20 16:38:30 -07005916 bool ucast
5917 )
5918{
5919 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305920 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07005921 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
5922
5923 ENTER();
5924
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305925 if (!cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -07005926 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305927 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: received cipher %d - considering none",
Jeff Johnson295189b2012-06-20 16:38:30 -07005928 __func__, cipher);
5929 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
5930 }
5931 else
5932 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305933
Jeff Johnson295189b2012-06-20 16:38:30 -07005934 /*set encryption method*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305935 switch (cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -07005936 {
5937 case IW_AUTH_CIPHER_NONE:
5938 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
5939 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305940
Jeff Johnson295189b2012-06-20 16:38:30 -07005941 case WLAN_CIPHER_SUITE_WEP40:
Gopichand Nakkala29149562013-05-10 21:43:41 +05305942 encryptionType = eCSR_ENCRYPT_TYPE_WEP40;
Jeff Johnson295189b2012-06-20 16:38:30 -07005943 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305944
Jeff Johnson295189b2012-06-20 16:38:30 -07005945 case WLAN_CIPHER_SUITE_WEP104:
Gopichand Nakkala29149562013-05-10 21:43:41 +05305946 encryptionType = eCSR_ENCRYPT_TYPE_WEP104;
Jeff Johnson295189b2012-06-20 16:38:30 -07005947 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305948
Jeff Johnson295189b2012-06-20 16:38:30 -07005949 case WLAN_CIPHER_SUITE_TKIP:
5950 encryptionType = eCSR_ENCRYPT_TYPE_TKIP;
5951 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305952
Jeff Johnson295189b2012-06-20 16:38:30 -07005953 case WLAN_CIPHER_SUITE_CCMP:
5954 encryptionType = eCSR_ENCRYPT_TYPE_AES;
5955 break;
5956#ifdef FEATURE_WLAN_WAPI
5957 case WLAN_CIPHER_SUITE_SMS4:
5958 encryptionType = eCSR_ENCRYPT_TYPE_WPI;
5959 break;
5960#endif
5961
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005962#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -07005963 case WLAN_CIPHER_SUITE_KRK:
5964 encryptionType = eCSR_ENCRYPT_TYPE_KRK;
5965 break;
5966#endif
5967 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305968 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported cipher type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07005969 __func__, cipher);
5970 return -EOPNOTSUPP;
5971 }
5972 }
5973
5974 if (ucast)
5975 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305976 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting unicast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07005977 __func__, encryptionType);
5978 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
5979 pWextState->roamProfile.EncryptionType.numEntries = 1;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305980 pWextState->roamProfile.EncryptionType.encryptionType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -07005981 encryptionType;
5982 }
5983 else
5984 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305985 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting mcast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07005986 __func__, encryptionType);
5987 pHddStaCtx->conn_info.mcEncryptionType = encryptionType;
5988 pWextState->roamProfile.mcEncryptionType.numEntries = 1;
5989 pWextState->roamProfile.mcEncryptionType.encryptionType[0] = encryptionType;
5990 }
5991
5992 return 0;
5993}
5994
5995
5996/*
5997 * FUNCTION: wlan_hdd_cfg80211_set_ie
5998 * This function is used to parse WPA/RSN IE's.
5999 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306000int wlan_hdd_cfg80211_set_ie( hdd_adapter_t *pAdapter,
6001 u8 *ie,
Jeff Johnson295189b2012-06-20 16:38:30 -07006002 size_t ie_len
6003 )
6004{
6005 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
6006 u8 *genie = ie;
6007 v_U16_t remLen = ie_len;
6008#ifdef FEATURE_WLAN_WAPI
6009 v_U32_t akmsuite[MAX_NUM_AKM_SUITES];
6010 u16 *tmp;
6011 v_U16_t akmsuiteCount;
6012 int *akmlist;
6013#endif
6014 ENTER();
6015
6016 /* clear previous assocAddIE */
6017 pWextState->assocAddIE.length = 0;
6018 pWextState->roamProfile.bWPSAssociation = VOS_FALSE;
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -07006019 pWextState->roamProfile.bOSENAssociation = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07006020
6021 while (remLen >= 2)
6022 {
6023 v_U16_t eLen = 0;
6024 v_U8_t elementId;
6025 elementId = *genie++;
6026 eLen = *genie++;
6027 remLen -= 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306028
Arif Hussain6d2a3322013-11-17 19:50:10 -08006029 hddLog(VOS_TRACE_LEVEL_INFO, "%s: IE[0x%X], LEN[%d]",
Jeff Johnson295189b2012-06-20 16:38:30 -07006030 __func__, elementId, eLen);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306031
6032 switch ( elementId )
Jeff Johnson295189b2012-06-20 16:38:30 -07006033 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306034 case DOT11F_EID_WPA:
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07006035 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 -07006036 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306037 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07006038 "%s: Invalid WPA IE", __func__);
6039 return -EINVAL;
6040 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306041 else if (0 == memcmp(&genie[0], "\x00\x50\xf2\x04", 4))
Jeff Johnson295189b2012-06-20 16:38:30 -07006042 {
6043 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306044 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPS IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -07006045 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306046
Jeff Johnson295189b2012-06-20 16:38:30 -07006047 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
6048 {
Jeff Johnson902c9832012-12-10 14:28:09 -08006049 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE. "
6050 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -07006051 VOS_ASSERT(0);
6052 return -ENOMEM;
6053 }
6054 // WSC IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
6055 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
6056 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306057
Jeff Johnson295189b2012-06-20 16:38:30 -07006058 pWextState->roamProfile.bWPSAssociation = VOS_TRUE;
6059 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
6060 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
6061 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306062 else if (0 == memcmp(&genie[0], "\x00\x50\xf2", 3))
6063 {
Jeff Johnson295189b2012-06-20 16:38:30 -07006064 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPA IE (len %d)",__func__, eLen + 2);
6065 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
6066 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2) /*ie_len*/);
6067 pWextState->roamProfile.pWPAReqIE = pWextState->WPARSNIE;
6068 pWextState->roamProfile.nWPAReqIELength = eLen + 2;//ie_len;
6069 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306070 else if ( (0 == memcmp(&genie[0], P2P_OUI_TYPE,
Kiet Lam8da98992013-11-21 15:59:07 +05306071 P2P_OUI_TYPE_SIZE)))
Jeff Johnson295189b2012-06-20 16:38:30 -07006072 {
6073 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306074 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set P2P IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -07006075 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306076
Jeff Johnson295189b2012-06-20 16:38:30 -07006077 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
6078 {
Jeff Johnson902c9832012-12-10 14:28:09 -08006079 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
6080 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -07006081 VOS_ASSERT(0);
6082 return -ENOMEM;
6083 }
6084 // P2P IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
6085 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
6086 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306087
Jeff Johnson295189b2012-06-20 16:38:30 -07006088 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
6089 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
6090 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006091#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306092 else if ( (0 == memcmp(&genie[0], WFD_OUI_TYPE,
6093 WFD_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07006094 /*Consider WFD IE, only for P2P Client */
6095 && (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
6096 {
6097 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306098 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WFD IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -07006099 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306100
Jeff Johnson295189b2012-06-20 16:38:30 -07006101 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
6102 {
Jeff Johnson902c9832012-12-10 14:28:09 -08006103 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
6104 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -07006105 VOS_ASSERT(0);
6106 return -ENOMEM;
6107 }
6108 // WFD IE is saved to Additional IE ; it should be accumulated to handle
6109 // WPS IE + P2P IE + WFD IE
6110 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
6111 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306112
Jeff Johnson295189b2012-06-20 16:38:30 -07006113 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
6114 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
6115 }
6116#endif
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07006117 /* Appending HS 2.0 Indication Element in Assiciation Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306118 else if ( (0 == memcmp(&genie[0], HS20_OUI_TYPE,
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07006119 HS20_OUI_TYPE_SIZE)) )
6120 {
6121 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306122 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set HS20 IE(len %d)",
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07006123 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07006124
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07006125 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
6126 {
Jeff Johnson902c9832012-12-10 14:28:09 -08006127 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
6128 "Need bigger buffer space");
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07006129 VOS_ASSERT(0);
6130 return -ENOMEM;
6131 }
6132 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
6133 pWextState->assocAddIE.length += eLen + 2;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07006134
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07006135 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
6136 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
6137 }
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -07006138 /* Appending OSEN Information Element in Assiciation Request */
6139 else if ( (0 == memcmp(&genie[0], OSEN_OUI_TYPE,
6140 OSEN_OUI_TYPE_SIZE)) )
6141 {
6142 v_U16_t curAddIELen = pWextState->assocAddIE.length;
6143 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set OSEN IE(len %d)",
6144 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07006145
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -07006146 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
6147 {
6148 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
6149 "Need bigger buffer space");
6150 VOS_ASSERT(0);
6151 return -ENOMEM;
6152 }
6153 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
6154 pWextState->assocAddIE.length += eLen + 2;
6155
6156 pWextState->roamProfile.bOSENAssociation = VOS_TRUE;
6157 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
6158 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
6159 }
6160
6161 break;
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -07006162 if (WLAN_HDD_IBSS == pAdapter->device_mode) {
6163
6164 /* populating as ADDIE in beacon frames */
6165 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
6166 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, genie - 2, eLen + 2,
6167 NULL, eANI_BOOLEAN_FALSE)== eHAL_STATUS_SUCCESS)
6168 {
6169 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
6170 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
6171 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
6172 {
6173 hddLog(LOGE,
6174 "Coldn't pass "
6175 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
6176 }
6177 }/* ccmCfgSetStr(,WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, , )*/
6178 else
6179 hddLog(LOGE,
6180 "Could not pass on "
6181 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
6182
6183 /* IBSS mode doesn't contain params->proberesp_ies still
6184 beaconIE's need to be populated in probe response frames */
6185 if ( (NULL != (genie - 2)) && (0 != eLen + 2) )
6186 {
6187 u16 rem_probe_resp_ie_len = eLen + 2;
6188 u8 probe_rsp_ie_len[3] = {0};
6189 u8 counter = 0;
6190
6191 /* Check Probe Resp Length if it is greater then 255 then
6192 Store Probe Rsp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1
6193 & WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are
6194 not able Store More then 255 bytes into One Variable */
6195
6196 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
6197 {
6198 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
6199 {
6200 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
6201 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
6202 }
6203 else
6204 {
6205 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
6206 rem_probe_resp_ie_len = 0;
6207 }
6208 }
6209
6210 rem_probe_resp_ie_len = 0;
6211
6212 if (probe_rsp_ie_len[0] > 0)
6213 {
6214 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
6215 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
6216 (tANI_U8*)(genie - 2),
6217 probe_rsp_ie_len[0], NULL,
6218 eANI_BOOLEAN_FALSE)
6219 == eHAL_STATUS_FAILURE)
6220 {
6221 hddLog(LOGE,
6222 "Could not pass"
6223 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
6224 }
6225 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
6226 }
6227
6228 if (probe_rsp_ie_len[1] > 0)
6229 {
6230 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
6231 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
6232 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
6233 probe_rsp_ie_len[1], NULL,
6234 eANI_BOOLEAN_FALSE)
6235 == eHAL_STATUS_FAILURE)
6236 {
6237 hddLog(LOGE,
6238 "Could not pass"
6239 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
6240 }
6241 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
6242 }
6243
6244 if (probe_rsp_ie_len[2] > 0)
6245 {
6246 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
6247 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
6248 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
6249 probe_rsp_ie_len[2], NULL,
6250 eANI_BOOLEAN_FALSE)
6251 == eHAL_STATUS_FAILURE)
6252 {
6253 hddLog(LOGE,
6254 "Could not pass"
6255 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
6256 }
6257 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
6258 }
6259
6260 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
6261 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
6262 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
6263 {
6264 hddLog(LOGE,
6265 "Could not pass"
6266 "on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
6267 }
6268 }
6269 else
6270 {
6271 // Reset WNI_CFG_PROBE_RSP Flags
6272 wlan_hdd_reset_prob_rspies(pAdapter);
6273
6274 hddLog(VOS_TRACE_LEVEL_INFO,
6275 "%s: No Probe Response IE received in set beacon",
6276 __func__);
6277 }
6278 } /* end of if (WLAN_HDD_IBSS == pAdapter->device_mode) */
Jeff Johnson295189b2012-06-20 16:38:30 -07006279 break;
6280 case DOT11F_EID_RSN:
6281 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set RSN IE(len %d)",__func__, eLen + 2);
6282 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
6283 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2)/*ie_len*/);
6284 pWextState->roamProfile.pRSNReqIE = pWextState->WPARSNIE;
6285 pWextState->roamProfile.nRSNReqIELength = eLen + 2; //ie_len;
6286 break;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07006287 /* Appending Extended Capabilities with Interworking bit set in Assoc Req */
6288 case DOT11F_EID_EXTCAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306289 {
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07006290 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306291 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set Extended CAPS IE(len %d)",
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07006292 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306293
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07006294 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
6295 {
Jeff Johnson902c9832012-12-10 14:28:09 -08006296 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
6297 "Need bigger buffer space");
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07006298 VOS_ASSERT(0);
6299 return -ENOMEM;
6300 }
6301 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
6302 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306303
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07006304 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
6305 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
6306 break;
6307 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006308#ifdef FEATURE_WLAN_WAPI
6309 case WLAN_EID_WAPI:
6310 pAdapter->wapi_info.nWapiMode = 1; //Setting WAPI Mode to ON=1
Jeff Johnson0299d0a2013-10-30 12:37:43 -07006311 hddLog(VOS_TRACE_LEVEL_INFO, "WAPI MODE IS %u",
Jeff Johnson295189b2012-06-20 16:38:30 -07006312 pAdapter->wapi_info.nWapiMode);
6313 tmp = (u16 *)ie;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306314 tmp = tmp + 2; // Skip element Id and Len, Version
Jeff Johnson295189b2012-06-20 16:38:30 -07006315 akmsuiteCount = WPA_GET_LE16(tmp);
6316 tmp = tmp + 1;
6317 akmlist = (int *)(tmp);
6318 if(akmsuiteCount <= MAX_NUM_AKM_SUITES)
6319 {
6320 memcpy(akmsuite, akmlist, (4*akmsuiteCount));
6321 }
6322 else
6323 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08006324 hddLog(VOS_TRACE_LEVEL_FATAL, "Invalid akmSuite count");
Jeff Johnson295189b2012-06-20 16:38:30 -07006325 VOS_ASSERT(0);
6326 return -EINVAL;
6327 }
6328
6329 if (WAPI_PSK_AKM_SUITE == akmsuite[0])
6330 {
6331 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO PSK",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006332 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006333 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_PSK;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306334 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006335 if (WAPI_CERT_AKM_SUITE == akmsuite[0])
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306336 {
Jeff Johnson295189b2012-06-20 16:38:30 -07006337 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO CERTIFICATE",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006338 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006339 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_CERT;
6340 }
6341 break;
6342#endif
6343 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306344 hddLog (VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07006345 "%s Set UNKNOWN IE %X", __func__, elementId);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07006346 /* when Unknown IE is received we should break and continue
6347 * to the next IE in the buffer instead we were returning
6348 * so changing this to break */
6349 break;
Jeff Johnson295189b2012-06-20 16:38:30 -07006350 }
6351 genie += eLen;
6352 remLen -= eLen;
6353 }
6354 EXIT();
6355 return 0;
6356}
6357
6358/*
Gopichand Nakkala18f0c262013-05-07 23:25:08 +05306359 * FUNCTION: hdd_isWPAIEPresent
6360 * Parse the received IE to find the WPA IE
6361 *
6362 */
6363static bool hdd_isWPAIEPresent(u8 *ie, u8 ie_len)
6364{
6365 v_U8_t eLen = 0;
6366 v_U16_t remLen = ie_len;
6367 v_U8_t elementId = 0;
6368
6369 while (remLen >= 2)
6370 {
6371 elementId = *ie++;
6372 eLen = *ie++;
6373 remLen -= 2;
6374 if (eLen > remLen)
6375 {
6376 hddLog(VOS_TRACE_LEVEL_ERROR,
6377 "%s: IE length is wrong %d", __func__, eLen);
6378 return FALSE;
6379 }
6380 if ((elementId == DOT11F_EID_WPA) && (remLen > 5))
6381 {
6382 /* OUI - 0x00 0X50 0XF2
6383 WPA Information Element - 0x01
6384 WPA version - 0x01*/
6385 if (0 == memcmp(&ie[0], "\x00\x50\xf2\x01\x01", 5))
6386 return TRUE;
6387 }
6388 ie += eLen;
6389 remLen -= eLen;
6390 }
6391 return FALSE;
6392}
6393
6394/*
Jeff Johnson295189b2012-06-20 16:38:30 -07006395 * FUNCTION: wlan_hdd_cfg80211_set_privacy
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306396 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -07006397 * parameters during connect operation.
6398 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306399int wlan_hdd_cfg80211_set_privacy( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07006400 struct cfg80211_connect_params *req
6401 )
6402{
6403 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306404 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07006405 ENTER();
6406
6407 /*set wpa version*/
6408 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
6409
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306410 if (req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -07006411 {
Gopichand Nakkala781ded42013-06-28 12:10:45 +05306412 if (NL80211_WPA_VERSION_1 == req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -07006413 {
6414 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
6415 }
6416 else if (NL80211_WPA_VERSION_2 == req->crypto.wpa_versions)
6417 {
6418 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
6419 }
6420 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306421
6422 hddLog(VOS_TRACE_LEVEL_INFO, "%s: set wpa version to %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07006423 pWextState->wpaVersion);
6424
6425 /*set authentication type*/
6426 status = wlan_hdd_cfg80211_set_auth_type(pAdapter, req->auth_type);
6427
6428 if (0 > status)
6429 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306430 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07006431 "%s: failed to set authentication type ", __func__);
6432 return status;
6433 }
6434
6435 /*set key mgmt type*/
6436 if (req->crypto.n_akm_suites)
6437 {
6438 status = wlan_hdd_set_akm_suite(pAdapter, req->crypto.akm_suites[0]);
6439 if (0 > status)
6440 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306441 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set akm suite",
Jeff Johnson295189b2012-06-20 16:38:30 -07006442 __func__);
6443 return status;
6444 }
6445 }
6446
6447 /*set pairwise cipher type*/
6448 if (req->crypto.n_ciphers_pairwise)
6449 {
6450 status = wlan_hdd_cfg80211_set_cipher(pAdapter,
6451 req->crypto.ciphers_pairwise[0], true);
6452 if (0 > status)
6453 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306454 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07006455 "%s: failed to set unicast cipher type", __func__);
6456 return status;
6457 }
6458 }
6459 else
6460 {
6461 /*Reset previous cipher suite to none*/
6462 status = wlan_hdd_cfg80211_set_cipher(pAdapter, 0, true);
6463 if (0 > status)
6464 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306465 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07006466 "%s: failed to set unicast cipher type", __func__);
6467 return status;
6468 }
6469 }
6470
6471 /*set group cipher type*/
6472 status = wlan_hdd_cfg80211_set_cipher(pAdapter, req->crypto.cipher_group,
6473 false);
6474
6475 if (0 > status)
6476 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306477 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set mcast cipher type",
Jeff Johnson295189b2012-06-20 16:38:30 -07006478 __func__);
6479 return status;
6480 }
6481
Chet Lanctot186b5732013-03-18 10:26:30 -07006482#ifdef WLAN_FEATURE_11W
6483 pWextState->roamProfile.MFPEnabled = (req->mfp == NL80211_MFP_REQUIRED);
6484#endif
6485
Jeff Johnson295189b2012-06-20 16:38:30 -07006486 /*parse WPA/RSN IE, and set the correspoing fileds in Roam profile*/
6487 if (req->ie_len)
6488 {
6489 status = wlan_hdd_cfg80211_set_ie(pAdapter, req->ie, req->ie_len);
6490 if ( 0 > status)
6491 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306492 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse the WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -07006493 __func__);
6494 return status;
6495 }
6496 }
6497
6498 /*incase of WEP set default key information*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306499 if (req->key && req->key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -07006500 {
6501 if ( (WLAN_CIPHER_SUITE_WEP40 == req->crypto.ciphers_pairwise[0])
6502 || (WLAN_CIPHER_SUITE_WEP104 == req->crypto.ciphers_pairwise[0])
6503 )
6504 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306505 if ( IW_AUTH_KEY_MGMT_802_1X
Jeff Johnson295189b2012-06-20 16:38:30 -07006506 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X ))
6507 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306508 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Dynamic WEP not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -07006509 __func__);
6510 return -EOPNOTSUPP;
6511 }
6512 else
6513 {
6514 u8 key_len = req->key_len;
6515 u8 key_idx = req->key_idx;
6516
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306517 if ((eCSR_SECURITY_WEP_KEYSIZE_MAX_BYTES >= key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -07006518 && (CSR_MAX_NUM_KEY > key_idx)
6519 )
6520 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306521 hddLog(VOS_TRACE_LEVEL_INFO,
6522 "%s: setting default wep key, key_idx = %hu key_len %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07006523 __func__, key_idx, key_len);
6524 vos_mem_copy(
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306525 &pWextState->roamProfile.Keys.KeyMaterial[key_idx][0],
Jeff Johnson295189b2012-06-20 16:38:30 -07006526 req->key, key_len);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306527 pWextState->roamProfile.Keys.KeyLength[key_idx] =
Jeff Johnson295189b2012-06-20 16:38:30 -07006528 (u8)key_len;
6529 pWextState->roamProfile.Keys.defaultIndex = (u8)key_idx;
6530 }
6531 }
6532 }
6533 }
6534
6535 return status;
6536}
6537
6538/*
Vinay Krishna Eranna21042322014-01-08 19:21:39 +05306539 * FUNCTION: wlan_hdd_try_disconnect
6540 * This function is used to disconnect from previous
6541 * connection
6542 */
6543static int wlan_hdd_try_disconnect( hdd_adapter_t *pAdapter )
6544{
6545 long ret = 0;
6546 hdd_station_ctx_t *pHddStaCtx;
6547 eMib_dot11DesiredBssType connectedBssType;
6548
6549 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6550
6551 hdd_connGetConnectedBssType(pHddStaCtx,&connectedBssType );
6552
6553 if((eMib_dot11DesiredBssType_independent == connectedBssType) ||
6554 (eConnectionState_Associated == pHddStaCtx->conn_info.connState) ||
6555 (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState))
6556 {
6557 /* Issue disconnect to CSR */
6558 INIT_COMPLETION(pAdapter->disconnect_comp_var);
6559 if( eHAL_STATUS_SUCCESS ==
6560 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
6561 pAdapter->sessionId,
6562 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
6563 {
6564 ret = wait_for_completion_interruptible_timeout(
6565 &pAdapter->disconnect_comp_var,
6566 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
6567 if (0 >= ret)
6568 {
6569 hddLog(LOGE, FL("Failed to receive disconnect event"));
6570 return -EALREADY;
6571 }
6572 }
6573 }
6574 else if(eConnectionState_Disconnecting == pHddStaCtx->conn_info.connState)
6575 {
6576 ret = wait_for_completion_interruptible_timeout(
6577 &pAdapter->disconnect_comp_var,
6578 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
6579 if (0 >= ret)
6580 {
6581 hddLog(LOGE, FL("Failed to receive disconnect event"));
6582 return -EALREADY;
6583 }
6584 }
6585
6586 return 0;
6587}
6588
6589/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +05306590 * FUNCTION: __wlan_hdd_cfg80211_set_privacy
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306591 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -07006592 * parameters during connect operation.
6593 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +05306594static int __wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07006595 struct net_device *ndev,
6596 struct cfg80211_connect_params *req
6597 )
6598{
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306599 int status;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306600 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -07006601 VOS_STATUS exitbmpsStatus = VOS_STATUS_E_INVAL;
Rajesh Chauhana0516c62014-01-30 16:11:18 -08006602 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07006603
6604 ENTER();
6605
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05306606 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
6607 TRACE_CODE_HDD_CFG80211_CONNECT,
6608 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306609 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05306610 "%s: device_mode = %s (%d)", __func__,
6611 hdd_device_modetoString(pAdapter->device_mode),
6612 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07006613
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306614 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -08006615 if (!pHddCtx)
6616 {
6617 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6618 "%s: HDD context is null", __func__);
6619 return VOS_STATUS_E_FAILURE;
6620 }
6621
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306622 status = wlan_hdd_validate_context(pHddCtx);
6623
6624 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -07006625 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306626 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6627 "%s: HDD context is not valid", __func__);
6628 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -07006629 }
6630
6631#ifdef WLAN_BTAMP_FEATURE
6632 //Infra connect not supported when AMP traffic is on.
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306633 if( VOS_TRUE == WLANBAP_AmpSessionOn() )
Jeff Johnson295189b2012-06-20 16:38:30 -07006634 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306635 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07006636 "%s: No connection when AMP is on", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08006637 return -ECONNREFUSED;
Jeff Johnson295189b2012-06-20 16:38:30 -07006638 }
6639#endif
Vinay Krishna Eranna21042322014-01-08 19:21:39 +05306640
6641 //If Device Mode is Station Concurrent Sessions Exit BMps
6642 //P2P Mode will be taken care in Open/close adapter
6643 if((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
6644 (vos_concurrent_sessions_running()))
6645 {
6646 exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
6647 }
6648
6649 /*Try disconnecting if already in connected state*/
6650 status = wlan_hdd_try_disconnect(pAdapter);
6651 if ( 0 > status)
6652 {
6653 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
6654 " connection"));
6655 return -EALREADY;
6656 }
6657
Jeff Johnson295189b2012-06-20 16:38:30 -07006658 /*initialise security parameters*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306659 status = wlan_hdd_cfg80211_set_privacy(pAdapter, req);
Jeff Johnson295189b2012-06-20 16:38:30 -07006660
6661 if ( 0 > status)
6662 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306663 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security params",
Jeff Johnson295189b2012-06-20 16:38:30 -07006664 __func__);
6665 return status;
6666 }
6667
Mohit Khanna765234a2012-09-11 15:08:35 -07006668 if ( req->channel )
6669 {
6670 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
6671 req->ssid_len, req->bssid,
6672 req->channel->hw_value);
6673 }
6674 else
6675 {
6676 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306677 req->ssid_len, req->bssid, 0);
Mohit Khanna765234a2012-09-11 15:08:35 -07006678 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006679
6680 if (0 > status)
6681 {
6682 //ReEnable BMPS if disabled
6683 if((VOS_STATUS_SUCCESS == exitbmpsStatus) &&
6684 (NULL != pHddCtx))
6685 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306686 if (pHddCtx->hdd_wlan_suspended)
6687 {
6688 hdd_set_pwrparams(pHddCtx);
6689 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006690 //ReEnable Bmps and Imps back
6691 hdd_enable_bmps_imps(pHddCtx);
6692 }
6693
6694 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: connect failed", __func__);
6695 return status;
6696 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306697 pHddCtx->isAmpAllowed = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07006698 EXIT();
6699 return status;
6700}
6701
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +05306702static int wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
6703 struct net_device *ndev,
6704 struct cfg80211_connect_params *req)
6705{
6706 int ret;
6707 vos_ssr_protect(__func__);
6708 ret = __wlan_hdd_cfg80211_connect(wiphy, ndev, req);
6709 vos_ssr_unprotect(__func__);
6710
6711 return ret;
6712}
Jeff Johnson295189b2012-06-20 16:38:30 -07006713
6714/*
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05306715 * FUNCTION: wlan_hdd_disconnect
6716 * This function is used to issue a disconnect request to SME
6717 */
6718int wlan_hdd_disconnect( hdd_adapter_t *pAdapter, u16 reason )
6719{
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306720 int status;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05306721 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306722 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
6723
6724 status = wlan_hdd_validate_context(pHddCtx);
6725
6726 if (0 != status)
6727 {
6728 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6729 "%s: HDD context is not valid", __func__);
6730 return status;
6731 }
6732
6733 pHddCtx->isAmpAllowed = VOS_TRUE;
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +05306734 pHddStaCtx->conn_info.connState = eConnectionState_Disconnecting;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05306735 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306736
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05306737 /*issue disconnect*/
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +05306738
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05306739 status = sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
6740 pAdapter->sessionId, reason);
6741
6742 if ( 0 != status )
6743 {
6744 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006745 "%s csrRoamDisconnect failure, returned %d",
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05306746 __func__, (int)status );
6747 return -EINVAL;
6748 }
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +05306749 status = wait_for_completion_interruptible_timeout(
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05306750 &pAdapter->disconnect_comp_var,
6751 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +05306752 if (!status)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306753 {
6754 hddLog(VOS_TRACE_LEVEL_ERROR,
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +05306755 "%s: Failed to disconnect, timed out", __func__);
6756 return -ETIMEDOUT;
6757 }
6758 else if (status == -ERESTARTSYS)
6759 {
6760 hddLog(VOS_TRACE_LEVEL_ERROR,
6761 "%s: Failed to disconnect, wait interrupted", __func__);
6762 return status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306763 }
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05306764 /*stop tx queues*/
6765 netif_tx_disable(pAdapter->dev);
6766 netif_carrier_off(pAdapter->dev);
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +05306767 return 0;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05306768}
6769
6770
6771/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +05306772 * FUNCTION: __wlan_hdd_cfg80211_disconnect
Jeff Johnson295189b2012-06-20 16:38:30 -07006773 * This function is used to issue a disconnect request to SME
6774 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +05306775static int __wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07006776 struct net_device *dev,
6777 u16 reason
6778 )
6779{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306780 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
6781 tCsrRoamProfile *pRoamProfile =
Jeff Johnson295189b2012-06-20 16:38:30 -07006782 &(WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter))->roamProfile;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306783 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07006784 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkala4327a152013-03-04 23:22:42 -08006785 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaaa353782013-05-17 20:36:22 +05306786#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08006787 tANI_U8 staIdx;
6788#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306789
Jeff Johnson295189b2012-06-20 16:38:30 -07006790 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306791
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05306792 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
6793 TRACE_CODE_HDD_CFG80211_DISCONNECT,
6794 pAdapter->sessionId, reason));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05306795 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s(%d)",
6796 __func__, hdd_device_modetoString(pAdapter->device_mode),
6797 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07006798
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306799 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Disconnect called with reason code %d",
6800 __func__, reason);
Jeff Johnson295189b2012-06-20 16:38:30 -07006801
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306802 status = wlan_hdd_validate_context(pHddCtx);
6803
6804 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -07006805 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306806 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6807 "%s: HDD context is not valid", __func__);
6808 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -07006809 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306810
Jeff Johnson295189b2012-06-20 16:38:30 -07006811 if (NULL != pRoamProfile)
6812 {
6813 /*issue disconnect request to SME, if station is in connected state*/
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +05306814 if ((pHddStaCtx->conn_info.connState == eConnectionState_Associated) ||
6815 (pHddStaCtx->conn_info.connState == eConnectionState_Connecting))
Jeff Johnson295189b2012-06-20 16:38:30 -07006816 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306817 eCsrRoamDisconnectReason reasonCode =
Jeff Johnson295189b2012-06-20 16:38:30 -07006818 eCSR_DISCONNECT_REASON_UNSPECIFIED;
Gopichand Nakkalaaa353782013-05-17 20:36:22 +05306819 hdd_scaninfo_t *pScanInfo;
Jeff Johnson295189b2012-06-20 16:38:30 -07006820 switch(reason)
6821 {
6822 case WLAN_REASON_MIC_FAILURE:
6823 reasonCode = eCSR_DISCONNECT_REASON_MIC_ERROR;
6824 break;
6825
6826 case WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY:
6827 case WLAN_REASON_DISASSOC_AP_BUSY:
6828 case WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA:
6829 reasonCode = eCSR_DISCONNECT_REASON_DISASSOC;
6830 break;
6831
6832 case WLAN_REASON_PREV_AUTH_NOT_VALID:
6833 case WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA:
Abhishek Singhc3269a52014-05-21 17:22:24 +05306834 case WLAN_REASON_DEAUTH_LEAVING:
Jeff Johnson295189b2012-06-20 16:38:30 -07006835 reasonCode = eCSR_DISCONNECT_REASON_DEAUTH;
6836 break;
6837
Jeff Johnson295189b2012-06-20 16:38:30 -07006838 default:
6839 reasonCode = eCSR_DISCONNECT_REASON_UNSPECIFIED;
6840 break;
6841 }
Gopichand Nakkalaaa353782013-05-17 20:36:22 +05306842 pScanInfo = &pHddCtx->scan_info;
6843 if (pScanInfo->mScanPending)
6844 {
Srinivas, Dasari138af4f2014-02-07 11:13:45 +05306845 hddLog(VOS_TRACE_LEVEL_INFO, "Disconnect is in progress, "
Gopichand Nakkalaaa353782013-05-17 20:36:22 +05306846 "Aborting Scan");
Srinivas, Dasari138af4f2014-02-07 11:13:45 +05306847 hdd_abort_mac_scan(pHddCtx, pAdapter->sessionId,
6848 eCSR_SCAN_ABORT_DEFAULT);
Gopichand Nakkalaaa353782013-05-17 20:36:22 +05306849 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006850
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08006851#ifdef FEATURE_WLAN_TDLS
6852 /* First clean up the tdls peers if any */
Gopichand Nakkala4327a152013-03-04 23:22:42 -08006853 for (staIdx = 0 ; staIdx < HDD_MAX_NUM_TDLS_STA; staIdx++)
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08006854 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -08006855 if ((pHddCtx->tdlsConnInfo[staIdx].sessionId == pAdapter->sessionId) &&
6856 (pHddCtx->tdlsConnInfo[staIdx].staId))
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08006857 {
Hoonki Lee11f7dda2013-02-14 16:55:44 -08006858 uint8 *mac;
Gopichand Nakkala4327a152013-03-04 23:22:42 -08006859 mac = pHddCtx->tdlsConnInfo[staIdx].peerMac.bytes;
Hoonki Lee11f7dda2013-02-14 16:55:44 -08006860 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07006861 "%s: call sme_DeleteTdlsPeerSta staId %d sessionId %d " MAC_ADDRESS_STR,
Gopichand Nakkala4327a152013-03-04 23:22:42 -08006862 __func__, pHddCtx->tdlsConnInfo[staIdx].staId, pAdapter->sessionId,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07006863 MAC_ADDR_ARRAY(mac));
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08006864 sme_DeleteTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala4327a152013-03-04 23:22:42 -08006865 pAdapter->sessionId,
6866 mac);
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08006867 }
6868 }
6869#endif
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +05306870 hddLog(LOG1, FL("Disconnecting with reasoncode:%u"), reasonCode);
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05306871 status = wlan_hdd_disconnect(pAdapter, reasonCode);
6872 if ( 0 != status )
Jeff Johnson295189b2012-06-20 16:38:30 -07006873 {
6874 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006875 "%s wlan_hdd_disconnect failure, returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07006876 __func__, (int)status );
6877 return -EINVAL;
6878 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006879 }
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +05306880 else
6881 {
6882 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unexpected cfg disconnect API"
6883 "called while in %d state", __func__,
6884 pHddStaCtx->conn_info.connState);
6885 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006886 }
6887 else
6888 {
6889 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid roam profile", __func__);
6890 }
6891
6892 return status;
6893}
6894
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +05306895static int wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
6896 struct net_device *dev,
6897 u16 reason
6898 )
6899{
6900 int ret;
6901 vos_ssr_protect(__func__);
6902 ret = __wlan_hdd_cfg80211_disconnect(wiphy, dev, reason);
6903 vos_ssr_unprotect(__func__);
6904
6905 return ret;
6906}
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05306907
Jeff Johnson295189b2012-06-20 16:38:30 -07006908/*
6909 * FUNCTION: wlan_hdd_cfg80211_set_privacy_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306910 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -07006911 * settings in IBSS mode.
6912 */
6913static int wlan_hdd_cfg80211_set_privacy_ibss(
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306914 hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07006915 struct cfg80211_ibss_params *params
6916 )
6917{
6918 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306919 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07006920 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
6921 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306922
Jeff Johnson295189b2012-06-20 16:38:30 -07006923 ENTER();
6924
6925 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
Ravi Joshib58ca0d2013-10-29 09:50:23 -07006926 vos_mem_zero(&pHddStaCtx->ibss_enc_key, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -07006927
6928 if (params->ie_len && ( NULL != params->ie) )
6929 {
Shailender Karmuchi67edd312013-06-18 16:30:48 -07006930 if (wlan_hdd_cfg80211_get_ie_ptr (params->ie,
6931 params->ie_len, WLAN_EID_RSN ))
Jeff Johnson295189b2012-06-20 16:38:30 -07006932 {
6933 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
6934 encryptionType = eCSR_ENCRYPT_TYPE_AES;
6935 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -07006936 else if ( hdd_isWPAIEPresent (params->ie, params->ie_len ))
Jeff Johnson295189b2012-06-20 16:38:30 -07006937 {
Shailender Karmuchi642e9812013-05-30 14:34:49 -07006938 tDot11fIEWPA dot11WPAIE;
6939 tHalHandle halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
Shailender Karmuchi67edd312013-06-18 16:30:48 -07006940 u8 *ie;
Shailender Karmuchi642e9812013-05-30 14:34:49 -07006941
Wilson Yang00256342013-10-10 23:13:38 -07006942 memset(&dot11WPAIE, 0, sizeof(dot11WPAIE));
Shailender Karmuchi67edd312013-06-18 16:30:48 -07006943 ie = wlan_hdd_cfg80211_get_ie_ptr (params->ie,
6944 params->ie_len, DOT11F_EID_WPA);
6945 if ( NULL != ie )
6946 {
6947 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
6948 // Unpack the WPA IE
6949 //Skip past the EID byte and length byte - and four byte WiFi OUI
6950 dot11fUnpackIeWPA((tpAniSirGlobal) halHandle,
6951 &ie[2+4],
6952 ie[1] - 4,
6953 &dot11WPAIE);
6954 /*Extract the multicast cipher, the encType for unicast
6955 cipher for wpa-none is none*/
6956 encryptionType =
6957 hdd_TranslateWPAToCsrEncryptionType(dot11WPAIE.multicast_cipher);
6958 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006959 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -07006960
Jeff Johnson295189b2012-06-20 16:38:30 -07006961 status = wlan_hdd_cfg80211_set_ie(pAdapter, params->ie, params->ie_len);
6962
6963 if (0 > status)
6964 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306965 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -07006966 __func__);
6967 return status;
6968 }
6969 }
6970
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306971 pWextState->roamProfile.AuthType.authType[0] =
6972 pHddStaCtx->conn_info.authType =
Jeff Johnson295189b2012-06-20 16:38:30 -07006973 eCSR_AUTH_TYPE_OPEN_SYSTEM;
6974
6975 if (params->privacy)
6976 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306977 /* Security enabled IBSS, At this time there is no information available
6978 * about the security paramters, so initialise the encryption type to
Jeff Johnson295189b2012-06-20 16:38:30 -07006979 * eCSR_ENCRYPT_TYPE_WEP40_STATICKEY.
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306980 * The correct security parameters will be updated later in
Jeff Johnson295189b2012-06-20 16:38:30 -07006981 * wlan_hdd_cfg80211_add_key */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306982 /* Hal expects encryption type to be set inorder
Jeff Johnson295189b2012-06-20 16:38:30 -07006983 *enable privacy bit in beacons */
6984
6985 encryptionType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
6986 }
Shailender Karmuchi642e9812013-05-30 14:34:49 -07006987 VOS_TRACE (VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
6988 "encryptionType=%d", encryptionType);
Jeff Johnson295189b2012-06-20 16:38:30 -07006989 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
6990 pWextState->roamProfile.EncryptionType.numEntries = 1;
6991 pWextState->roamProfile.EncryptionType.encryptionType[0] = encryptionType;
Jeff Johnson295189b2012-06-20 16:38:30 -07006992 return status;
6993}
6994
6995/*
6996 * FUNCTION: wlan_hdd_cfg80211_join_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306997 * This function is used to create/join an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -07006998 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306999static int wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07007000 struct net_device *dev,
7001 struct cfg80211_ibss_params *params
7002 )
7003{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307004 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Jeff Johnson295189b2012-06-20 16:38:30 -07007005 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
7006 tCsrRoamProfile *pRoamProfile;
7007 int status;
krunal sonie9002db2013-11-25 14:24:17 -08007008 bool alloc_bssid = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07007009 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307010 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07007011
7012 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307013
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307014 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7015 TRACE_CODE_HDD_CFG80211_JOIN_IBSS,
7016 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307017 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05307018 "%s: device_mode = %s (%d)", __func__,
7019 hdd_device_modetoString(pAdapter->device_mode),
7020 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07007021
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307022 status = wlan_hdd_validate_context(pHddCtx);
7023
7024 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -07007025 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307026 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7027 "%s: HDD context is not valid", __func__);
7028 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -07007029 }
7030
7031 if (NULL == pWextState)
7032 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08007033 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -07007034 __func__);
7035 return -EIO;
7036 }
7037
Vinay Krishna Eranna21042322014-01-08 19:21:39 +05307038 /*Try disconnecting if already in connected state*/
7039 status = wlan_hdd_try_disconnect(pAdapter);
7040 if ( 0 > status)
7041 {
7042 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
7043 " IBSS connection"));
7044 return -EALREADY;
7045 }
7046
Jeff Johnson295189b2012-06-20 16:38:30 -07007047 pRoamProfile = &pWextState->roamProfile;
7048
7049 if ( eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType )
7050 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307051 hddLog (VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007052 "%s Interface type is not set to IBSS", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007053 return -EINVAL;
7054 }
7055
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -07007056 /* BSSID is provided by upper layers hence no need to AUTO generate */
7057 if (NULL != params->bssid) {
7058 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
7059 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) {
7060 hddLog (VOS_TRACE_LEVEL_ERROR,
7061 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
7062 return -EIO;
7063 }
7064 }
krunal sonie9002db2013-11-25 14:24:17 -08007065 else if(pHddCtx->cfg_ini->isCoalesingInIBSSAllowed == 0)
7066 {
7067 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
7068 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
7069 {
7070 hddLog (VOS_TRACE_LEVEL_ERROR,
7071 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
7072 return -EIO;
7073 }
7074 params->bssid = vos_mem_malloc(sizeof(VOS_MAC_ADDR_SIZE));
7075 if (!params->bssid)
7076 {
7077 hddLog (VOS_TRACE_LEVEL_ERROR,
7078 "%s:Failed memory allocation", __func__);
7079 return -EIO;
7080 }
7081 vos_mem_copy((v_U8_t *)params->bssid,
7082 (v_U8_t *)&pHddCtx->cfg_ini->IbssBssid.bytes[0],
7083 VOS_MAC_ADDR_SIZE);
7084 alloc_bssid = VOS_TRUE;
7085 }
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -07007086
Jeff Johnson295189b2012-06-20 16:38:30 -07007087 /* Set Channel */
Yue Maf49ba872013-08-19 12:04:25 -07007088 if (NULL !=
7089#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
7090 params->chandef.chan)
7091#else
7092 params->channel)
7093#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007094 {
7095 u8 channelNum;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07007096 v_U32_t numChans = WNI_CFG_VALID_CHANNEL_LIST_LEN;
7097 v_U8_t validChan[WNI_CFG_VALID_CHANNEL_LIST_LEN];
7098 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
7099 int indx;
Jeff Johnson295189b2012-06-20 16:38:30 -07007100
7101 /* Get channel number */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307102 channelNum =
Yue Maf49ba872013-08-19 12:04:25 -07007103 ieee80211_frequency_to_channel(
7104#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
7105 params->chandef.chan->center_freq);
7106#else
7107 params->channel->center_freq);
7108#endif
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07007109
7110 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
7111 validChan, &numChans))
Jeff Johnson295189b2012-06-20 16:38:30 -07007112 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07007113 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid channel list",
7114 __func__);
7115 return -EOPNOTSUPP;
Jeff Johnson295189b2012-06-20 16:38:30 -07007116 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07007117
7118 for (indx = 0; indx < numChans; indx++)
Jeff Johnson295189b2012-06-20 16:38:30 -07007119 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07007120 if (channelNum == validChan[indx])
7121 {
7122 break;
7123 }
7124 }
7125 if (indx >= numChans)
7126 {
7127 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Not valid Channel %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07007128 __func__, channelNum);
7129 return -EINVAL;
7130 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07007131 /* Set the Operational Channel */
7132 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: set channel %d", __func__,
7133 channelNum);
7134 pRoamProfile->ChannelInfo.numOfChannels = 1;
7135 pHddStaCtx->conn_info.operationChannel = channelNum;
7136 pRoamProfile->ChannelInfo.ChannelList =
7137 &pHddStaCtx->conn_info.operationChannel;
Jeff Johnson295189b2012-06-20 16:38:30 -07007138 }
7139
7140 /* Initialize security parameters */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307141 status = wlan_hdd_cfg80211_set_privacy_ibss(pAdapter, params);
Jeff Johnson295189b2012-06-20 16:38:30 -07007142 if (status < 0)
7143 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307144 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security parameters",
Jeff Johnson295189b2012-06-20 16:38:30 -07007145 __func__);
7146 return status;
7147 }
7148
7149 /* Issue connect start */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307150 status = wlan_hdd_cfg80211_connect_start(pAdapter, params->ssid,
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07007151 params->ssid_len, params->bssid,
7152 pHddStaCtx->conn_info.operationChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -07007153
7154 if (0 > status)
7155 {
7156 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: connect failed", __func__);
7157 return status;
7158 }
7159
krunal sonie9002db2013-11-25 14:24:17 -08007160 if (NULL != params->bssid &&
7161 pHddCtx->cfg_ini->isCoalesingInIBSSAllowed == 0 &&
7162 alloc_bssid == VOS_TRUE)
7163 {
7164 vos_mem_free(params->bssid);
7165 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007166 return 0;
7167}
7168
7169/*
7170 * FUNCTION: wlan_hdd_cfg80211_leave_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307171 * This function is used to leave an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -07007172 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307173static int wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07007174 struct net_device *dev
7175 )
7176{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307177 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Jeff Johnson295189b2012-06-20 16:38:30 -07007178 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
7179 tCsrRoamProfile *pRoamProfile;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307180 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7181 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07007182
7183 ENTER();
7184
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307185 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7186 TRACE_CODE_HDD_CFG80211_LEAVE_IBSS,
7187 pAdapter->sessionId, eCSR_DISCONNECT_REASON_IBSS_LEAVE));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307188 status = wlan_hdd_validate_context(pHddCtx);
7189
7190 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007191 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307192 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7193 "%s: HDD context is not valid", __func__);
7194 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007195 }
7196
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05307197 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)", __func__,
7198 hdd_device_modetoString(pAdapter->device_mode),
7199 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07007200 if (NULL == pWextState)
7201 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08007202 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -07007203 __func__);
7204 return -EIO;
7205 }
7206
7207 pRoamProfile = &pWextState->roamProfile;
7208
7209 /* Issue disconnect only if interface type is set to IBSS */
7210 if (eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType)
7211 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307212 hddLog (VOS_TRACE_LEVEL_ERROR, "%s: BSS Type is not set to IBSS",
Jeff Johnson295189b2012-06-20 16:38:30 -07007213 __func__);
7214 return -EINVAL;
7215 }
7216
7217 /* Issue Disconnect request */
7218 INIT_COMPLETION(pAdapter->disconnect_comp_var);
7219 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
7220 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
7221
7222 return 0;
7223}
7224
7225/*
7226 * FUNCTION: wlan_hdd_cfg80211_set_wiphy_params
7227 * This function is used to set the phy parameters
7228 * (RTS Threshold/FRAG Threshold/Retry Count etc ...)
7229 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307230static int wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07007231 u32 changed)
7232{
7233 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
7234 tHalHandle hHal = pHddCtx->hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307235 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07007236
7237 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307238 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7239 TRACE_CODE_HDD_CFG80211_SET_WIPHY_PARAMS,
7240 NO_SESSION, wiphy->rts_threshold));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307241 status = wlan_hdd_validate_context(pHddCtx);
7242
7243 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007244 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307245 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7246 "%s: HDD context is not valid", __func__);
7247 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007248 }
7249
Jeff Johnson295189b2012-06-20 16:38:30 -07007250 if (changed & WIPHY_PARAM_RTS_THRESHOLD)
7251 {
7252 u16 rts_threshold = (wiphy->rts_threshold == -1) ?
7253 WNI_CFG_RTS_THRESHOLD_STAMAX :
7254 wiphy->rts_threshold;
7255
7256 if ((WNI_CFG_RTS_THRESHOLD_STAMIN > rts_threshold) ||
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307257 (WNI_CFG_RTS_THRESHOLD_STAMAX < rts_threshold))
Jeff Johnson295189b2012-06-20 16:38:30 -07007258 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307259 hddLog(VOS_TRACE_LEVEL_ERROR,
7260 "%s: Invalid RTS Threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07007261 __func__, rts_threshold);
7262 return -EINVAL;
7263 }
7264
7265 if (0 != ccmCfgSetInt(hHal, WNI_CFG_RTS_THRESHOLD,
7266 rts_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307267 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -07007268 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307269 hddLog(VOS_TRACE_LEVEL_ERROR,
7270 "%s: ccmCfgSetInt failed for rts_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07007271 __func__, rts_threshold);
7272 return -EIO;
7273 }
7274
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307275 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set rts threshold %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07007276 rts_threshold);
7277 }
7278
7279 if (changed & WIPHY_PARAM_FRAG_THRESHOLD)
7280 {
7281 u16 frag_threshold = (wiphy->frag_threshold == -1) ?
7282 WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX :
7283 wiphy->frag_threshold;
7284
7285 if ((WNI_CFG_FRAGMENTATION_THRESHOLD_STAMIN > frag_threshold)||
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307286 (WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX < frag_threshold) )
Jeff Johnson295189b2012-06-20 16:38:30 -07007287 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307288 hddLog(VOS_TRACE_LEVEL_ERROR,
7289 "%s: Invalid frag_threshold value %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07007290 frag_threshold);
7291 return -EINVAL;
7292 }
7293
7294 if (0 != ccmCfgSetInt(hHal, WNI_CFG_FRAGMENTATION_THRESHOLD,
7295 frag_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307296 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -07007297 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307298 hddLog(VOS_TRACE_LEVEL_ERROR,
7299 "%s: ccmCfgSetInt failed for frag_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07007300 __func__, frag_threshold);
7301 return -EIO;
7302 }
7303
7304 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set frag threshold %hu", __func__,
7305 frag_threshold);
7306 }
7307
7308 if ((changed & WIPHY_PARAM_RETRY_SHORT)
7309 || (changed & WIPHY_PARAM_RETRY_LONG))
7310 {
7311 u8 retry_value = (changed & WIPHY_PARAM_RETRY_SHORT) ?
7312 wiphy->retry_short :
7313 wiphy->retry_long;
7314
7315 if ((WNI_CFG_LONG_RETRY_LIMIT_STAMIN > retry_value) ||
7316 (WNI_CFG_LONG_RETRY_LIMIT_STAMAX < retry_value))
7317 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307318 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07007319 __func__, retry_value);
7320 return -EINVAL;
7321 }
7322
7323 if (changed & WIPHY_PARAM_RETRY_SHORT)
7324 {
7325 if (0 != ccmCfgSetInt(hHal, WNI_CFG_LONG_RETRY_LIMIT,
7326 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307327 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -07007328 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307329 hddLog(VOS_TRACE_LEVEL_ERROR,
7330 "%s: ccmCfgSetInt failed for long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07007331 __func__, retry_value);
7332 return -EIO;
7333 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307334 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07007335 __func__, retry_value);
7336 }
7337 else if (changed & WIPHY_PARAM_RETRY_SHORT)
7338 {
7339 if (0 != ccmCfgSetInt(hHal, WNI_CFG_SHORT_RETRY_LIMIT,
7340 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307341 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -07007342 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307343 hddLog(VOS_TRACE_LEVEL_ERROR,
7344 "%s: ccmCfgSetInt failed for short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07007345 __func__, retry_value);
7346 return -EIO;
7347 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307348 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07007349 __func__, retry_value);
7350 }
7351 }
7352
7353 return 0;
7354}
7355
7356/*
7357 * FUNCTION: wlan_hdd_cfg80211_set_txpower
7358 * This function is used to set the txpower
7359 */
7360static int wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
Yue Maf49ba872013-08-19 12:04:25 -07007361#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
7362 struct wireless_dev *wdev,
7363#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007364#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307365 enum tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -07007366#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307367 enum nl80211_tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -07007368#endif
7369 int dbm)
7370{
7371 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307372 tHalHandle hHal = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07007373 tSirMacAddr bssid = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
7374 tSirMacAddr selfMac = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307375 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07007376
7377 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307378 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7379 TRACE_CODE_HDD_CFG80211_SET_TXPOWER,
7380 NO_SESSION, type ));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307381 status = wlan_hdd_validate_context(pHddCtx);
7382
7383 if (0 != status)
7384 {
7385 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7386 "%s: HDD context is not valid", __func__);
7387 return status;
7388 }
7389
7390 hHal = pHddCtx->hHal;
7391
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307392 if (0 != ccmCfgSetInt(hHal, WNI_CFG_CURRENT_TX_POWER_LEVEL,
7393 dbm, ccmCfgSetCallback,
7394 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -07007395 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307396 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07007397 "%s: ccmCfgSetInt failed for tx power %hu", __func__, dbm);
7398 return -EIO;
7399 }
7400
7401 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set tx power level %d dbm", __func__,
7402 dbm);
7403
7404 switch(type)
7405 {
7406 case NL80211_TX_POWER_AUTOMATIC: /*automatically determine transmit power*/
7407 /* Fall through */
7408 case NL80211_TX_POWER_LIMITED: /*limit TX power by the mBm parameter*/
7409 if( sme_SetMaxTxPower(hHal, bssid, selfMac, dbm) != eHAL_STATUS_SUCCESS )
7410 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307411 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Setting maximum tx power failed",
7412 __func__);
7413 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -07007414 }
7415 break;
7416 case NL80211_TX_POWER_FIXED: /*fix TX power to the mBm parameter*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307417 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: NL80211_TX_POWER_FIXED not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -07007418 __func__);
7419 return -EOPNOTSUPP;
7420 break;
7421 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307422 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid power setting type %d",
7423 __func__, type);
Jeff Johnson295189b2012-06-20 16:38:30 -07007424 return -EIO;
7425 }
7426
7427 return 0;
7428}
7429
7430/*
7431 * FUNCTION: wlan_hdd_cfg80211_get_txpower
7432 * This function is used to read the txpower
7433 */
Yue Maf49ba872013-08-19 12:04:25 -07007434static int wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy,
7435#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
7436 struct wireless_dev *wdev,
7437#endif
7438 int *dbm)
Jeff Johnson295189b2012-06-20 16:38:30 -07007439{
7440
7441 hdd_adapter_t *pAdapter;
7442 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307443 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07007444
Jeff Johnsone7245742012-09-05 17:12:55 -07007445 ENTER();
7446
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307447 status = wlan_hdd_validate_context(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07007448
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307449 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007450 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307451 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7452 "%s: HDD context is not valid", __func__);
7453 *dbm = 0;
7454 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007455 }
7456
Jeff Johnson295189b2012-06-20 16:38:30 -07007457 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
7458 if (NULL == pAdapter)
7459 {
7460 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Not in station context " ,__func__);
7461 return -ENOENT;
7462 }
7463
7464 wlan_hdd_get_classAstats(pAdapter);
7465 *dbm = pAdapter->hdd_stats.ClassA_stat.max_pwr;
7466
Jeff Johnsone7245742012-09-05 17:12:55 -07007467 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07007468 return 0;
7469}
7470
7471static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
7472 u8* mac, struct station_info *sinfo)
7473{
7474 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
7475 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7476 int ssidlen = pHddStaCtx->conn_info.SSID.SSID.length;
c_hpothu44ff4e02014-05-08 00:13:57 +05307477 tANI_U32 rate_flags;
Jeff Johnson295189b2012-06-20 16:38:30 -07007478
7479 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
7480 hdd_config_t *pCfg = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -07007481
7482 tANI_U8 OperationalRates[CSR_DOT11_SUPPORTED_RATES_MAX];
7483 tANI_U32 ORLeng = CSR_DOT11_SUPPORTED_RATES_MAX;
7484 tANI_U8 ExtendedRates[CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX];
7485 tANI_U32 ERLeng = CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX;
7486 tANI_U8 MCSRates[SIZE_OF_BASIC_MCS_SET];
7487 tANI_U32 MCSLeng = SIZE_OF_BASIC_MCS_SET;
7488 tANI_U16 maxRate = 0;
7489 tANI_U16 myRate;
7490 tANI_U16 currentRate = 0;
7491 tANI_U8 maxSpeedMCS = 0;
7492 tANI_U8 maxMCSIdx = 0;
7493 tANI_U8 rateFlag = 1;
7494 tANI_U8 i, j, rssidx;
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07007495 tANI_U16 temp;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307496 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07007497
Leo Chang6f8870f2013-03-26 18:11:36 -07007498#ifdef WLAN_FEATURE_11AC
7499 tANI_U32 vht_mcs_map;
7500 eDataRate11ACMaxMcs vhtMaxMcs;
7501#endif /* WLAN_FEATURE_11AC */
7502
Jeff Johnsone7245742012-09-05 17:12:55 -07007503 ENTER();
7504
Jeff Johnson295189b2012-06-20 16:38:30 -07007505 if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) ||
7506 (0 == ssidlen))
7507 {
7508 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Not associated or"
7509 " Invalid ssidlen, %d", __func__, ssidlen);
7510 /*To keep GUI happy*/
7511 return 0;
7512 }
7513
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307514 status = wlan_hdd_validate_context(pHddCtx);
7515
7516 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007517 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307518 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7519 "%s: HDD context is not valid", __func__);
7520 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007521 }
7522
Jeff Johnson295189b2012-06-20 16:38:30 -07007523
Kiet Lam3b17fc82013-09-27 05:24:08 +05307524 wlan_hdd_get_rssi(pAdapter, &sinfo->signal);
7525 sinfo->filled |= STATION_INFO_SIGNAL;
7526
c_hpothu44ff4e02014-05-08 00:13:57 +05307527 if ((eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed) ||
7528 (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed &&
7529 sinfo->signal >= pCfg->linkSpeedRssiHigh))
7530 {
7531 rate_flags = pAdapter->maxRateFlags;
7532 }
7533 else
7534 {
7535 wlan_hdd_get_station_stats(pAdapter);
7536 rate_flags = pAdapter->hdd_stats.ClassA_stat.tx_rate_flags;
7537 }
7538
Jeff Johnson295189b2012-06-20 16:38:30 -07007539 //convert to the UI units of 100kbps
7540 myRate = pAdapter->hdd_stats.ClassA_stat.tx_rate * 5;
7541
7542#ifdef LINKSPEED_DEBUG_ENABLED
Leo Chang6f8870f2013-03-26 18:11:36 -07007543 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 -07007544 sinfo->signal,
7545 pCfg->reportMaxLinkSpeed,
7546 myRate,
7547 (int) pCfg->linkSpeedRssiHigh,
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07007548 (int) pCfg->linkSpeedRssiMid,
7549 (int) pCfg->linkSpeedRssiLow,
Leo Chang6f8870f2013-03-26 18:11:36 -07007550 (int) rate_flags,
7551 (int) pAdapter->hdd_stats.ClassA_stat.mcs_index);
Jeff Johnson295189b2012-06-20 16:38:30 -07007552#endif //LINKSPEED_DEBUG_ENABLED
7553
7554 if (eHDD_LINK_SPEED_REPORT_ACTUAL != pCfg->reportMaxLinkSpeed)
7555 {
7556 // we do not want to necessarily report the current speed
7557 if (eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed)
7558 {
7559 // report the max possible speed
7560 rssidx = 0;
7561 }
7562 else if (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed)
7563 {
7564 // report the max possible speed with RSSI scaling
7565 if (sinfo->signal >= pCfg->linkSpeedRssiHigh)
7566 {
7567 // report the max possible speed
7568 rssidx = 0;
7569 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07007570 else if (sinfo->signal >= pCfg->linkSpeedRssiMid)
Jeff Johnson295189b2012-06-20 16:38:30 -07007571 {
7572 // report middle speed
7573 rssidx = 1;
7574 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07007575 else if (sinfo->signal >= pCfg->linkSpeedRssiLow)
7576 {
7577 // report middle speed
7578 rssidx = 2;
7579 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007580 else
7581 {
7582 // report actual speed
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07007583 rssidx = 3;
Jeff Johnson295189b2012-06-20 16:38:30 -07007584 }
7585 }
7586 else
7587 {
7588 // unknown, treat as eHDD_LINK_SPEED_REPORT_MAX
7589 hddLog(VOS_TRACE_LEVEL_ERROR,
7590 "%s: Invalid value for reportMaxLinkSpeed: %u",
7591 __func__, pCfg->reportMaxLinkSpeed);
7592 rssidx = 0;
7593 }
7594
7595 maxRate = 0;
7596
7597 /* Get Basic Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +05307598 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_OPERATIONAL_RATE_SET,
7599 OperationalRates, &ORLeng))
7600 {
7601 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
7602 /*To keep GUI happy*/
7603 return 0;
7604 }
7605
Jeff Johnson295189b2012-06-20 16:38:30 -07007606 for (i = 0; i < ORLeng; i++)
7607 {
Jeff Johnsone7245742012-09-05 17:12:55 -07007608 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -07007609 {
7610 /* Validate Rate Set */
7611 if (supported_data_rate[j].beacon_rate_index == (OperationalRates[i] & 0x7F))
7612 {
7613 currentRate = supported_data_rate[j].supported_rate[rssidx];
7614 break;
7615 }
7616 }
7617 /* Update MAX rate */
7618 maxRate = (currentRate > maxRate)?currentRate:maxRate;
7619 }
7620
7621 /* Get Extended Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +05307622 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET,
7623 ExtendedRates, &ERLeng))
7624 {
7625 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
7626 /*To keep GUI happy*/
7627 return 0;
7628 }
7629
Jeff Johnson295189b2012-06-20 16:38:30 -07007630 for (i = 0; i < ERLeng; i++)
7631 {
Jeff Johnsone7245742012-09-05 17:12:55 -07007632 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -07007633 {
7634 if (supported_data_rate[j].beacon_rate_index == (ExtendedRates[i] & 0x7F))
7635 {
7636 currentRate = supported_data_rate[j].supported_rate[rssidx];
7637 break;
7638 }
7639 }
7640 /* Update MAX rate */
7641 maxRate = (currentRate > maxRate)?currentRate:maxRate;
7642 }
Kiet Lamb69f8dc2013-11-15 15:34:27 +05307643 /* Get MCS Rate Set --
Kaushik, Sushantdc304d82014-01-22 10:58:37 +05307644 Only if we are always reporting max speed (or)
Kiet Lamb69f8dc2013-11-15 15:34:27 +05307645 if we have good rssi */
Kaushik, Sushantdc304d82014-01-22 10:58:37 +05307646 if ((0 == rssidx) ||
Kiet Lamb69f8dc2013-11-15 15:34:27 +05307647 (eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed))
Jeff Johnson295189b2012-06-20 16:38:30 -07007648 {
Gopichand Nakkala05ab1322013-02-15 11:28:38 +05307649 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_CURRENT_MCS_SET,
7650 MCSRates, &MCSLeng))
7651 {
7652 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
7653 /*To keep GUI happy*/
7654 return 0;
7655 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007656 rateFlag = 0;
Leo Chang6f8870f2013-03-26 18:11:36 -07007657#ifdef WLAN_FEATURE_11AC
7658 /* VHT80 rate has seperate rate table */
Gopichand Nakkala4c705372013-04-24 13:20:33 +05307659 if (rate_flags & (eHAL_TX_RATE_VHT20|eHAL_TX_RATE_VHT40|eHAL_TX_RATE_VHT80))
Jeff Johnson295189b2012-06-20 16:38:30 -07007660 {
Leo Chang6f8870f2013-03-26 18:11:36 -07007661 ccmCfgGetInt(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_VHT_TX_MCS_MAP, &vht_mcs_map);
Gopichand Nakkala4c705372013-04-24 13:20:33 +05307662 vhtMaxMcs = (eDataRate11ACMaxMcs)(vht_mcs_map & DATA_RATE_11AC_MCS_MASK );
Leo Chang6f8870f2013-03-26 18:11:36 -07007663 if (rate_flags & eHAL_TX_RATE_SGI)
Jeff Johnson295189b2012-06-20 16:38:30 -07007664 {
Leo Chang6f8870f2013-03-26 18:11:36 -07007665 rateFlag |= 1;
Jeff Johnson295189b2012-06-20 16:38:30 -07007666 }
Leo Chang6f8870f2013-03-26 18:11:36 -07007667 if (DATA_RATE_11AC_MAX_MCS_7 == vhtMaxMcs)
Jeff Johnson295189b2012-06-20 16:38:30 -07007668 {
Leo Chang6f8870f2013-03-26 18:11:36 -07007669 maxMCSIdx = 7;
7670 }
7671 else if (DATA_RATE_11AC_MAX_MCS_8 == vhtMaxMcs)
7672 {
7673 maxMCSIdx = 8;
7674 }
7675 else if (DATA_RATE_11AC_MAX_MCS_9 == vhtMaxMcs)
7676 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +05307677 //VHT20 is supporting 0~8
7678 if (rate_flags & eHAL_TX_RATE_VHT20)
7679 maxMCSIdx = 8;
7680 else
7681 maxMCSIdx = 9;
Leo Chang6f8870f2013-03-26 18:11:36 -07007682 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +05307683
7684 if (rate_flags & eHAL_TX_RATE_VHT80)
7685 {
7686 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT80_rate[rateFlag];
7687 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT80_rate[rateFlag];
7688 }
7689 else if (rate_flags & eHAL_TX_RATE_VHT40)
7690 {
7691 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT40_rate[rateFlag];
7692 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT40_rate[rateFlag];
7693 }
7694 else if (rate_flags & eHAL_TX_RATE_VHT20)
7695 {
7696 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT20_rate[rateFlag];
7697 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT20_rate[rateFlag];
7698 }
7699
Leo Chang6f8870f2013-03-26 18:11:36 -07007700 maxSpeedMCS = 1;
7701 if (currentRate > maxRate)
7702 {
7703 maxRate = currentRate;
7704 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +05307705
Leo Chang6f8870f2013-03-26 18:11:36 -07007706 }
7707 else
7708#endif /* WLAN_FEATURE_11AC */
7709 {
7710 if (rate_flags & eHAL_TX_RATE_HT40)
7711 {
7712 rateFlag |= 1;
7713 }
7714 if (rate_flags & eHAL_TX_RATE_SGI)
7715 {
7716 rateFlag |= 2;
7717 }
7718
7719 for (i = 0; i < MCSLeng; i++)
7720 {
7721 temp = sizeof(supported_mcs_rate) / sizeof(supported_mcs_rate[0]);
7722 for (j = 0; j < temp; j++)
7723 {
7724 if (supported_mcs_rate[j].beacon_rate_index == MCSRates[i])
7725 {
7726 currentRate = supported_mcs_rate[j].supported_rate[rateFlag];
7727 break;
7728 }
7729 }
7730 if ((j < temp) && (currentRate > maxRate))
7731 {
7732 maxRate = currentRate;
7733 maxSpeedMCS = 1;
7734 maxMCSIdx = supported_mcs_rate[j].beacon_rate_index;
7735 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007736 }
7737 }
7738 }
7739
Gopichand Nakkala4c705372013-04-24 13:20:33 +05307740 else if (!(rate_flags & eHAL_TX_RATE_LEGACY))
7741 {
7742 maxRate = myRate;
7743 maxSpeedMCS = 1;
7744 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
7745 }
7746
Jeff Johnson295189b2012-06-20 16:38:30 -07007747 // make sure we report a value at least as big as our current rate
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07007748 if (((maxRate < myRate) && (0 == rssidx)) ||
7749 (0 == maxRate))
Jeff Johnson295189b2012-06-20 16:38:30 -07007750 {
7751 maxRate = myRate;
7752 if (rate_flags & eHAL_TX_RATE_LEGACY)
7753 {
7754 maxSpeedMCS = 0;
7755 }
7756 else
7757 {
7758 maxSpeedMCS = 1;
7759 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
7760 }
7761 }
7762
Gopichand Nakkala4c705372013-04-24 13:20:33 +05307763 if (rate_flags & eHAL_TX_RATE_LEGACY)
Jeff Johnson295189b2012-06-20 16:38:30 -07007764 {
7765 sinfo->txrate.legacy = maxRate;
7766#ifdef LINKSPEED_DEBUG_ENABLED
7767 pr_info("Reporting legacy rate %d\n", sinfo->txrate.legacy);
7768#endif //LINKSPEED_DEBUG_ENABLED
7769 }
7770 else
7771 {
7772 sinfo->txrate.mcs = maxMCSIdx;
Leo Chang6f8870f2013-03-26 18:11:36 -07007773#ifdef WLAN_FEATURE_11AC
7774 sinfo->txrate.nss = 1;
7775 if (rate_flags & eHAL_TX_RATE_VHT80)
7776 {
7777 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
Gopichand Nakkala4c705372013-04-24 13:20:33 +05307778 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
Leo Chang6f8870f2013-03-26 18:11:36 -07007779 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +05307780 else if (rate_flags & eHAL_TX_RATE_VHT40)
Leo Chang6f8870f2013-03-26 18:11:36 -07007781 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +05307782 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
7783 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
7784 }
7785 else if (rate_flags & eHAL_TX_RATE_VHT20)
7786 {
7787 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
7788 }
7789#endif /* WLAN_FEATURE_11AC */
7790 if (rate_flags & (eHAL_TX_RATE_HT20 | eHAL_TX_RATE_HT40))
7791 {
7792 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
7793 if (rate_flags & eHAL_TX_RATE_HT40)
7794 {
7795 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
7796 }
Leo Chang6f8870f2013-03-26 18:11:36 -07007797 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007798 if (rate_flags & eHAL_TX_RATE_SGI)
7799 {
7800 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
7801 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +05307802
Jeff Johnson295189b2012-06-20 16:38:30 -07007803#ifdef LINKSPEED_DEBUG_ENABLED
7804 pr_info("Reporting MCS rate %d flags %x\n",
7805 sinfo->txrate.mcs,
7806 sinfo->txrate.flags );
7807#endif //LINKSPEED_DEBUG_ENABLED
7808 }
7809 }
7810 else
7811 {
7812 // report current rate instead of max rate
7813
7814 if (rate_flags & eHAL_TX_RATE_LEGACY)
7815 {
7816 //provide to the UI in units of 100kbps
7817 sinfo->txrate.legacy = myRate;
7818#ifdef LINKSPEED_DEBUG_ENABLED
7819 pr_info("Reporting actual legacy rate %d\n", sinfo->txrate.legacy);
7820#endif //LINKSPEED_DEBUG_ENABLED
7821 }
7822 else
7823 {
7824 //must be MCS
7825 sinfo->txrate.mcs = pAdapter->hdd_stats.ClassA_stat.mcs_index;
Leo Chang6f8870f2013-03-26 18:11:36 -07007826#ifdef WLAN_FEATURE_11AC
7827 sinfo->txrate.nss = 1;
7828 if (rate_flags & eHAL_TX_RATE_VHT80)
7829 {
7830 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
7831 }
7832 else
7833#endif /* WLAN_FEATURE_11AC */
7834 {
7835 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
7836 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007837 if (rate_flags & eHAL_TX_RATE_SGI)
7838 {
7839 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
7840 }
7841 if (rate_flags & eHAL_TX_RATE_HT40)
7842 {
7843 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
7844 }
Leo Chang6f8870f2013-03-26 18:11:36 -07007845#ifdef WLAN_FEATURE_11AC
7846 else if (rate_flags & eHAL_TX_RATE_VHT80)
7847 {
7848 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
7849 }
7850#endif /* WLAN_FEATURE_11AC */
Jeff Johnson295189b2012-06-20 16:38:30 -07007851#ifdef LINKSPEED_DEBUG_ENABLED
7852 pr_info("Reporting actual MCS rate %d flags %x\n",
7853 sinfo->txrate.mcs,
7854 sinfo->txrate.flags );
7855#endif //LINKSPEED_DEBUG_ENABLED
7856 }
7857 }
7858 sinfo->filled |= STATION_INFO_TX_BITRATE;
7859
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -07007860 sinfo->tx_packets =
7861 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[0] +
7862 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[1] +
7863 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[2] +
7864 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[3];
7865
7866 sinfo->tx_retries =
7867 pAdapter->hdd_stats.summary_stat.retry_cnt[0] +
7868 pAdapter->hdd_stats.summary_stat.retry_cnt[1] +
7869 pAdapter->hdd_stats.summary_stat.retry_cnt[2] +
7870 pAdapter->hdd_stats.summary_stat.retry_cnt[3];
7871
7872 sinfo->tx_failed =
7873 pAdapter->hdd_stats.summary_stat.fail_cnt[0] +
7874 pAdapter->hdd_stats.summary_stat.fail_cnt[1] +
7875 pAdapter->hdd_stats.summary_stat.fail_cnt[2] +
7876 pAdapter->hdd_stats.summary_stat.fail_cnt[3];
7877
7878 sinfo->filled |=
7879 STATION_INFO_TX_PACKETS |
7880 STATION_INFO_TX_RETRIES |
7881 STATION_INFO_TX_FAILED;
7882
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307883 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7884 TRACE_CODE_HDD_CFG80211_GET_STA,
7885 pAdapter->sessionId, maxRate));
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -07007886 EXIT();
7887 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07007888}
7889
7890static int wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
Sameer Thalappilc9f26e92013-06-07 10:11:06 -07007891 struct net_device *dev, bool mode, int timeout)
Jeff Johnson295189b2012-06-20 16:38:30 -07007892{
7893 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +05307894 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07007895 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307896 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07007897
Jeff Johnsone7245742012-09-05 17:12:55 -07007898 ENTER();
7899
Jeff Johnson295189b2012-06-20 16:38:30 -07007900 if (NULL == pAdapter)
7901 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08007902 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007903 return -ENODEV;
7904 }
7905
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307906 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7907 TRACE_CODE_HDD_CFG80211_SET_POWER_MGMT,
7908 pAdapter->sessionId, timeout));
7909
Gopichand Nakkala20c4c042013-04-19 22:08:55 +05307910 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307911 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +05307912
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307913 if (0 != status)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307914 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307915 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7916 "%s: HDD context is not valid", __func__);
7917 return status;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307918 }
7919
Gopichand Nakkala20c4c042013-04-19 22:08:55 +05307920 if ((DRIVER_POWER_MODE_AUTO == !mode) &&
7921 (TRUE == pHddCtx->hdd_wlan_suspended) &&
7922 (pHddCtx->cfg_ini->fhostArpOffload) &&
7923 (eConnectionState_Associated ==
7924 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
7925 {
Amar Singhald53568e2013-09-26 11:03:45 -07007926
7927 hddLog(VOS_TRACE_LEVEL_INFO,
7928 "offload: in cfg80211_set_power_mgmt, calling arp offload");
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05307929 vos_status = hdd_conf_arp_offload(pAdapter, TRUE);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +05307930 if (!VOS_IS_STATUS_SUCCESS(vos_status))
7931 {
7932 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007933 "%s:Failed to enable ARPOFFLOAD Feature %d",
Gopichand Nakkala20c4c042013-04-19 22:08:55 +05307934 __func__, vos_status);
7935 }
7936 }
7937
Jeff Johnson295189b2012-06-20 16:38:30 -07007938 /**The get power cmd from the supplicant gets updated by the nl only
7939 *on successful execution of the function call
7940 *we are oppositely mapped w.r.t mode in the driver
7941 **/
7942 vos_status = wlan_hdd_enter_bmps(pAdapter, !mode);
7943
Jeff Johnsone7245742012-09-05 17:12:55 -07007944 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07007945 if (VOS_STATUS_E_FAILURE == vos_status)
7946 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307947 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7948 "%s: failed to enter bmps mode", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007949 return -EINVAL;
7950 }
7951 return 0;
7952}
7953
7954
7955#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
7956static int wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
7957 struct net_device *netdev,
7958 u8 key_index)
7959{
Jeff Johnsone7245742012-09-05 17:12:55 -07007960 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07007961 return 0;
7962}
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307963#endif //LINUX_VERSION_CODE
Jeff Johnson295189b2012-06-20 16:38:30 -07007964
7965#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
7966static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
7967 struct net_device *dev,
7968 struct ieee80211_txq_params *params)
7969{
Jeff Johnsone7245742012-09-05 17:12:55 -07007970 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07007971 return 0;
7972}
7973#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
7974static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
7975 struct ieee80211_txq_params *params)
7976{
Jeff Johnsone7245742012-09-05 17:12:55 -07007977 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07007978 return 0;
7979}
7980#endif //LINUX_VERSION_CODE
7981
7982static int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
7983 struct net_device *dev, u8 *mac)
7984{
7985 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307986 hdd_context_t *pHddCtx;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08007987 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307988 int status;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08007989 v_U8_t staId;
Jeff Johnson295189b2012-06-20 16:38:30 -07007990
Jeff Johnsone7245742012-09-05 17:12:55 -07007991 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307992
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307993 if ( NULL == pAdapter )
Jeff Johnson295189b2012-06-20 16:38:30 -07007994 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307995 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007996 return -EINVAL;
7997 }
7998
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307999 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
8000 TRACE_CODE_HDD_CFG80211_DEL_STA,
8001 pAdapter->sessionId, pAdapter->device_mode));
8002
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308003 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8004 status = wlan_hdd_validate_context(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07008005
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308006 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008007 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308008 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8009 "%s: HDD context is not valid", __func__);
8010 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008011 }
8012
Jeff Johnson295189b2012-06-20 16:38:30 -07008013 if ( (WLAN_HDD_SOFTAP == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -07008014 || (WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -07008015 )
8016 {
8017 if( NULL == mac )
8018 {
8019 v_U16_t i;
8020 for(i = 0; i < WLAN_MAX_STA_COUNT; i++)
8021 {
Rajesh Chauhan18488fc2013-08-22 10:15:03 -07008022 if ((pAdapter->aStaInfo[i].isUsed) &&
8023 (!pAdapter->aStaInfo[i].isDeauthInProgress))
Jeff Johnson295189b2012-06-20 16:38:30 -07008024 {
8025 u8 *macAddr = pAdapter->aStaInfo[i].macAddrSTA.bytes;
8026 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -08008027 "%s: Delete STA with MAC::"
8028 MAC_ADDRESS_STR,
8029 __func__, MAC_ADDR_ARRAY(macAddr));
Rajesh Chauhan18488fc2013-08-22 10:15:03 -07008030 vos_status = hdd_softap_sta_deauth(pAdapter, macAddr);
8031 if (VOS_IS_STATUS_SUCCESS(vos_status))
8032 pAdapter->aStaInfo[i].isDeauthInProgress = TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -07008033 }
8034 }
8035 }
8036 else
8037 {
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08008038
8039 vos_status = hdd_softap_GetStaId(pAdapter,(v_MACADDR_t *)mac, &staId);
8040 if (!VOS_IS_STATUS_SUCCESS(vos_status))
8041 {
8042 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -08008043 "%s: Skip this DEL STA as this is not used::"
8044 MAC_ADDRESS_STR,
8045 __func__, MAC_ADDR_ARRAY(mac));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08008046 return -ENOENT;
8047 }
8048
8049 if( pAdapter->aStaInfo[staId].isDeauthInProgress == TRUE)
8050 {
8051 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -08008052 "%s: Skip this DEL STA as deauth is in progress::"
8053 MAC_ADDRESS_STR,
8054 __func__, MAC_ADDR_ARRAY(mac));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08008055 return -ENOENT;
8056 }
8057
8058 pAdapter->aStaInfo[staId].isDeauthInProgress = TRUE;
8059
Jeff Johnson295189b2012-06-20 16:38:30 -07008060 hddLog(VOS_TRACE_LEVEL_INFO,
8061 "%s: Delete STA with MAC::"
Arif Hussain24bafea2013-11-15 15:10:03 -08008062 MAC_ADDRESS_STR,
Jeff Johnson295189b2012-06-20 16:38:30 -07008063 __func__,
Arif Hussain24bafea2013-11-15 15:10:03 -08008064 MAC_ADDR_ARRAY(mac));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08008065
8066 vos_status = hdd_softap_sta_deauth(pAdapter, mac);
8067 if (!VOS_IS_STATUS_SUCCESS(vos_status))
8068 {
8069 pAdapter->aStaInfo[staId].isDeauthInProgress = FALSE;
8070 hddLog(VOS_TRACE_LEVEL_INFO,
8071 "%s: STA removal failed for ::"
Arif Hussain24bafea2013-11-15 15:10:03 -08008072 MAC_ADDRESS_STR,
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08008073 __func__,
Arif Hussain24bafea2013-11-15 15:10:03 -08008074 MAC_ADDR_ARRAY(mac));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08008075 return -ENOENT;
8076 }
8077
Jeff Johnson295189b2012-06-20 16:38:30 -07008078 }
8079 }
8080
8081 EXIT();
8082
8083 return 0;
8084}
8085
Hoonki Lee11f7dda2013-02-14 16:55:44 -08008086static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
8087 struct net_device *dev, u8 *mac, struct station_parameters *params)
8088{
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308089 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkalab977a972013-02-18 19:15:09 -08008090 int status = -EPERM;
Hoonki Lee11f7dda2013-02-14 16:55:44 -08008091#ifdef FEATURE_WLAN_TDLS
8092 u32 mask, set;
Hoonki Lee11f7dda2013-02-14 16:55:44 -08008093 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308094
8095 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
8096 TRACE_CODE_HDD_CFG80211_ADD_STA,
8097 pAdapter->sessionId, params->listen_interval));
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008098 mask = params->sta_flags_mask;
8099
8100 set = params->sta_flags_set;
8101
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07008102#ifdef WLAN_FEATURE_TDLS_DEBUG
8103 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8104 "%s: mask 0x%x set 0x%x " MAC_ADDRESS_STR,
8105 __func__, mask, set, MAC_ADDR_ARRAY(mac));
8106#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008107
8108 if (mask & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
8109 if (set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008110 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 0, NULL);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008111 }
8112 }
8113#endif
Gopichand Nakkalab977a972013-02-18 19:15:09 -08008114 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -07008115}
8116
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008117
8118#ifdef FEATURE_WLAN_LFR
Wilson Yang6507c4e2013-10-01 20:11:19 -07008119
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008120static int wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
Jeff Johnsond13512a2012-07-17 11:42:19 -07008121 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008122{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308123 tANI_U32 j=0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008124 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Agarwal Ashish3da95242014-05-21 14:57:17 +05308125 hdd_station_ctx_t *pHddStaCtx;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008126 tHalHandle halHandle;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308127 eHalStatus result;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308128 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008129 tANI_U8 BSSIDMatched = 0;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308130 hdd_context_t *pHddCtx;
Jeff Johnson0299d0a2013-10-30 12:37:43 -07008131 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: set PMKSA for " MAC_ADDRESS_STR,
8132 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
Jeff Johnsone7245742012-09-05 17:12:55 -07008133
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308134 // Validate pAdapter
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308135 if ( NULL == pAdapter )
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008136 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308137 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008138 return -EINVAL;
8139 }
8140
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308141 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8142 status = wlan_hdd_validate_context(pHddCtx);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008143
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308144 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008145 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308146 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8147 "%s: HDD context is not valid", __func__);
8148 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008149 }
8150
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308151 // Retrieve halHandle
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008152 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
Agarwal Ashish3da95242014-05-21 14:57:17 +05308153 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008154
Agarwal Ashish3da95242014-05-21 14:57:17 +05308155 for (j = 0; j < pHddStaCtx->PMKIDCacheIndex; j++)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008156 {
Agarwal Ashish3da95242014-05-21 14:57:17 +05308157 if (vos_mem_compare(pHddStaCtx->PMKIDCache[j].BSSID,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008158 pmksa->bssid, WNI_CFG_BSSID_LEN))
8159 {
8160 /* BSSID matched previous entry. Overwrite it. */
8161 BSSIDMatched = 1;
Agarwal Ashish3da95242014-05-21 14:57:17 +05308162 vos_mem_copy(pHddStaCtx->PMKIDCache[j].BSSID,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008163 pmksa->bssid, WNI_CFG_BSSID_LEN);
Agarwal Ashish3da95242014-05-21 14:57:17 +05308164 vos_mem_copy(pHddStaCtx->PMKIDCache[j].PMKID,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308165 pmksa->pmkid,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008166 CSR_RSN_PMKID_SIZE);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308167 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Reusing cache entry %d.",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008168 __func__, j );
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008169 dump_bssid(pmksa->bssid);
8170 dump_pmkid(halHandle, pmksa->pmkid);
8171 break;
8172 }
8173 }
8174
Madan Mohan Koyyalamudic4b317d2012-10-18 19:43:08 -07008175 /* Check we compared all entries,if then take the first slot now */
Agarwal Ashish3da95242014-05-21 14:57:17 +05308176 if (j == MAX_PMKSAIDS_IN_CACHE) pHddStaCtx->PMKIDCacheIndex=0;
Madan Mohan Koyyalamudic4b317d2012-10-18 19:43:08 -07008177
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008178 if (!BSSIDMatched)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308179 {
8180 // Now, we DON'T have a BSSID match, so take a new entry in the cache.
Agarwal Ashish3da95242014-05-21 14:57:17 +05308181 vos_mem_copy(pHddStaCtx->PMKIDCache[pHddStaCtx->PMKIDCacheIndex].BSSID,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308182 pmksa->bssid, ETHER_ADDR_LEN);
Agarwal Ashish3da95242014-05-21 14:57:17 +05308183 vos_mem_copy(pHddStaCtx->PMKIDCache[pHddStaCtx->PMKIDCacheIndex].PMKID,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308184 pmksa->pmkid,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008185 CSR_RSN_PMKID_SIZE);
Agarwal Ashish3da95242014-05-21 14:57:17 +05308186 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: Adding a new cache entry %d.",
8187 __func__, pHddStaCtx->PMKIDCacheIndex );
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008188 dump_bssid(pmksa->bssid);
8189 dump_pmkid(halHandle, pmksa->pmkid);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308190 // Increment the HDD Local Cache index
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008191 // The "i=0" doesn't work for the call to sme_RoamSetPMKIDCache() - LFR FIXME
Agarwal Ashish3da95242014-05-21 14:57:17 +05308192 if (pHddStaCtx->PMKIDCacheIndex <= (MAX_PMKSAIDS_IN_CACHE-1))
8193 pHddStaCtx->PMKIDCacheIndex++;
8194 else
8195 pHddStaCtx->PMKIDCacheIndex = 0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008196 }
8197
8198
8199 // Calling csrRoamSetPMKIDCache to configure the PMKIDs into the cache
Agarwal Ashish3da95242014-05-21 14:57:17 +05308200 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: Calling csrRoamSetPMKIDCache with %d cache entries.",
8201 __func__, pHddStaCtx->PMKIDCacheIndex );
8202
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008203 // Finally set the PMKSA ID Cache in CSR
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308204 result = sme_RoamSetPMKIDCache(halHandle,pAdapter->sessionId,
Agarwal Ashish3da95242014-05-21 14:57:17 +05308205 pHddStaCtx->PMKIDCache,
8206 pHddStaCtx->PMKIDCacheIndex);
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308207 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
8208 TRACE_CODE_HDD_CFG80211_SET_PMKSA,
8209 pAdapter->sessionId, result));
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008210 return 0;
8211}
8212
8213
Wilson Yang6507c4e2013-10-01 20:11:19 -07008214
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008215static int wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
Wilson Yang6507c4e2013-10-01 20:11:19 -07008216 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008217{
Wilson Yang6507c4e2013-10-01 20:11:19 -07008218 tANI_U32 j=0;
8219 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Agarwal Ashish3da95242014-05-21 14:57:17 +05308220 hdd_station_ctx_t *pHddStaCtx;
Wilson Yang6507c4e2013-10-01 20:11:19 -07008221 tHalHandle halHandle;
Wilson Yang6507c4e2013-10-01 20:11:19 -07008222 tANI_U8 BSSIDMatched = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -07008223 hdd_context_t *pHddCtx;
Wilson Yangef657d32014-01-15 19:19:23 -08008224 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -07008225
Jeff Johnson0299d0a2013-10-30 12:37:43 -07008226 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: deleting PMKSA for " MAC_ADDRESS_STR,
8227 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
Wilson Yang6507c4e2013-10-01 20:11:19 -07008228
8229 /* Validate pAdapter */
8230 if (NULL == pAdapter)
8231 {
8232 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
8233 return -EINVAL;
8234 }
8235
8236 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8237 status = wlan_hdd_validate_context(pHddCtx);
8238
8239 if (0 != status)
8240 {
8241 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8242 "%s: HDD context is not valid", __func__);
8243 return status;
8244 }
8245
8246 /*Retrieve halHandle*/
8247 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
Agarwal Ashish3da95242014-05-21 14:57:17 +05308248 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Wilson Yang6507c4e2013-10-01 20:11:19 -07008249
8250 /*in case index is 0,no entry to delete*/
Agarwal Ashish3da95242014-05-21 14:57:17 +05308251 if (0 == pHddStaCtx->PMKIDCacheIndex)
Wilson Yang6507c4e2013-10-01 20:11:19 -07008252 {
Agarwal Ashish3da95242014-05-21 14:57:17 +05308253 hddLog(VOS_TRACE_LEVEL_INFO, FL("No entries to flush"));
8254 return 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -07008255 }
8256
8257 /*find the matching PMKSA entry from j=0 to (index-1),
8258 * and delete the matched one
8259 */
Agarwal Ashish3da95242014-05-21 14:57:17 +05308260 for (j = 0; j < pHddStaCtx->PMKIDCacheIndex; j++)
Wilson Yang6507c4e2013-10-01 20:11:19 -07008261 {
Agarwal Ashish3da95242014-05-21 14:57:17 +05308262 if (vos_mem_compare(pHddStaCtx->PMKIDCache[j].BSSID,
Wilson Yang6507c4e2013-10-01 20:11:19 -07008263 pmksa->bssid,
8264 WNI_CFG_BSSID_LEN))
8265 {
8266 /* BSSID matched entry */
8267 BSSIDMatched = 1;
Agarwal Ashish3da95242014-05-21 14:57:17 +05308268 if (j < pHddStaCtx->PMKIDCacheIndex-1)
Wilson Yang6507c4e2013-10-01 20:11:19 -07008269 {
8270 /*replace the matching entry with the last entry in HDD local cache*/
Agarwal Ashish3da95242014-05-21 14:57:17 +05308271 vos_mem_copy(pHddStaCtx->PMKIDCache[j].BSSID,
8272 pHddStaCtx->PMKIDCache[pHddStaCtx->PMKIDCacheIndex-1].BSSID,
8273 VOS_MAC_ADDR_SIZE);
8274 vos_mem_copy(pHddStaCtx->PMKIDCache[j].PMKID,
8275 pHddStaCtx->PMKIDCache[pHddStaCtx->PMKIDCacheIndex-1].PMKID,
8276 CSR_RSN_PMKID_SIZE);
8277 }
Wilson Yang6507c4e2013-10-01 20:11:19 -07008278
8279 /*clear the last entry in HDD cache ---[index-1]*/
Agarwal Ashish3da95242014-05-21 14:57:17 +05308280 vos_mem_zero(pHddStaCtx->PMKIDCache[pHddStaCtx->PMKIDCacheIndex-1].BSSID,
8281 VOS_MAC_ADDR_SIZE);
8282 vos_mem_zero(pHddStaCtx->PMKIDCache[pHddStaCtx->PMKIDCacheIndex-1].PMKID,
8283 CSR_RSN_PMKID_SIZE);
Wilson Yang6507c4e2013-10-01 20:11:19 -07008284 /*reduce the PMKID array index*/
Agarwal Ashish3da95242014-05-21 14:57:17 +05308285 pHddStaCtx->PMKIDCacheIndex--;
Wilson Yang6507c4e2013-10-01 20:11:19 -07008286 /*delete the last PMKID cache in CSR*/
Wilson Yangef657d32014-01-15 19:19:23 -08008287 if (eHAL_STATUS_SUCCESS !=
8288 sme_RoamDelPMKIDfromCache(halHandle, pAdapter->sessionId, pmksa->bssid))
Wilson Yang6507c4e2013-10-01 20:11:19 -07008289 {
8290 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: cannot delete PMKSA %d CONTENT.",
Agarwal Ashish3da95242014-05-21 14:57:17 +05308291 __func__, pHddStaCtx->PMKIDCacheIndex);
Wilson Yangef657d32014-01-15 19:19:23 -08008292 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -07008293 }
8294
8295 dump_bssid(pmksa->bssid);
8296 dump_pmkid(halHandle,pmksa->pmkid);
8297
8298 break;
8299 }
8300 }
8301
8302 /* we compare all entries,but cannot find matching entry */
8303 if (j == MAX_PMKSAIDS_IN_CACHE && !BSSIDMatched)
8304 {
Jeff Johnson0299d0a2013-10-30 12:37:43 -07008305 hddLog(VOS_TRACE_LEVEL_FATAL,
8306 "%s: No such PMKSA entry existed " MAC_ADDRESS_STR,
8307 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
Wilson Yang6507c4e2013-10-01 20:11:19 -07008308 dump_bssid(pmksa->bssid);
8309 dump_pmkid(halHandle, pmksa->pmkid);
8310 return -EINVAL;
8311 }
Wilson Yangef657d32014-01-15 19:19:23 -08008312 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008313}
8314
Wilson Yang6507c4e2013-10-01 20:11:19 -07008315
8316
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008317static int wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
8318{
Wilson Yang6507c4e2013-10-01 20:11:19 -07008319 tANI_U32 j=0;
8320 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Agarwal Ashish3da95242014-05-21 14:57:17 +05308321 hdd_station_ctx_t *pHddStaCtx;
Wilson Yang6507c4e2013-10-01 20:11:19 -07008322 tHalHandle halHandle;
8323 hdd_context_t *pHddCtx;
8324 tANI_U8 *pBSSId;
Wilson Yangef657d32014-01-15 19:19:23 -08008325 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -07008326
8327 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: flushing PMKSA ",__func__);
8328
8329 /* Validate pAdapter */
8330 if (NULL == pAdapter)
8331 {
8332 hddLog(VOS_TRACE_LEVEL_ERROR,
8333 "%s: Invalid Adapter" ,__func__);
8334 return -EINVAL;
8335 }
8336
8337 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8338 status = wlan_hdd_validate_context(pHddCtx);
8339
8340 if (0 != status)
8341 {
8342 hddLog(VOS_TRACE_LEVEL_ERROR,
8343 "%s: HDD context is not valid", __func__);
8344 return status;
8345 }
8346
8347 /*Retrieve halHandle*/
8348 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
Agarwal Ashish3da95242014-05-21 14:57:17 +05308349 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Wilson Yang6507c4e2013-10-01 20:11:19 -07008350
8351 /*in case index is 0,no entry to delete*/
Agarwal Ashish3da95242014-05-21 14:57:17 +05308352 if (0 == pHddStaCtx->PMKIDCacheIndex)
Wilson Yang6507c4e2013-10-01 20:11:19 -07008353 {
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +05308354 hddLog(VOS_TRACE_LEVEL_ERROR, FL("No entries to flush"));
Agarwal Ashish3da95242014-05-21 14:57:17 +05308355 return 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -07008356 }
8357
8358 /*delete all the PMKSA one by one */
Agarwal Ashish3da95242014-05-21 14:57:17 +05308359 for (j = 0; j < pHddStaCtx->PMKIDCacheIndex; j++)
Wilson Yang6507c4e2013-10-01 20:11:19 -07008360 {
Agarwal Ashish3da95242014-05-21 14:57:17 +05308361 pBSSId =(tANI_U8 *)(pHddStaCtx->PMKIDCache[j].BSSID);
Wilson Yang6507c4e2013-10-01 20:11:19 -07008362 /*delete the PMKID in CSR*/
Wilson Yangef657d32014-01-15 19:19:23 -08008363 if (eHAL_STATUS_SUCCESS !=
8364 sme_RoamDelPMKIDfromCache(halHandle, pAdapter->sessionId, pBSSId))
Wilson Yang6507c4e2013-10-01 20:11:19 -07008365 {
8366 hddLog(VOS_TRACE_LEVEL_ERROR ,"%s cannot flush PMKIDCache %d.",
8367 __func__,j);
Wilson Yangef657d32014-01-15 19:19:23 -08008368 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -07008369 }
Kiet Lam8d21d5b2013-10-31 17:18:29 +05308370 /*clear the entry in HDD cache 0--index-1 */
Agarwal Ashish3da95242014-05-21 14:57:17 +05308371 vos_mem_zero(pHddStaCtx->PMKIDCache[j].BSSID, VOS_MAC_ADDR_SIZE);
8372 vos_mem_zero(pHddStaCtx->PMKIDCache[j].PMKID, CSR_RSN_PMKID_SIZE);
8373 }
Wilson Yang6507c4e2013-10-01 20:11:19 -07008374
Agarwal Ashish3da95242014-05-21 14:57:17 +05308375 pHddStaCtx->PMKIDCacheIndex = 0;
Wilson Yangef657d32014-01-15 19:19:23 -08008376 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008377}
8378#endif
8379
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07008380#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308381static int wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07008382 struct net_device *dev, struct cfg80211_update_ft_ies_params *ftie)
8383{
8384 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
8385 hdd_station_ctx_t *pHddStaCtx;
8386
8387 if (NULL == pAdapter)
8388 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08008389 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07008390 return -ENODEV;
8391 }
8392
8393 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
8394
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308395 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
8396 TRACE_CODE_HDD_CFG80211_UPDATE_FT_IES,
8397 pAdapter->sessionId, pHddStaCtx->conn_info.connState));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07008398 // Added for debug on reception of Re-assoc Req.
8399 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
8400 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08008401 hddLog(LOGE, FL("Called with Ie of length = %zu when not associated"),
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07008402 ftie->ie_len);
Arif Hussain6d2a3322013-11-17 19:50:10 -08008403 hddLog(LOGE, FL("Should be Re-assoc Req IEs"));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07008404 }
8405
8406#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG
Arif Hussain6d2a3322013-11-17 19:50:10 -08008407 hddLog(LOGE, FL("%s called with Ie of length = %zu"), __func__,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07008408 ftie->ie_len);
8409#endif
8410
8411 // Pass the received FT IEs to SME
Gopichand Nakkala356fb102013-03-06 12:34:04 +05308412 sme_SetFTIEs( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
8413 (const u8 *)ftie->ie,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07008414 ftie->ie_len);
8415 return 0;
8416}
8417#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008418
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308419#ifdef FEATURE_WLAN_SCAN_PNO
8420
8421void hdd_cfg80211_sched_scan_done_callback(void *callbackContext,
8422 tSirPrefNetworkFoundInd *pPrefNetworkFoundInd)
8423{
8424 int ret;
8425 hdd_adapter_t* pAdapter = (hdd_adapter_t*)callbackContext;
8426 hdd_context_t *pHddCtx;
8427
Nirav Shah80830bf2013-12-31 16:35:12 +05308428 ENTER();
8429
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308430 if (NULL == pAdapter)
8431 {
Agarwal Ashish971c2882013-10-30 20:11:12 +05308432 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308433 "%s: HDD adapter is Null", __func__);
8434 return ;
8435 }
8436
8437 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8438 if (NULL == pHddCtx)
8439 {
8440 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8441 "%s: HDD context is Null!!!", __func__);
8442 return ;
8443 }
8444
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05308445 spin_lock(&pHddCtx->schedScan_lock);
8446 if (TRUE == pHddCtx->isWiphySuspended)
8447 {
8448 pHddCtx->isSchedScanUpdatePending = TRUE;
8449 spin_unlock(&pHddCtx->schedScan_lock);
8450 hddLog(VOS_TRACE_LEVEL_INFO,
8451 "%s: Update cfg80211 scan database after it resume", __func__);
8452 return ;
8453 }
8454 spin_unlock(&pHddCtx->schedScan_lock);
8455
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308456 ret = wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter);
8457
8458 if (0 > ret)
8459 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
8460
8461 cfg80211_sched_scan_results(pHddCtx->wiphy);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05308462 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8463 "%s: cfg80211 scan result database updated", __func__);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308464}
8465
8466/*
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +05308467 * FUNCTION: wlan_hdd_is_pno_allowed
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +05308468 * Disallow pno if any session is active
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +05308469 */
8470static eHalStatus wlan_hdd_is_pno_allowed(hdd_adapter_t *pAdapter)
8471{
8472 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
8473 hdd_adapter_t *pTempAdapter = NULL;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +05308474 hdd_station_ctx_t *pStaCtx;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +05308475 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8476 int status = 0;
8477 status = hdd_get_front_adapter(pHddCtx, &pAdapterNode);
8478
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +05308479 /* The current firmware design does not allow PNO during any
8480 * active sessions. Hence, determine the active sessions
8481 * and return a failure.
8482 */
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +05308483 while ((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status))
8484 {
8485 pTempAdapter = pAdapterNode->pAdapter;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +05308486 pStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pTempAdapter);
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +05308487
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +05308488 if (((WLAN_HDD_INFRA_STATION == pTempAdapter->device_mode)
8489 && (eConnectionState_NotConnected != pStaCtx->conn_info.connState))
8490 || (WLAN_HDD_P2P_CLIENT == pTempAdapter->device_mode)
8491 || (WLAN_HDD_P2P_GO == pTempAdapter->device_mode)
8492 || (WLAN_HDD_SOFTAP == pTempAdapter->device_mode)
8493 )
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +05308494 {
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +05308495 return eHAL_STATUS_FAILURE;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +05308496 }
8497 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
8498 pAdapterNode = pNext;
8499 }
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +05308500 return eHAL_STATUS_SUCCESS;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +05308501}
8502
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +05308503void hdd_cfg80211_sched_scan_start_status_cb(void *callbackContext, VOS_STATUS status)
8504{
8505 hdd_adapter_t *pAdapter = callbackContext;
8506 hdd_context_t *pHddCtx;
8507
8508 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
8509 {
8510 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8511 FL("Invalid adapter or adapter has invalid magic"));
8512 return;
8513 }
8514
8515 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8516 if (0 != wlan_hdd_validate_context(pHddCtx))
8517 {
8518 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8519 FL("HDD context is not valid"));
8520 return;
8521 }
8522
8523 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8524 FL("PNO enable response status = %d"), status);
8525
8526 pAdapter->pno_req_status = (status == VOS_STATUS_SUCCESS) ? 0 : -EBUSY;
8527 complete(&pAdapter->pno_comp_var);
8528}
8529
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +05308530/*
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308531 * FUNCTION: wlan_hdd_cfg80211_sched_scan_start
8532 * NL interface to enable PNO
8533 */
8534static int wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
8535 struct net_device *dev, struct cfg80211_sched_scan_request *request)
8536{
8537 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
8538 tpSirPNOScanReq pPnoRequest = NULL;
8539 hdd_context_t *pHddCtx;
8540 tHalHandle hHal;
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +05308541 v_U32_t i, indx, num_ch, tempInterval;
Sushant Kaushikd62d9782014-02-19 15:39:40 +05308542 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
8543 u8 channels_allowed[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308544 v_U32_t num_channels_allowed = WNI_CFG_VALID_CHANNEL_LIST_LEN;
8545 eHalStatus status = eHAL_STATUS_FAILURE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308546 int ret = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308547
8548 if (NULL == pAdapter)
8549 {
8550 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
8551 "%s: HDD adapter is Null", __func__);
8552 return -ENODEV;
8553 }
8554
8555 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05308556 ret = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308557
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05308558 if (0 != ret)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308559 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05308560 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8561 "%s: HDD context is not valid", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308562 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308563 }
8564
8565 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
8566 if (NULL == hHal)
8567 {
8568 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8569 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05308570 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308571 }
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +05308572
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05308573 ret = wlan_hdd_scan_abort(pAdapter);
8574 if (ret <= 0)
8575 {
8576 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8577 "%s: aborting the existing scan is unsuccessfull", __func__);
8578 return -EBUSY;
8579 }
8580
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +05308581 if (eHAL_STATUS_SUCCESS != wlan_hdd_is_pno_allowed(pAdapter))
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +05308582 {
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +05308583 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +05308584 FL("Cannot handle sched_scan"));
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +05308585 return -EBUSY;
8586 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308587
c_hpothu37f21312014-04-09 21:49:54 +05308588 if (TRUE == pHddCtx->isPnoEnable)
8589 {
8590 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
8591 FL("already PNO is enabled"));
8592 return -EBUSY;
8593 }
8594 pHddCtx->isPnoEnable = TRUE;
8595
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308596 pPnoRequest = (tpSirPNOScanReq) vos_mem_malloc(sizeof (tSirPNOScanReq));
8597 if (NULL == pPnoRequest)
8598 {
8599 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
8600 "%s: vos_mem_malloc failed", __func__);
c_hpothu37f21312014-04-09 21:49:54 +05308601 pHddCtx->isPnoEnable = FALSE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308602 return -ENOMEM;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308603 }
8604
Madan Mohan Koyyalamudic3f04352013-09-26 19:21:48 +05308605 memset(pPnoRequest, 0, sizeof (tSirPNOScanReq));
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308606 pPnoRequest->enable = 1; /*Enable PNO */
8607 pPnoRequest->ucNetworksCount = request->n_match_sets;
8608
8609 if (( !pPnoRequest->ucNetworksCount ) ||
8610 ( pPnoRequest->ucNetworksCount > SIR_PNO_MAX_SUPP_NETWORKS ))
8611 {
8612 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik1e406c32014-05-09 15:57:52 +05308613 "%s: Network input is not correct %d Max Network supported is %d",
8614 __func__, pPnoRequest->ucNetworksCount,
8615 SIR_PNO_MAX_SUPP_NETWORKS);
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308616 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308617 goto error;
8618 }
8619
8620 if ( SIR_PNO_MAX_NETW_CHANNELS_EX < request->n_channels )
8621 {
8622 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +05308623 "%s: Incorrect number of channels %d",
8624 __func__, request->n_channels);
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308625 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308626 goto error;
8627 }
8628
8629 /* Framework provides one set of channels(all)
8630 * common for all saved profile */
8631 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
8632 channels_allowed, &num_channels_allowed))
8633 {
8634 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8635 "%s: failed to get valid channel list", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308636 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308637 goto error;
8638 }
8639 /* Checking each channel against allowed channel list */
8640 num_ch = 0;
Nirav Shah80830bf2013-12-31 16:35:12 +05308641 if (request->n_channels)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308642 {
Nirav Shah80830bf2013-12-31 16:35:12 +05308643 char chList [(request->n_channels*5)+1];
8644 int len;
8645 for (i = 0, len = 0; i < request->n_channels; i++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308646 {
Nirav Shah80830bf2013-12-31 16:35:12 +05308647 for (indx = 0; indx < num_channels_allowed; indx++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308648 {
Nirav Shah80830bf2013-12-31 16:35:12 +05308649 if (request->channels[i]->hw_value == channels_allowed[indx])
8650 {
8651 valid_ch[num_ch++] = request->channels[i]->hw_value;
8652 len += snprintf(chList+len, 5, "%d ",
8653 request->channels[i]->hw_value);
8654 break ;
8655 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308656 }
8657 }
Nirav Shah80830bf2013-12-31 16:35:12 +05308658 hddLog(VOS_TRACE_LEVEL_INFO,"Channel-List: %s ", chList);
8659 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308660
8661 /* Filling per profile params */
8662 for (i = 0; i < pPnoRequest->ucNetworksCount; i++)
8663 {
8664 pPnoRequest->aNetworks[i].ssId.length =
8665 request->match_sets[i].ssid.ssid_len;
8666
8667 if (( 0 == pPnoRequest->aNetworks[i].ssId.length ) ||
8668 ( pPnoRequest->aNetworks[i].ssId.length > 32 ) )
8669 {
8670 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +05308671 "%s: SSID Len %d is not correct for network %d",
8672 __func__, pPnoRequest->aNetworks[i].ssId.length, i);
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308673 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308674 goto error;
8675 }
8676
8677 memcpy(pPnoRequest->aNetworks[i].ssId.ssId,
8678 request->match_sets[i].ssid.ssid,
8679 request->match_sets[i].ssid.ssid_len);
Sushant Kaushik1e406c32014-05-09 15:57:52 +05308680 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8681 "%s: SSID of network %d is %s ", __func__,
8682 i, pPnoRequest->aNetworks[i].ssId.ssId);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308683 pPnoRequest->aNetworks[i].authentication = 0; /*eAUTH_TYPE_ANY*/
8684 pPnoRequest->aNetworks[i].encryption = 0; /*eED_ANY*/
8685 pPnoRequest->aNetworks[i].bcastNetwType = 0; /*eBCAST_UNKNOWN*/
8686
8687 /*Copying list of valid channel into request */
8688 memcpy(pPnoRequest->aNetworks[i].aChannels, valid_ch, num_ch);
8689 pPnoRequest->aNetworks[i].ucChannelCount = num_ch;
8690
8691 pPnoRequest->aNetworks[i].rssiThreshold = 0; //Default value
8692 }
8693
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +05308694 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnson59a121e2013-11-30 09:46:08 -08008695 "request->ie_len = %zu", request->ie_len);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +05308696 if ((0 < request->ie_len) && (NULL != request->ie))
8697 {
8698 pPnoRequest->us24GProbeTemplateLen = request->ie_len;
8699 memcpy(&pPnoRequest->p24GProbeTemplate, request->ie,
8700 pPnoRequest->us24GProbeTemplateLen);
8701
8702 pPnoRequest->us5GProbeTemplateLen = request->ie_len;
8703 memcpy(&pPnoRequest->p5GProbeTemplate, request->ie,
8704 pPnoRequest->us5GProbeTemplateLen);
8705 }
8706
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +05308707 /* Driver gets only one time interval which is hardcoded in
8708 * supplicant for 10000ms. Taking power consumption into account 6 timers
8709 * will be used, Timervalue is increased exponentially i.e 10,20,40,
8710 * 80,160,320 secs. And number of scan cycle for each timer
8711 * is configurable through INI param gPNOScanTimerRepeatValue.
8712 * If it is set to 0 only one timer will be used and PNO scan cycle
8713 * will be repeated after each interval specified by supplicant
8714 * till PNO is disabled.
8715 */
8716 if (0 == pHddCtx->cfg_ini->configPNOScanTimerRepeatValue)
8717 pPnoRequest->scanTimers.ucScanTimersCount = HDD_PNO_SCAN_TIMERS_SET_ONE;
8718 else
8719 pPnoRequest->scanTimers.ucScanTimersCount =
8720 HDD_PNO_SCAN_TIMERS_SET_MULTIPLE;
8721
8722 tempInterval = (request->interval)/1000;
8723 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8724 "Base scan interval = %d PNOScanTimerRepeatValue = %d",
8725 tempInterval, pHddCtx->cfg_ini->configPNOScanTimerRepeatValue);
8726 for ( i = 0; i < pPnoRequest->scanTimers.ucScanTimersCount; i++)
8727 {
8728 pPnoRequest->scanTimers.aTimerValues[i].uTimerRepeat =
8729 pHddCtx->cfg_ini->configPNOScanTimerRepeatValue;
8730 pPnoRequest->scanTimers.aTimerValues[i].uTimerValue = tempInterval;
8731 tempInterval *= 2;
8732 }
8733 //Repeat last timer until pno disabled.
8734 pPnoRequest->scanTimers.aTimerValues[i-1].uTimerRepeat = 0;
8735
Madan Mohan Koyyalamudid206c7b2013-09-26 22:54:51 +05308736 pPnoRequest->modePNO = SIR_PNO_MODE_IMMEDIATE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308737
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +05308738 INIT_COMPLETION(pAdapter->pno_comp_var);
8739 pPnoRequest->statusCallback = hdd_cfg80211_sched_scan_start_status_cb;
8740 pPnoRequest->callbackContext = pAdapter;
8741 pAdapter->pno_req_status = 0;
8742
Nirav Shah80830bf2013-12-31 16:35:12 +05308743 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8744 "SessionId %d, enable %d, modePNO %d, ucScanTimersCount %d",
8745 pAdapter->sessionId, pPnoRequest->enable, pPnoRequest->modePNO,
8746 pPnoRequest->scanTimers.ucScanTimersCount);
8747
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308748 status = sme_SetPreferredNetworkList(WLAN_HDD_GET_HAL_CTX(pAdapter),
8749 pPnoRequest, pAdapter->sessionId,
8750 hdd_cfg80211_sched_scan_done_callback, pAdapter);
8751 if (eHAL_STATUS_SUCCESS != status)
8752 {
8753 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +05308754 "%s: Failed to enable PNO", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308755 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308756 goto error;
8757 }
8758
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +05308759 ret = wait_for_completion_timeout(
8760 &pAdapter->pno_comp_var,
8761 msecs_to_jiffies(WLAN_WAIT_TIME_PNO));
8762 if (0 >= ret)
8763 {
8764 // Did not receive the response for PNO enable in time.
8765 // Assuming the PNO enable was success.
8766 // Returning error from here, because we timeout, results
8767 // in side effect of Wifi (Wifi Setting) not to work.
8768 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8769 FL("Timed out waiting for PNO to be Enabled"));
8770 ret = 0;
8771 goto error;
8772 }
8773
8774 ret = pAdapter->pno_req_status;
c_hpothu37f21312014-04-09 21:49:54 +05308775 return ret;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05308776
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308777error:
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +05308778 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8779 FL("PNO scanRequest offloaded ret = %d"), ret);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308780 vos_mem_free(pPnoRequest);
c_hpothu37f21312014-04-09 21:49:54 +05308781 pHddCtx->isPnoEnable = FALSE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308782 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308783}
8784
8785/*
8786 * FUNCTION: wlan_hdd_cfg80211_sched_scan_stop
8787 * NL interface to disable PNO
8788 */
8789static int wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
8790 struct net_device *dev)
8791{
8792 eHalStatus status = eHAL_STATUS_FAILURE;
8793 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
8794 hdd_context_t *pHddCtx;
8795 tHalHandle hHal;
8796 tpSirPNOScanReq pPnoRequest = NULL;
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308797 int ret = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308798
8799 ENTER();
8800
8801 if (NULL == pAdapter)
8802 {
8803 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
8804 "%s: HDD adapter is Null", __func__);
8805 return -ENODEV;
8806 }
8807
8808 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308809
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308810 if (NULL == pHddCtx)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308811 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05308812 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308813 "%s: HDD context is Null", __func__);
8814 return -ENODEV;
8815 }
8816
8817 /* The return 0 is intentional when isLogpInProgress and
8818 * isLoadUnloadInProgress. We did observe a crash due to a return of
8819 * failure in sched_scan_stop , especially for a case where the unload
8820 * of the happens at the same time. The function __cfg80211_stop_sched_scan
8821 * was clearing rdev->sched_scan_req only when the sched_scan_stop returns
8822 * success. If it returns a failure , then its next invocation due to the
8823 * clean up of the second interface will have the dev pointer corresponding
8824 * to the first one leading to a crash.
8825 */
8826 if (pHddCtx->isLogpInProgress)
8827 {
8828 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8829 "%s: LOGP in Progress. Ignore!!!", __func__);
8830 return ret;
8831 }
8832
Mihir Shete18156292014-03-11 15:38:30 +05308833 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308834 {
8835 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8836 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
8837 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308838 }
8839
8840 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
8841 if (NULL == hHal)
8842 {
8843 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8844 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05308845 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308846 }
8847
8848 pPnoRequest = (tpSirPNOScanReq) vos_mem_malloc(sizeof (tSirPNOScanReq));
8849 if (NULL == pPnoRequest)
8850 {
8851 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
8852 "%s: vos_mem_malloc failed", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308853 return -ENOMEM;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308854 }
8855
8856 memset(pPnoRequest, 0, sizeof (tSirPNOScanReq));
8857 pPnoRequest->enable = 0; /* Disable PNO */
8858 pPnoRequest->ucNetworksCount = 0;
8859
8860 status = sme_SetPreferredNetworkList(hHal, pPnoRequest,
8861 pAdapter->sessionId,
8862 NULL, pAdapter);
8863 if (eHAL_STATUS_SUCCESS != status)
8864 {
8865 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8866 "Failed to disabled PNO");
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308867 ret = -EINVAL;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +05308868 goto error;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308869 }
c_hpothu37f21312014-04-09 21:49:54 +05308870 pHddCtx->isPnoEnable = FALSE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308871
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +05308872error:
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05308873 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +05308874 FL("PNO scan disabled ret = %d"), ret);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308875 vos_mem_free(pPnoRequest);
8876
8877 EXIT();
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308878 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308879}
8880
8881#endif /*FEATURE_WLAN_SCAN_PNO*/
8882
8883
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008884#ifdef FEATURE_WLAN_TDLS
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +05308885#if TDLS_MGMT_VERSION2
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008886static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
8887 u8 *peer, u8 action_code, u8 dialog_token,
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +05308888 u16 status_code, u32 peer_capability, const u8 *buf, size_t len)
8889#else
8890static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
8891 u8 *peer, u8 action_code, u8 dialog_token,
8892 u16 status_code, const u8 *buf, size_t len)
8893#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008894{
8895
8896 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
8897 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008898 u8 peerMac[6];
8899 VOS_STATUS status;
Gopichand Nakkala05922802013-03-14 12:23:19 -07008900 int max_sta_failed = 0;
Hoonki Leea34dd892013-02-05 22:56:02 -08008901 int responder;
Hoonki Leed37cbb32013-04-20 00:31:14 -07008902 long rc;
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +05308903#if !(TDLS_MGMT_VERSION2)
8904 u32 peer_capability = 0;
8905#endif
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05308906 tANI_U16 numCurrTdlsPeers;
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008907
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308908 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
8909 TRACE_CODE_HDD_CFG80211_TDLS_MGMT,
8910 pAdapter->sessionId, action_code));
Hoonki Lee11f7dda2013-02-14 16:55:44 -08008911 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008912 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308913 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008914 "Invalid arguments");
8915 return -EINVAL;
8916 }
8917
Sameer Thalappil75ea31a2013-02-21 19:38:16 -08008918 if (pHddCtx->isLogpInProgress)
8919 {
8920 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8921 "%s:LOGP in Progress. Ignore!!!", __func__);
Gopichand Nakkala05922802013-03-14 12:23:19 -07008922 wlan_hdd_tdls_set_link_status(pAdapter, peer, eTDLS_LINK_IDLE);
Sameer Thalappil75ea31a2013-02-21 19:38:16 -08008923 return -EBUSY;
8924 }
8925
Hoonki Lee27511902013-03-14 18:19:06 -07008926 if (eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode)
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008927 {
Hoonki Lee27511902013-03-14 18:19:06 -07008928 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
8929 "%s: TDLS mode is disabled OR not enabled in FW."
8930 MAC_ADDRESS_STR " action %d declined.",
8931 __func__, MAC_ADDR_ARRAY(peer), action_code);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008932 return -ENOTSUPP;
8933 }
Lee Hoonkic1262f22013-01-24 21:59:00 -08008934
Hoonki Lee27511902013-03-14 18:19:06 -07008935 /* other than teardown frame, other mgmt frames are not sent if disabled */
8936 if (SIR_MAC_TDLS_TEARDOWN != action_code)
8937 {
8938 /* if tdls_mode is disabled to respond to peer's request */
8939 if (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode)
8940 {
8941 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
8942 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07008943 " TDLS mode is disabled. action %d declined.",
8944 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee27511902013-03-14 18:19:06 -07008945
8946 return -ENOTSUPP;
8947 }
8948 }
8949
Gopichand Nakkalab977a972013-02-18 19:15:09 -08008950 if (WLAN_IS_TDLS_SETUP_ACTION(action_code))
8951 {
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308952 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, peer, TRUE))
Gopichand Nakkalab977a972013-02-18 19:15:09 -08008953 {
8954 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07008955 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07008956 " TDLS setup is ongoing. action %d declined.",
8957 __func__, MAC_ADDR_ARRAY(peer), action_code);
8958 return -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -08008959 }
8960 }
8961
Hoonki Lee11f7dda2013-02-14 16:55:44 -08008962 if (SIR_MAC_TDLS_SETUP_REQ == action_code ||
8963 SIR_MAC_TDLS_SETUP_RSP == action_code )
Lee Hoonkic1262f22013-01-24 21:59:00 -08008964 {
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05308965 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
8966 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Lee Hoonkic1262f22013-01-24 21:59:00 -08008967 {
8968 /* supplicant still sends tdls_mgmt(SETUP_REQ) even after
8969 we return error code at 'add_station()'. Hence we have this
8970 check again in addtion to add_station().
8971 Anyway, there is no hard to double-check. */
Hoonki Lee11f7dda2013-02-14 16:55:44 -08008972 if (SIR_MAC_TDLS_SETUP_REQ == action_code)
Lee Hoonkic1262f22013-01-24 21:59:00 -08008973 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07008974 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8975 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05308976 " TDLS Max peer already connected. action (%d) declined. Num of peers (%d), Max allowed (%d).",
8977 __func__, MAC_ADDR_ARRAY(peer), action_code,
8978 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Sunil Dutt388ac8f2013-11-28 18:06:52 +05308979 return -EINVAL;
Lee Hoonkic1262f22013-01-24 21:59:00 -08008980 }
8981 else
8982 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -08008983 /* maximum reached. tweak to send error code to peer and return
8984 error code to supplicant */
Lee Hoonkic1262f22013-01-24 21:59:00 -08008985 status_code = eSIR_MAC_UNSPEC_FAILURE_STATUS;
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07008986 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8987 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05308988 " TDLS Max peer already connected, send response status (%d). Num of peers (%d), Max allowed (%d).",
8989 __func__, MAC_ADDR_ARRAY(peer), status_code,
8990 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -07008991 max_sta_failed = -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -08008992 /* fall through to send setup resp with failure status
8993 code */
Lee Hoonkic1262f22013-01-24 21:59:00 -08008994 }
8995 }
Hoonki Lee11f7dda2013-02-14 16:55:44 -08008996 else
8997 {
8998 hddTdlsPeer_t *pTdlsPeer;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308999 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009000 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Hoonki Lee11f7dda2013-02-14 16:55:44 -08009001 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07009002 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07009003 "%s:" MAC_ADDRESS_STR " already connected. action %d declined.",
9004 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee11f7dda2013-02-14 16:55:44 -08009005 return -EPERM;
9006 }
9007 }
Lee Hoonkic1262f22013-01-24 21:59:00 -08009008 }
Hoonki Lee11f7dda2013-02-14 16:55:44 -08009009 vos_mem_copy(peerMac, peer, 6);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009010
Hoonki Lee1090c6a2013-01-16 17:40:54 -08009011#ifdef WLAN_FEATURE_TDLS_DEBUG
9012 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +05309013 "%s: " MAC_ADDRESS_STR " action %d, dialog_token %d status %d, len = %zu",
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07009014 "tdls_mgmt", MAC_ADDR_ARRAY(peer),
9015 action_code, dialog_token, status_code, len);
Hoonki Lee1090c6a2013-01-16 17:40:54 -08009016#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009017
Hoonki Leea34dd892013-02-05 22:56:02 -08009018 /*Except teardown responder will not be used so just make 0*/
9019 responder = 0;
Hoonki Lee11f7dda2013-02-14 16:55:44 -08009020 if (SIR_MAC_TDLS_TEARDOWN == action_code)
Hoonki Leea34dd892013-02-05 22:56:02 -08009021 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -07009022
9023 hddTdlsPeer_t *pTdlsPeer;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05309024 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peerMac, TRUE);
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -07009025
9026 if(pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
9027 responder = pTdlsPeer->is_responder;
9028 else
Hoonki Leea34dd892013-02-05 22:56:02 -08009029 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -07009030 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +05309031 "%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 -07009032 __func__, MAC_ADDR_ARRAY(peer), (NULL == pTdlsPeer) ? -1 : pTdlsPeer->link_status,
9033 dialog_token, status_code, len);
9034 return -EPERM;
Hoonki Leea34dd892013-02-05 22:56:02 -08009035 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009036 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009037
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +05309038 /* For explicit trigger of DIS_REQ come out of BMPS for
9039 successfully receiving DIS_RSP from peer. */
Hoonki Lee14621352013-04-16 17:51:19 -07009040 if ((SIR_MAC_TDLS_SETUP_RSP == action_code) ||
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +05309041 (SIR_MAC_TDLS_DIS_RSP == action_code) ||
9042 (SIR_MAC_TDLS_DIS_REQ == action_code))
Hoonki Lee14621352013-04-16 17:51:19 -07009043 {
9044 if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter)))
9045 {
9046 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +05309047 "%s: Sending frame action_code %u.Disable BMPS", __func__, action_code);
Hoonki Lee14621352013-04-16 17:51:19 -07009048 hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
9049 }
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +05309050 if (SIR_MAC_TDLS_DIS_REQ != action_code)
9051 wlan_hdd_tdls_set_cap(pAdapter, peerMac, eTDLS_CAP_SUPPORTED);
Hoonki Lee14621352013-04-16 17:51:19 -07009052 }
9053
Hoonki Lee5305c3a2013-04-29 23:28:59 -07009054 /* make sure doesn't call send_mgmt() while it is pending */
9055 if (TDLS_CTX_MAGIC == pAdapter->mgmtTxCompletionStatus)
9056 {
9057 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009058 "%s: " MAC_ADDRESS_STR " action %d couldn't sent, as one is pending. return EBUSY",
Hoonki Lee5305c3a2013-04-29 23:28:59 -07009059 __func__, MAC_ADDR_ARRAY(peer), action_code);
9060 return -EBUSY;
9061 }
9062
9063 pAdapter->mgmtTxCompletionStatus = TDLS_CTX_MAGIC;
Gopichand Nakkalab977a972013-02-18 19:15:09 -08009064 INIT_COMPLETION(pAdapter->tdls_mgmt_comp);
9065
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009066 status = sme_SendTdlsMgmtFrame(WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
Pradeep Reddy POTTETIca171f82014-03-21 14:17:35 +05309067 peerMac, action_code, dialog_token, status_code, peer_capability, (tANI_U8 *)buf, len, responder);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009068
Gopichand Nakkalab977a972013-02-18 19:15:09 -08009069 if (VOS_STATUS_SUCCESS != status)
9070 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009071 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9072 "%s: sme_SendTdlsMgmtFrame failed!", __func__);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07009073 pAdapter->mgmtTxCompletionStatus = FALSE;
Hoonki Lee14621352013-04-16 17:51:19 -07009074 wlan_hdd_tdls_check_bmps(pAdapter);
Sunil Dutt388ac8f2013-11-28 18:06:52 +05309075 return -EINVAL;
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009076 }
9077
Hoonki Leed37cbb32013-04-20 00:31:14 -07009078 rc = wait_for_completion_interruptible_timeout(&pAdapter->tdls_mgmt_comp,
9079 msecs_to_jiffies(WAIT_TIME_TDLS_MGMT));
9080
9081 if ((rc <= 0) || (TRUE != pAdapter->mgmtTxCompletionStatus))
Gopichand Nakkalab977a972013-02-18 19:15:09 -08009082 {
Hoonki Leed37cbb32013-04-20 00:31:14 -07009083 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07009084 "%s: Mgmt Tx Completion failed status %ld TxCompletion %u",
Hoonki Leed37cbb32013-04-20 00:31:14 -07009085 __func__, rc, pAdapter->mgmtTxCompletionStatus);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07009086 pAdapter->mgmtTxCompletionStatus = FALSE;
Yue Ma4f55ef32014-01-23 16:45:33 -08009087
9088 if (pHddCtx->isLogpInProgress)
9089 {
9090 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9091 "%s: LOGP in Progress. Ignore!!!", __func__);
9092 return -EAGAIN;
9093 }
9094
Hoonki Leed37cbb32013-04-20 00:31:14 -07009095 wlan_hdd_tdls_check_bmps(pAdapter);
Sunil Dutt388ac8f2013-11-28 18:06:52 +05309096 return -EINVAL;
Gopichand Nakkalab977a972013-02-18 19:15:09 -08009097 }
9098
Gopichand Nakkala05922802013-03-14 12:23:19 -07009099 if (max_sta_failed)
Hoonki Lee14621352013-04-16 17:51:19 -07009100 {
9101 wlan_hdd_tdls_check_bmps(pAdapter);
Gopichand Nakkala05922802013-03-14 12:23:19 -07009102 return max_sta_failed;
Hoonki Lee14621352013-04-16 17:51:19 -07009103 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -08009104
Hoonki Leea34dd892013-02-05 22:56:02 -08009105 if (SIR_MAC_TDLS_SETUP_RSP == action_code)
9106 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -08009107 wlan_hdd_tdls_set_responder(pAdapter, peerMac, TRUE);
Hoonki Leea34dd892013-02-05 22:56:02 -08009108 }
9109 else if (SIR_MAC_TDLS_SETUP_CNF == action_code)
9110 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -08009111 wlan_hdd_tdls_set_responder(pAdapter, peerMac, FALSE);
Hoonki Leea34dd892013-02-05 22:56:02 -08009112 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009113
9114 return 0;
9115}
9116
9117static int wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
9118 u8 *peer, enum nl80211_tdls_operation oper)
9119{
9120 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
9121 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309122 int status;
Hoonki Lee5305c3a2013-04-29 23:28:59 -07009123 hddTdlsPeer_t *pTdlsPeer;
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009124
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309125 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
9126 TRACE_CODE_HDD_CFG80211_TDLS_OPER,
9127 pAdapter->sessionId, oper));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309128 if ( NULL == peer )
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009129 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -08009130 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chilam Ngc4244af2013-04-01 15:37:32 -07009131 "%s: Invalid arguments", __func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009132 return -EINVAL;
9133 }
Hoonki Lee1090c6a2013-01-16 17:40:54 -08009134
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309135 status = wlan_hdd_validate_context(pHddCtx);
9136
9137 if (0 != status)
Sameer Thalappil75ea31a2013-02-21 19:38:16 -08009138 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309139 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9140 "%s: HDD context is not valid", __func__);
9141 return status;
Sameer Thalappil75ea31a2013-02-21 19:38:16 -08009142 }
9143
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009144
9145 if( FALSE == pHddCtx->cfg_ini->fEnableTDLSSupport ||
Hoonki Lee1090c6a2013-01-16 17:40:54 -08009146 FALSE == sme_IsFeatureSupportedByFW(TDLS))
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009147 {
Hoonki Lee1090c6a2013-01-16 17:40:54 -08009148 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chilam Ngc4244af2013-04-01 15:37:32 -07009149 "TDLS Disabled in INI OR not enabled in FW. "
9150 "Cannot process TDLS commands");
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009151 return -ENOTSUPP;
9152 }
9153
9154 switch (oper) {
9155 case NL80211_TDLS_ENABLE_LINK:
9156 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009157 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309158 long ret;
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05309159 tCsrTdlsLinkEstablishParams tdlsLinkEstablishParams;
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009160
Sunil Dutt41de4e22013-11-14 18:09:02 +05309161 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
9162
9163 if ( NULL == pTdlsPeer ) {
9164 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
9165 " (oper %d) not exsting. ignored",
9166 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
9167 return -EINVAL;
9168 }
9169
9170 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9171 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
9172 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
9173 "NL80211_TDLS_ENABLE_LINK");
9174
Gopichand Nakkala2f4a2822013-04-17 11:22:01 -07009175 if (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
9176 {
9177 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Staion Index %u "
9178 MAC_ADDRESS_STR " failed",
9179 __func__, pTdlsPeer->staId, MAC_ADDR_ARRAY(peer));
9180 return -EINVAL;
9181 }
9182
Hoonki Lee5305c3a2013-04-29 23:28:59 -07009183 if (eTDLS_LINK_CONNECTED != pTdlsPeer->link_status)
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07009184 {
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +05309185 if (IS_ADVANCE_TDLS_ENABLE) {
Gopichand Nakkala24be5312013-07-02 16:47:12 +05309186
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +05309187 if (0 != wlan_hdd_tdls_get_link_establish_params(
9188 pAdapter, peer,&tdlsLinkEstablishParams)) {
9189 return -EINVAL;
9190 }
9191 INIT_COMPLETION(pAdapter->tdls_link_establish_req_comp);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05309192
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +05309193 sme_SendTdlsLinkEstablishParams(WLAN_HDD_GET_HAL_CTX(pAdapter),
9194 pAdapter->sessionId, peer, &tdlsLinkEstablishParams);
9195 /* Send TDLS peer UAPSD capabilities to the firmware and
9196 * register with the TL on after the response for this operation
9197 * is received .
9198 */
9199 ret = wait_for_completion_interruptible_timeout(
9200 &pAdapter->tdls_link_establish_req_comp,
9201 msecs_to_jiffies(WAIT_TIME_TDLS_LINK_ESTABLISH_REQ));
9202 if (ret <= 0)
9203 {
9204 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9205 "%s: Link Establish Request Faled Status %ld",
9206 __func__, ret);
9207 return -EINVAL;
9208 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05309209 }
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -07009210 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer, eTDLS_LINK_CONNECTED);
Gopichand Nakkala471708b2013-06-04 20:03:01 +05309211 /* Mark TDLS client Authenticated .*/
9212 status = WLANTL_ChangeSTAState( pHddCtx->pvosContext,
9213 pTdlsPeer->staId,
9214 WLANTL_STA_AUTHENTICATED);
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -07009215 if (VOS_STATUS_SUCCESS == status)
9216 {
Hoonki Lee14621352013-04-16 17:51:19 -07009217 if (pTdlsPeer->is_responder == 0)
9218 {
9219 v_U8_t staId = (v_U8_t)pTdlsPeer->staId;
9220
9221 wlan_hdd_tdls_timer_restart(pAdapter,
9222 &pTdlsPeer->initiatorWaitTimeoutTimer,
9223 WAIT_TIME_TDLS_INITIATOR);
9224 /* suspend initiator TX until it receives direct packet from the
9225 reponder or WAIT_TIME_TDLS_INITIATOR timer expires */
9226 WLANTL_SuspendDataTx( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
9227 &staId, NULL);
9228 }
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -07009229 wlan_hdd_tdls_increment_peer_count(pAdapter);
9230 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07009231 wlan_hdd_tdls_check_bmps(pAdapter);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05309232
9233 /* Update TL about the UAPSD masks , to route the packets to firmware */
Gopichand Nakkala574f6d12013-06-27 19:38:43 +05309234 if ((TRUE == pHddCtx->cfg_ini->fEnableTDLSBufferSta)
9235 || pHddCtx->cfg_ini->fTDLSUapsdMask )
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05309236 {
Gopichand Nakkala574f6d12013-06-27 19:38:43 +05309237 int ac;
9238 uint8 ucAc[4] = { WLANTL_AC_VO,
9239 WLANTL_AC_VI,
9240 WLANTL_AC_BK,
9241 WLANTL_AC_BE };
9242 uint8 tlTid[4] = { 7, 5, 2, 3 } ;
9243 for(ac=0; ac < 4; ac++)
9244 {
9245 status = WLANTL_EnableUAPSDForAC( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
9246 pTdlsPeer->staId, ucAc[ac],
9247 tlTid[ac], tlTid[ac], 0, 0,
9248 WLANTL_BI_DIR );
9249 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05309250 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07009251 }
9252
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009253 }
9254 break;
9255 case NL80211_TDLS_DISABLE_LINK:
Lee Hoonkic1262f22013-01-24 21:59:00 -08009256 {
Sunil Dutt41de4e22013-11-14 18:09:02 +05309257 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
9258
9259 if ( NULL == pTdlsPeer ) {
9260 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
9261 " (oper %d) not exsting. ignored",
9262 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
9263 return -EINVAL;
9264 }
9265
9266 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9267 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
9268 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
9269 "NL80211_TDLS_DISABLE_LINK");
9270
Hoonki Lee5305c3a2013-04-29 23:28:59 -07009271 if(TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
Lee Hoonkic1262f22013-01-24 21:59:00 -08009272 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009273 long status;
9274
9275 INIT_COMPLETION(pAdapter->tdls_del_station_comp);
9276
Lee Hoonkic1262f22013-01-24 21:59:00 -08009277 sme_DeleteTdlsPeerSta( WLAN_HDD_GET_HAL_CTX(pAdapter),
9278 pAdapter->sessionId, peer );
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009279
9280 status = wait_for_completion_interruptible_timeout(&pAdapter->tdls_del_station_comp,
9281 msecs_to_jiffies(WAIT_TIME_TDLS_DEL_STA));
9282 if (status <= 0)
9283 {
Hoonki Lee5305c3a2013-04-29 23:28:59 -07009284 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer, eTDLS_LINK_IDLE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009285 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9286 "%s: Del station failed status %ld",
9287 __func__, status);
9288 return -EPERM;
9289 }
Hoonki Lee5305c3a2013-04-29 23:28:59 -07009290 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer, eTDLS_LINK_IDLE);
Lee Hoonkic1262f22013-01-24 21:59:00 -08009291 }
9292 else
9293 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07009294 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9295 "%s: TDLS Peer Station doesn't exist.", __func__);
Lee Hoonkic1262f22013-01-24 21:59:00 -08009296 }
Lee Hoonkic1262f22013-01-24 21:59:00 -08009297 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07009298 break;
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009299 case NL80211_TDLS_TEARDOWN:
Sunil Dutt41de4e22013-11-14 18:09:02 +05309300 {
9301 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9302 " %s : NL80211_TDLS_TEARDOWN for " MAC_ADDRESS_STR,
9303 __func__, MAC_ADDR_ARRAY(peer));
9304
9305 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
9306 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
9307
9308 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9309 " %s TDLS External control and Implicit Trigger not enabled ",
9310 __func__);
9311 return -ENOTSUPP;
9312 }
9313
Sunil Dutt41de4e22013-11-14 18:09:02 +05309314
9315 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
9316
9317 if ( NULL == pTdlsPeer ) {
9318 hddLog(VOS_TRACE_LEVEL_INFO, "%s: " MAC_ADDRESS_STR
9319 " peer not exsting",
9320 __func__, MAC_ADDR_ARRAY(peer));
Naresh Jayaram937abdf2013-11-26 19:50:25 +05309321 return -EINVAL;
Sunil Dutt41de4e22013-11-14 18:09:02 +05309322 }
9323 else {
9324 wlan_hdd_tdls_indicate_teardown(pAdapter, pTdlsPeer,
9325 eSIR_MAC_TDLS_TEARDOWN_UNSPEC_REASON);
9326 }
Naresh Jayaram937abdf2013-11-26 19:50:25 +05309327
9328 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, FALSE) )
9329 return -EINVAL;
Sunil Dutt41de4e22013-11-14 18:09:02 +05309330 break;
9331 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009332 case NL80211_TDLS_SETUP:
Sunil Dutt41de4e22013-11-14 18:09:02 +05309333 {
Naresh Jayaramdb4514b2013-11-25 18:08:10 +05309334 hddTdlsPeer_t *pTdlsPeer;
Sunil Dutt41de4e22013-11-14 18:09:02 +05309335 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9336 " %s : NL80211_TDLS_SETUP for " MAC_ADDRESS_STR,
9337 __func__, MAC_ADDR_ARRAY(peer));
9338
9339 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
9340 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
9341
9342 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9343 " %s TDLS External control and Implicit Trigger not enabled ",
9344 __func__);
9345 return -ENOTSUPP;
9346 }
9347
Naresh Jayaramdb4514b2013-11-25 18:08:10 +05309348 /* To cater the requirement of establishing the TDLS link
9349 * irrespective of the data traffic , get an entry of TDLS peer.
9350 */
9351 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, peer);
9352 if (pTdlsPeer == NULL) {
9353 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9354 "%s: peer " MAC_ADDRESS_STR " not existing",
9355 __func__, MAC_ADDR_ARRAY(peer));
9356 return -EINVAL;
9357 }
Naresh Jayaram937abdf2013-11-26 19:50:25 +05309358
9359 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, TRUE) ) {
9360
9361 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9362 " %s TDLS Add Force Peer Failed",
9363 __func__);
9364 return -EINVAL;
9365 }
Naresh Jayaramdb4514b2013-11-25 18:08:10 +05309366 break;
Sunil Dutt41de4e22013-11-14 18:09:02 +05309367 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009368 case NL80211_TDLS_DISCOVERY_REQ:
9369 /* We don't support in-driver setup/teardown/discovery */
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309370 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
9371 "%s: We don't support in-driver setup/teardown/discovery "
9372 ,__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009373 return -ENOTSUPP;
9374 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309375 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9376 "%s: unsupported event",__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009377 return -ENOTSUPP;
9378 }
9379 return 0;
9380}
Chilam NG571c65a2013-01-19 12:27:36 +05309381
9382int wlan_hdd_cfg80211_send_tdls_discover_req(struct wiphy *wiphy,
9383 struct net_device *dev, u8 *peer)
9384{
Arif Hussaina7c8e412013-11-20 11:06:42 -08009385 hddLog(VOS_TRACE_LEVEL_INFO,
9386 "tdls send discover req: "MAC_ADDRESS_STR,
9387 MAC_ADDR_ARRAY(peer));
Chilam NG571c65a2013-01-19 12:27:36 +05309388
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +05309389#if TDLS_MGMT_VERSION2
9390 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
9391 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
9392#else
Chilam NG571c65a2013-01-19 12:27:36 +05309393 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
9394 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, NULL, 0);
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +05309395#endif
Chilam NG571c65a2013-01-19 12:27:36 +05309396}
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009397#endif
9398
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309399#ifdef WLAN_FEATURE_GTK_OFFLOAD
9400/*
9401 * FUNCTION: wlan_hdd_cfg80211_update_replayCounterCallback
9402 * Callback rountine called upon receiving response for
9403 * get offload info
9404 */
9405void wlan_hdd_cfg80211_update_replayCounterCallback(void *callbackContext,
9406 tpSirGtkOffloadGetInfoRspParams pGtkOffloadGetInfoRsp)
9407{
9408
9409 hdd_adapter_t *pAdapter = (hdd_adapter_t *)callbackContext;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05309410 tANI_U8 tempReplayCounter[8];
9411 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309412
9413 ENTER();
9414
9415 if (NULL == pAdapter)
9416 {
Agarwal Ashish971c2882013-10-30 20:11:12 +05309417 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309418 "%s: HDD adapter is Null", __func__);
9419 return ;
9420 }
9421
9422 if (NULL == pGtkOffloadGetInfoRsp)
9423 {
9424 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9425 "%s: pGtkOffloadGetInfoRsp is Null", __func__);
9426 return ;
9427 }
9428
9429 if (VOS_STATUS_SUCCESS != pGtkOffloadGetInfoRsp->ulStatus)
9430 {
9431 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9432 "%s: wlan Failed to get replay counter value",
9433 __func__);
9434 return ;
9435 }
9436
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05309437 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9438 /* Update replay counter */
9439 pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter =
9440 pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
9441
9442 {
9443 /* changing from little to big endian since supplicant
9444 * works on big endian format
9445 */
9446 int i;
9447 tANI_U8 *p = (tANI_U8 *)&pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
9448
9449 for (i = 0; i < 8; i++)
9450 {
9451 tempReplayCounter[7-i] = (tANI_U8)p[i];
9452 }
9453 }
9454
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309455 /* Update replay counter to NL */
9456 cfg80211_gtk_rekey_notify(pAdapter->dev, pGtkOffloadGetInfoRsp->bssId,
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05309457 tempReplayCounter, GFP_KERNEL);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309458}
9459
9460/*
9461 * FUNCTION: wlan_hdd_cfg80211_set_rekey_data
9462 * This function is used to offload GTK rekeying job to the firmware.
9463 */
9464int wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
9465 struct cfg80211_gtk_rekey_data *data)
9466{
9467 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
9468 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
9469 hdd_station_ctx_t *pHddStaCtx;
9470 tHalHandle hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309471 int result;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05309472 tSirGtkOffloadParams hddGtkOffloadReqParams;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309473 eHalStatus status = eHAL_STATUS_FAILURE;
9474
9475 ENTER();
9476
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309477
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309478 if (NULL == pAdapter)
9479 {
9480 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
9481 "%s: HDD adapter is Null", __func__);
9482 return -ENODEV;
9483 }
9484
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309485 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
9486 TRACE_CODE_HDD_CFG80211_SET_REKEY_DATA,
9487 pAdapter->sessionId, pAdapter->device_mode));
9488
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309489 result = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309490
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309491 if (0 != result)
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309492 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309493 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9494 "%s: HDD context is not valid", __func__);
9495 return result;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309496 }
9497
9498 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9499 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
9500 if (NULL == hHal)
9501 {
9502 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9503 "%s: HAL context is Null!!!", __func__);
9504 return -EAGAIN;
9505 }
9506
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05309507 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_ENABLE;
9508 memcpy(pHddStaCtx->gtkOffloadReqParams.aKCK, data->kck, NL80211_KCK_LEN);
9509 memcpy(pHddStaCtx->gtkOffloadReqParams.aKEK, data->kek, NL80211_KEK_LEN);
9510 memcpy(pHddStaCtx->gtkOffloadReqParams.bssId, &pHddStaCtx->conn_info.bssId,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309511 WNI_CFG_BSSID_LEN);
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05309512 {
9513 /* changing from big to little endian since driver
9514 * works on little endian format
9515 */
9516 tANI_U8 *p =
9517 (tANI_U8 *)&pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter;
9518 int i;
9519
9520 for (i = 0; i < 8; i++)
9521 {
9522 p[7-i] = data->replay_ctr[i];
9523 }
9524 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309525
9526 if (TRUE == pHddCtx->hdd_wlan_suspended)
9527 {
9528 /* if wlan is suspended, enable GTK offload directly from here */
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05309529 memcpy(&hddGtkOffloadReqParams, &pHddStaCtx->gtkOffloadReqParams,
9530 sizeof (tSirGtkOffloadParams));
9531 status = sme_SetGTKOffload(hHal, &hddGtkOffloadReqParams,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309532 pAdapter->sessionId);
9533
9534 if (eHAL_STATUS_SUCCESS != status)
9535 {
9536 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9537 "%s: sme_SetGTKOffload failed, returned %d",
9538 __func__, status);
9539 return status;
9540 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309541 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9542 "%s: sme_SetGTKOffload successfull", __func__);
9543 }
9544 else
9545 {
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309546 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9547 "%s: wlan not suspended GTKOffload request is stored",
9548 __func__);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309549 }
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05309550
9551 return eHAL_STATUS_SUCCESS;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309552}
9553#endif /*WLAN_FEATURE_GTK_OFFLOAD*/
9554
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05309555/*
9556 * FUNCTION: wlan_hdd_cfg80211_set_mac_acl
9557 * This function is used to set access control policy
9558 */
9559static int wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy,
9560 struct net_device *dev, const struct cfg80211_acl_data *params)
9561{
9562 int i;
9563 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
9564 hdd_hostapd_state_t *pHostapdState;
9565 tsap_Config_t *pConfig;
9566 v_CONTEXT_t pVosContext = NULL;
9567 hdd_context_t *pHddCtx;
9568 int status;
9569
9570 ENTER();
9571
9572 if (NULL == pAdapter)
9573 {
9574 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
9575 "%s: HDD adapter is Null", __func__);
9576 return -ENODEV;
9577 }
9578
9579 if (NULL == params)
9580 {
9581 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
9582 "%s: params is Null", __func__);
9583 return -EINVAL;
9584 }
9585
9586 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9587 status = wlan_hdd_validate_context(pHddCtx);
9588
9589 if (0 != status)
9590 {
9591 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9592 "%s: HDD context is not valid", __func__);
9593 return status;
9594 }
9595
9596 pVosContext = pHddCtx->pvosContext;
9597 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
9598
9599 if (NULL == pHostapdState)
9600 {
9601 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
9602 "%s: pHostapdState is Null", __func__);
9603 return -EINVAL;
9604 }
9605
9606 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"acl policy: = %d"
9607 "no acl entries = %d", params->acl_policy, params->n_acl_entries);
9608
9609 if (WLAN_HDD_SOFTAP == pAdapter->device_mode)
9610 {
9611 pConfig = &pAdapter->sessionCtx.ap.sapConfig;
9612
9613 /* default value */
9614 pConfig->num_accept_mac = 0;
9615 pConfig->num_deny_mac = 0;
9616
9617 /**
9618 * access control policy
9619 * @NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED: Deny stations which are
9620 * listed in hostapd.deny file.
9621 * @NL80211_ACL_POLICY_DENY_UNLESS_LISTED: Allow stations which are
9622 * listed in hostapd.accept file.
9623 */
9624 if (NL80211_ACL_POLICY_DENY_UNLESS_LISTED == params->acl_policy)
9625 {
9626 pConfig->SapMacaddr_acl = eSAP_DENY_UNLESS_ACCEPTED;
9627 }
9628 else if (NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED == params->acl_policy)
9629 {
9630 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
9631 }
9632 else
9633 {
9634 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9635 "%s:Acl Policy : %d is not supported",
9636 __func__, params->acl_policy);
9637 return -ENOTSUPP;
9638 }
9639
9640 if (eSAP_DENY_UNLESS_ACCEPTED == pConfig->SapMacaddr_acl)
9641 {
9642 pConfig->num_accept_mac = params->n_acl_entries;
9643 for (i = 0; i < params->n_acl_entries; i++)
9644 {
9645 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9646 "** Add ACL MAC entry %i in WhiletList :"
9647 MAC_ADDRESS_STR, i,
9648 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
9649
9650 vos_mem_copy(&pConfig->accept_mac[i], params->mac_addrs[i].addr,
9651 sizeof(qcmacaddr));
9652 }
9653 }
9654 else if (eSAP_ACCEPT_UNLESS_DENIED == pConfig->SapMacaddr_acl)
9655 {
9656 pConfig->num_deny_mac = params->n_acl_entries;
9657 for (i = 0; i < params->n_acl_entries; i++)
9658 {
9659 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9660 "** Add ACL MAC entry %i in BlackList :"
9661 MAC_ADDRESS_STR, i,
9662 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
9663
9664 vos_mem_copy(&pConfig->deny_mac[i], params->mac_addrs[i].addr,
9665 sizeof(qcmacaddr));
9666 }
9667 }
9668
9669 if (VOS_STATUS_SUCCESS != WLANSAP_SetMacACL(pVosContext, pConfig))
9670 {
9671 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9672 "%s: SAP Set Mac Acl fail", __func__);
9673 return -EINVAL;
9674 }
9675 }
9676 else
9677 {
9678 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309679 "%s: Invalid device_mode = %s (%d)",
9680 __func__, hdd_device_modetoString(pAdapter->device_mode),
9681 pAdapter->device_mode);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05309682 return -EINVAL;
9683 }
9684
9685 return 0;
9686}
9687
Leo Chang9056f462013-08-01 19:21:11 -07009688#ifdef WLAN_NL80211_TESTMODE
9689#ifdef FEATURE_WLAN_LPHB
Leo Changd9df8aa2013-09-26 13:32:26 -07009690void wlan_hdd_cfg80211_lphb_ind_handler
Leo Chang9056f462013-08-01 19:21:11 -07009691(
9692 void *pAdapter,
9693 void *indCont
9694)
9695{
Leo Changd9df8aa2013-09-26 13:32:26 -07009696 tSirLPHBInd *lphbInd;
9697 struct sk_buff *skb;
c_hpothu73f35e62014-04-18 13:40:08 +05309698 hdd_context_t *pHddCtxt;
Leo Chang9056f462013-08-01 19:21:11 -07009699
9700 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -07009701 "LPHB indication arrived");
Leo Chang9056f462013-08-01 19:21:11 -07009702
c_hpothu73f35e62014-04-18 13:40:08 +05309703 if (pAdapter == NULL)
9704 {
9705 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9706 "%s: pAdapter is NULL\n",__func__);
9707 return;
9708 }
9709
Leo Chang9056f462013-08-01 19:21:11 -07009710 if (NULL == indCont)
9711 {
9712 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -07009713 "LPHB IND, invalid argument");
Leo Chang9056f462013-08-01 19:21:11 -07009714 return;
9715 }
9716
c_hpothu73f35e62014-04-18 13:40:08 +05309717 pHddCtxt = (hdd_context_t *)pAdapter;
Leo Changd9df8aa2013-09-26 13:32:26 -07009718 lphbInd = (tSirLPHBInd *)indCont;
Leo Chang9056f462013-08-01 19:21:11 -07009719 skb = cfg80211_testmode_alloc_event_skb(
c_hpothu73f35e62014-04-18 13:40:08 +05309720 pHddCtxt->wiphy,
Leo Changd9df8aa2013-09-26 13:32:26 -07009721 sizeof(tSirLPHBInd),
Leo Chang9056f462013-08-01 19:21:11 -07009722 GFP_ATOMIC);
9723 if (!skb)
9724 {
9725 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9726 "LPHB timeout, NL buffer alloc fail");
9727 return;
9728 }
9729
Leo Changac3ba772013-10-07 09:47:04 -07009730 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_CMD, WLAN_HDD_TM_CMD_WLAN_HB))
Leo Changd9df8aa2013-09-26 13:32:26 -07009731 {
9732 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9733 "WLAN_HDD_TM_ATTR_CMD put fail");
9734 goto nla_put_failure;
9735 }
Leo Changac3ba772013-10-07 09:47:04 -07009736 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_TYPE, lphbInd->protocolType))
Leo Changd9df8aa2013-09-26 13:32:26 -07009737 {
9738 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9739 "WLAN_HDD_TM_ATTR_TYPE put fail");
9740 goto nla_put_failure;
9741 }
Leo Changac3ba772013-10-07 09:47:04 -07009742 if(nla_put(skb, WLAN_HDD_TM_ATTR_DATA,
Leo Changd9df8aa2013-09-26 13:32:26 -07009743 sizeof(tSirLPHBInd), lphbInd))
9744 {
9745 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9746 "WLAN_HDD_TM_ATTR_DATA put fail");
9747 goto nla_put_failure;
9748 }
Leo Chang9056f462013-08-01 19:21:11 -07009749 cfg80211_testmode_event(skb, GFP_ATOMIC);
9750 return;
9751
9752nla_put_failure:
9753 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9754 "NLA Put fail");
9755 kfree_skb(skb);
9756
9757 return;
9758}
9759#endif /* FEATURE_WLAN_LPHB */
9760
9761static int wlan_hdd_cfg80211_testmode(struct wiphy *wiphy, void *data, int len)
9762{
9763 struct nlattr *tb[WLAN_HDD_TM_ATTR_MAX + 1];
9764 int err = 0;
9765#ifdef FEATURE_WLAN_LPHB
9766 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Leo Changd9df8aa2013-09-26 13:32:26 -07009767 eHalStatus smeStatus;
Leo Chang9056f462013-08-01 19:21:11 -07009768#endif /* FEATURE_WLAN_LPHB */
9769
9770 err = nla_parse(tb, WLAN_HDD_TM_ATTR_MAX, data, len, wlan_hdd_tm_policy);
9771 if (err)
9772 {
9773 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9774 "%s Testmode INV ATTR", __func__);
9775 return err;
9776 }
9777
9778 if (!tb[WLAN_HDD_TM_ATTR_CMD])
9779 {
9780 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9781 "%s Testmode INV CMD", __func__);
9782 return -EINVAL;
9783 }
9784
9785 switch (nla_get_u32(tb[WLAN_HDD_TM_ATTR_CMD]))
9786 {
9787#ifdef FEATURE_WLAN_LPHB
9788 /* Low Power Heartbeat configuration request */
9789 case WLAN_HDD_TM_CMD_WLAN_HB:
9790 {
9791 int buf_len;
9792 void *buf;
9793 tSirLPHBReq *hb_params = NULL;
Amar Singhal05852702014-02-04 14:40:00 -08009794 tSirLPHBReq *hb_params_temp = NULL;
Leo Chang9056f462013-08-01 19:21:11 -07009795
9796 if (!tb[WLAN_HDD_TM_ATTR_DATA])
9797 {
9798 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9799 "%s Testmode INV DATA", __func__);
9800 return -EINVAL;
9801 }
9802
9803 buf = nla_data(tb[WLAN_HDD_TM_ATTR_DATA]);
9804 buf_len = nla_len(tb[WLAN_HDD_TM_ATTR_DATA]);
Amar Singhal05852702014-02-04 14:40:00 -08009805
9806 hb_params_temp =(tSirLPHBReq *)buf;
9807 if ((hb_params_temp->cmd == LPHB_SET_TCP_PARAMS_INDID) &&
9808 (hb_params_temp->params.lphbTcpParamReq.timePeriodSec == 0))
9809 return -EINVAL;
9810
Leo Chang9056f462013-08-01 19:21:11 -07009811 hb_params = (tSirLPHBReq *)vos_mem_malloc(sizeof(tSirLPHBReq));
9812 if (NULL == hb_params)
9813 {
9814 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9815 "%s Request Buffer Alloc Fail", __func__);
9816 return -EINVAL;
9817 }
9818
9819 vos_mem_copy(hb_params, buf, buf_len);
Leo Changd9df8aa2013-09-26 13:32:26 -07009820 smeStatus = sme_LPHBConfigReq((tHalHandle)(pHddCtx->hHal),
9821 hb_params,
9822 wlan_hdd_cfg80211_lphb_ind_handler);
9823 if (eHAL_STATUS_SUCCESS != smeStatus)
Leo Chang9056f462013-08-01 19:21:11 -07009824 {
Leo Changd9df8aa2013-09-26 13:32:26 -07009825 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9826 "LPHB Config Fail, disable");
Leo Chang9056f462013-08-01 19:21:11 -07009827 vos_mem_free(hb_params);
9828 }
Leo Chang9056f462013-08-01 19:21:11 -07009829 return 0;
9830 }
9831#endif /* FEATURE_WLAN_LPHB */
9832 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309833 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9834 "%s: unsupported event",__func__);
Leo Chang9056f462013-08-01 19:21:11 -07009835 return -EOPNOTSUPP;
9836 }
9837
9838 return err;
9839}
9840#endif /* CONFIG_NL80211_TESTMODE */
9841
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +05309842static int wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
9843 struct net_device *dev,
9844 int idx, struct survey_info *survey)
9845{
9846 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
9847 hdd_context_t *pHddCtx;
Mihir Sheted9072e02013-08-21 17:02:29 +05309848 hdd_station_ctx_t *pHddStaCtx;
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +05309849 tHalHandle halHandle;
Mihir Sheted9072e02013-08-21 17:02:29 +05309850 v_U32_t channel = 0, freq = 0; /* Initialization Required */
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +05309851 v_S7_t snr,rssi;
9852 int status, i, j, filled = 0;
9853
9854 ENTER();
9855
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +05309856 if (NULL == pAdapter)
9857 {
9858 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
9859 "%s: HDD adapter is Null", __func__);
9860 return -ENODEV;
9861 }
9862
9863 if (NULL == wiphy)
9864 {
9865 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
9866 "%s: wiphy is Null", __func__);
9867 return -ENODEV;
9868 }
9869
9870 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9871 status = wlan_hdd_validate_context(pHddCtx);
9872
9873 if (0 != status)
9874 {
9875 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9876 "%s: HDD context is not valid", __func__);
9877 return status;
9878 }
9879
Mihir Sheted9072e02013-08-21 17:02:29 +05309880 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9881
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +05309882 if (0 == pHddCtx->cfg_ini->fEnableSNRMonitoring ||
Mihir Sheted9072e02013-08-21 17:02:29 +05309883 0 != pAdapter->survey_idx ||
9884 eConnectionState_Associated != pHddStaCtx->conn_info.connState)
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +05309885 {
9886 /* The survey dump ops when implemented completely is expected to
9887 * return a survey of all channels and the ops is called by the
9888 * kernel with incremental values of the argument 'idx' till it
9889 * returns -ENONET. But we can only support the survey for the
9890 * operating channel for now. survey_idx is used to track
9891 * that the ops is called only once and then return -ENONET for
9892 * the next iteration
9893 */
9894 pAdapter->survey_idx = 0;
9895 return -ENONET;
9896 }
9897
9898 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
9899
9900 wlan_hdd_get_snr(pAdapter, &snr);
9901 wlan_hdd_get_rssi(pAdapter, &rssi);
9902
9903 sme_GetOperationChannel(halHandle, &channel, pAdapter->sessionId);
9904 hdd_wlan_get_freq(channel, &freq);
9905
9906
9907 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
9908 {
9909 if (NULL == wiphy->bands[i])
9910 {
9911 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
9912 "%s: wiphy->bands[i] is NULL, i = %d", __func__, i);
9913 continue;
9914 }
9915
9916 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
9917 {
9918 struct ieee80211_supported_band *band = wiphy->bands[i];
9919
9920 if (band->channels[j].center_freq == (v_U16_t)freq)
9921 {
9922 survey->channel = &band->channels[j];
9923 /* The Rx BDs contain SNR values in dB for the received frames
9924 * while the supplicant expects noise. So we calculate and
9925 * return the value of noise (dBm)
9926 * SNR (dB) = RSSI (dBm) - NOISE (dBm)
9927 */
9928 survey->noise = rssi - snr;
9929 survey->filled = SURVEY_INFO_NOISE_DBM;
9930 filled = 1;
9931 }
9932 }
9933 }
9934
9935 if (filled)
9936 pAdapter->survey_idx = 1;
9937 else
9938 {
9939 pAdapter->survey_idx = 0;
9940 return -ENONET;
9941 }
9942
9943 return 0;
9944}
9945
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05309946/*
9947 * FUNCTION: wlan_hdd_cfg80211_resume_wlan
9948 * this is called when cfg80211 driver resume
9949 * driver updates latest sched_scan scan result(if any) to cfg80211 database
9950 */
9951int wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
9952{
9953 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
9954 hdd_adapter_t *pAdapter;
9955 hdd_adapter_list_node_t *pAdapterNode, *pNext;
9956 VOS_STATUS status = VOS_STATUS_SUCCESS;
9957
9958 ENTER();
9959
9960 if ( NULL == pHddCtx )
9961 {
9962 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
9963 "%s: HddCtx validation failed", __func__);
9964 return 0;
9965 }
9966
9967 if (pHddCtx->isLogpInProgress)
9968 {
9969 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9970 "%s: LOGP in Progress. Ignore!!!", __func__);
9971 return 0;
9972 }
9973
Mihir Shete18156292014-03-11 15:38:30 +05309974 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05309975 {
9976 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9977 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
9978 return 0;
9979 }
9980
9981 spin_lock(&pHddCtx->schedScan_lock);
9982 pHddCtx->isWiphySuspended = FALSE;
9983 if (TRUE != pHddCtx->isSchedScanUpdatePending)
9984 {
9985 spin_unlock(&pHddCtx->schedScan_lock);
9986 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9987 "%s: Return resume is not due to PNO indication", __func__);
9988 return 0;
9989 }
9990 // Reset flag to avoid updatating cfg80211 data old results again
9991 pHddCtx->isSchedScanUpdatePending = FALSE;
9992 spin_unlock(&pHddCtx->schedScan_lock);
9993
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +05309994
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05309995 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
9996
9997 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
9998 {
9999 pAdapter = pAdapterNode->pAdapter;
10000 if ( (NULL != pAdapter) &&
10001 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) )
10002 {
10003 if (0 != wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter))
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053010004 {
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053010005 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
10006 "%s: NO SCAN result", __func__);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053010007 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053010008 else
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053010009 {
10010 /* Acquire wakelock to handle the case where APP's tries to
10011 * suspend immediately after updating the scan results. Whis
10012 * results in app's is in suspended state and not able to
10013 * process the connect request to AP
10014 */
10015 hdd_prevent_suspend_timeout(2000);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053010016 cfg80211_sched_scan_results(pHddCtx->wiphy);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053010017 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053010018
10019 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
10020 "%s : cfg80211 scan result database updated", __func__);
10021
10022 return 0;
10023
10024 }
10025 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
10026 pAdapterNode = pNext;
10027 }
10028
10029 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
10030 "%s: Failed to find Adapter", __func__);
10031 return 0;
10032}
10033
10034/*
10035 * FUNCTION: wlan_hdd_cfg80211_suspend_wlan
10036 * this is called when cfg80211 driver suspends
10037 */
10038int wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
10039 struct cfg80211_wowlan *wow)
10040{
10041 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
10042
10043 ENTER();
10044 if (NULL == pHddCtx)
10045 {
10046 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
10047 "%s: HddCtx validation failed", __func__);
10048 return 0;
10049 }
10050
10051 pHddCtx->isWiphySuspended = TRUE;
10052
10053 EXIT();
10054
10055 return 0;
10056}
10057
Jeff Johnson295189b2012-06-20 16:38:30 -070010058/* cfg80211_ops */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010059static struct cfg80211_ops wlan_hdd_cfg80211_ops =
Jeff Johnson295189b2012-06-20 16:38:30 -070010060{
10061 .add_virtual_intf = wlan_hdd_add_virtual_intf,
10062 .del_virtual_intf = wlan_hdd_del_virtual_intf,
10063 .change_virtual_intf = wlan_hdd_cfg80211_change_iface,
10064 .change_station = wlan_hdd_change_station,
10065#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
10066 .add_beacon = wlan_hdd_cfg80211_add_beacon,
10067 .del_beacon = wlan_hdd_cfg80211_del_beacon,
10068 .set_beacon = wlan_hdd_cfg80211_set_beacon,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010069#else
10070 .start_ap = wlan_hdd_cfg80211_start_ap,
10071 .change_beacon = wlan_hdd_cfg80211_change_beacon,
10072 .stop_ap = wlan_hdd_cfg80211_stop_ap,
Jeff Johnson295189b2012-06-20 16:38:30 -070010073#endif
10074 .change_bss = wlan_hdd_cfg80211_change_bss,
10075 .add_key = wlan_hdd_cfg80211_add_key,
10076 .get_key = wlan_hdd_cfg80211_get_key,
10077 .del_key = wlan_hdd_cfg80211_del_key,
10078 .set_default_key = wlan_hdd_cfg80211_set_default_key,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080010079#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
Jeff Johnson295189b2012-06-20 16:38:30 -070010080 .set_channel = wlan_hdd_cfg80211_set_channel,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080010081#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010082 .scan = wlan_hdd_cfg80211_scan,
10083 .connect = wlan_hdd_cfg80211_connect,
10084 .disconnect = wlan_hdd_cfg80211_disconnect,
10085 .join_ibss = wlan_hdd_cfg80211_join_ibss,
10086 .leave_ibss = wlan_hdd_cfg80211_leave_ibss,
10087 .set_wiphy_params = wlan_hdd_cfg80211_set_wiphy_params,
10088 .set_tx_power = wlan_hdd_cfg80211_set_txpower,
10089 .get_tx_power = wlan_hdd_cfg80211_get_txpower,
Jeff Johnson295189b2012-06-20 16:38:30 -070010090 .remain_on_channel = wlan_hdd_cfg80211_remain_on_channel,
10091 .cancel_remain_on_channel = wlan_hdd_cfg80211_cancel_remain_on_channel,
DARAM SUDHA39eede62014-02-12 11:16:40 +053010092 .mgmt_tx = wlan_hdd_mgmt_tx,
Jeff Johnson295189b2012-06-20 16:38:30 -070010093#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
10094 .mgmt_tx_cancel_wait = wlan_hdd_cfg80211_mgmt_tx_cancel_wait,
10095 .set_default_mgmt_key = wlan_hdd_set_default_mgmt_key,
10096 .set_txq_params = wlan_hdd_set_txq_params,
10097#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010098 .get_station = wlan_hdd_cfg80211_get_station,
10099 .set_power_mgmt = wlan_hdd_cfg80211_set_power_mgmt,
10100 .del_station = wlan_hdd_cfg80211_del_station,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010101 .add_station = wlan_hdd_cfg80211_add_station,
10102#ifdef FEATURE_WLAN_LFR
10103 .set_pmksa = wlan_hdd_cfg80211_set_pmksa,
10104 .del_pmksa = wlan_hdd_cfg80211_del_pmksa,
10105 .flush_pmksa = wlan_hdd_cfg80211_flush_pmksa,
10106#endif
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070010107#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
10108 .update_ft_ies = wlan_hdd_cfg80211_update_ft_ies,
10109#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080010110#ifdef FEATURE_WLAN_TDLS
10111 .tdls_mgmt = wlan_hdd_cfg80211_tdls_mgmt,
10112 .tdls_oper = wlan_hdd_cfg80211_tdls_oper,
10113#endif
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053010114#ifdef WLAN_FEATURE_GTK_OFFLOAD
10115 .set_rekey_data = wlan_hdd_cfg80211_set_rekey_data,
10116#endif /* WLAN_FEATURE_GTK_OFFLOAD */
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053010117#ifdef FEATURE_WLAN_SCAN_PNO
10118 .sched_scan_start = wlan_hdd_cfg80211_sched_scan_start,
10119 .sched_scan_stop = wlan_hdd_cfg80211_sched_scan_stop,
10120#endif /*FEATURE_WLAN_SCAN_PNO */
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053010121 .resume = wlan_hdd_cfg80211_resume_wlan,
10122 .suspend = wlan_hdd_cfg80211_suspend_wlan,
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053010123 .set_mac_acl = wlan_hdd_cfg80211_set_mac_acl,
Leo Chang9056f462013-08-01 19:21:11 -070010124#ifdef WLAN_NL80211_TESTMODE
10125 .testmode_cmd = wlan_hdd_cfg80211_testmode,
10126#endif
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053010127 .dump_survey = wlan_hdd_cfg80211_dump_survey,
Jeff Johnson295189b2012-06-20 16:38:30 -070010128};
10129