blob: 76a115b2ccfb218e49e3038e6f0c0b2f953fe3ae [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"
Jeff Johnson295189b2012-06-20 16:38:30 -070084#ifdef WLAN_BTAMP_FEATURE
85#include "bap_hdd_misc.h"
86#endif
87#include <qc_sap_ioctl.h>
Mohit Khanna698ba2a2012-12-04 15:08:18 -080088#ifdef FEATURE_WLAN_TDLS
89#include "wlan_hdd_tdls.h"
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053090#include "wlan_hdd_wmm.h"
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053091#include "wlan_qct_wda.h"
Mohit Khanna698ba2a2012-12-04 15:08:18 -080092#endif
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +053093#include "wlan_nv.h"
Leo Chang6fe1f922013-06-07 19:21:24 -070094#include "wlan_hdd_dev_pwr.h"
Jeff Johnson295189b2012-06-20 16:38:30 -070095
96#define g_mode_rates_size (12)
97#define a_mode_rates_size (8)
98#define FREQ_BASE_80211G (2407)
99#define FREQ_BAND_DIFF_80211G (5)
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700100#define MAX_SCAN_SSID 9
Kiet Lamac06e2c2013-10-23 16:25:07 +0530101#define MAX_PENDING_LOG 5
Jeff Johnson295189b2012-06-20 16:38:30 -0700102#define GET_IE_LEN_IN_BSS_DESC(lenInBss) ( lenInBss + sizeof(lenInBss) - \
103 ((int) OFFSET_OF( tSirBssDescription, ieFields)))
104
105#define HDD2GHZCHAN(freq, chan, flag) { \
106 .band = IEEE80211_BAND_2GHZ, \
107 .center_freq = (freq), \
108 .hw_value = (chan),\
109 .flags = (flag), \
110 .max_antenna_gain = 0 ,\
111 .max_power = 30, \
112}
113
114#define HDD5GHZCHAN(freq, chan, flag) { \
115 .band = IEEE80211_BAND_5GHZ, \
116 .center_freq = (freq), \
117 .hw_value = (chan),\
118 .flags = (flag), \
119 .max_antenna_gain = 0 ,\
120 .max_power = 30, \
121}
122
123#define HDD_G_MODE_RATETAB(rate, rate_id, flag)\
124{\
125 .bitrate = rate, \
126 .hw_value = rate_id, \
127 .flags = flag, \
128}
129
Lee Hoonkic1262f22013-01-24 21:59:00 -0800130#ifndef WLAN_FEATURE_TDLS_DEBUG
131#define TDLS_LOG_LEVEL VOS_TRACE_LEVEL_INFO
132#else
133#define TDLS_LOG_LEVEL VOS_TRACE_LEVEL_ERROR
134#endif
135
Gopichand Nakkala356fb102013-03-06 12:34:04 +0530136#ifdef WLAN_FEATURE_VOWIFI_11R
137#define WLAN_AKM_SUITE_FT_8021X 0x000FAC03
138#define WLAN_AKM_SUITE_FT_PSK 0x000FAC04
139#endif
140
Naresh Jayaram3180aa42014-02-12 21:47:26 +0530141#define HDD_CHANNEL_14 14
142
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530143static const u32 hdd_cipher_suites[] =
Jeff Johnson295189b2012-06-20 16:38:30 -0700144{
145 WLAN_CIPHER_SUITE_WEP40,
146 WLAN_CIPHER_SUITE_WEP104,
147 WLAN_CIPHER_SUITE_TKIP,
148#ifdef FEATURE_WLAN_CCX
149#define WLAN_CIPHER_SUITE_KRK 0x004096ff /* use for KRK */
150 WLAN_CIPHER_SUITE_KRK,
151 WLAN_CIPHER_SUITE_CCMP,
152#else
153 WLAN_CIPHER_SUITE_CCMP,
154#endif
155#ifdef FEATURE_WLAN_WAPI
156 WLAN_CIPHER_SUITE_SMS4,
157#endif
Chet Lanctot186b5732013-03-18 10:26:30 -0700158#ifdef WLAN_FEATURE_11W
159 WLAN_CIPHER_SUITE_AES_CMAC,
160#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700161};
162
163static inline int is_broadcast_ether_addr(const u8 *addr)
164{
165 return ((addr[0] == 0xff) && (addr[1] == 0xff) && (addr[2] == 0xff) &&
166 (addr[3] == 0xff) && (addr[4] == 0xff) && (addr[5] == 0xff));
167}
168
169static struct ieee80211_channel hdd_channels_2_4_GHZ[] =
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530170{
Jeff Johnson295189b2012-06-20 16:38:30 -0700171 HDD2GHZCHAN(2412, 1, 0) ,
172 HDD2GHZCHAN(2417, 2, 0) ,
173 HDD2GHZCHAN(2422, 3, 0) ,
174 HDD2GHZCHAN(2427, 4, 0) ,
175 HDD2GHZCHAN(2432, 5, 0) ,
176 HDD2GHZCHAN(2437, 6, 0) ,
177 HDD2GHZCHAN(2442, 7, 0) ,
178 HDD2GHZCHAN(2447, 8, 0) ,
179 HDD2GHZCHAN(2452, 9, 0) ,
180 HDD2GHZCHAN(2457, 10, 0) ,
181 HDD2GHZCHAN(2462, 11, 0) ,
182 HDD2GHZCHAN(2467, 12, 0) ,
183 HDD2GHZCHAN(2472, 13, 0) ,
184 HDD2GHZCHAN(2484, 14, 0) ,
185};
186
Jeff Johnson295189b2012-06-20 16:38:30 -0700187static struct ieee80211_channel hdd_social_channels_2_4_GHZ[] =
188{
189 HDD2GHZCHAN(2412, 1, 0) ,
190 HDD2GHZCHAN(2437, 6, 0) ,
191 HDD2GHZCHAN(2462, 11, 0) ,
192};
Jeff Johnson295189b2012-06-20 16:38:30 -0700193
194static struct ieee80211_channel hdd_channels_5_GHZ[] =
195{
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -0700196 HDD5GHZCHAN(4920, 240, 0) ,
197 HDD5GHZCHAN(4940, 244, 0) ,
198 HDD5GHZCHAN(4960, 248, 0) ,
199 HDD5GHZCHAN(4980, 252, 0) ,
200 HDD5GHZCHAN(5040, 208, 0) ,
201 HDD5GHZCHAN(5060, 212, 0) ,
202 HDD5GHZCHAN(5080, 216, 0) ,
Jeff Johnson295189b2012-06-20 16:38:30 -0700203 HDD5GHZCHAN(5180, 36, 0) ,
204 HDD5GHZCHAN(5200, 40, 0) ,
205 HDD5GHZCHAN(5220, 44, 0) ,
206 HDD5GHZCHAN(5240, 48, 0) ,
207 HDD5GHZCHAN(5260, 52, 0) ,
208 HDD5GHZCHAN(5280, 56, 0) ,
209 HDD5GHZCHAN(5300, 60, 0) ,
210 HDD5GHZCHAN(5320, 64, 0) ,
211 HDD5GHZCHAN(5500,100, 0) ,
212 HDD5GHZCHAN(5520,104, 0) ,
213 HDD5GHZCHAN(5540,108, 0) ,
214 HDD5GHZCHAN(5560,112, 0) ,
215 HDD5GHZCHAN(5580,116, 0) ,
216 HDD5GHZCHAN(5600,120, 0) ,
217 HDD5GHZCHAN(5620,124, 0) ,
218 HDD5GHZCHAN(5640,128, 0) ,
219 HDD5GHZCHAN(5660,132, 0) ,
220 HDD5GHZCHAN(5680,136, 0) ,
221 HDD5GHZCHAN(5700,140, 0) ,
Leo Chang80de3c22013-11-26 10:52:12 -0800222#ifdef FEATURE_WLAN_CH144
223 HDD5GHZCHAN(5720,144, 0) ,
224#endif /* FEATURE_WLAN_CH144 */
Jeff Johnson295189b2012-06-20 16:38:30 -0700225 HDD5GHZCHAN(5745,149, 0) ,
226 HDD5GHZCHAN(5765,153, 0) ,
227 HDD5GHZCHAN(5785,157, 0) ,
228 HDD5GHZCHAN(5805,161, 0) ,
229 HDD5GHZCHAN(5825,165, 0) ,
230};
231
232static struct ieee80211_rate g_mode_rates[] =
233{
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530234 HDD_G_MODE_RATETAB(10, 0x1, 0),
235 HDD_G_MODE_RATETAB(20, 0x2, 0),
236 HDD_G_MODE_RATETAB(55, 0x4, 0),
237 HDD_G_MODE_RATETAB(110, 0x8, 0),
238 HDD_G_MODE_RATETAB(60, 0x10, 0),
239 HDD_G_MODE_RATETAB(90, 0x20, 0),
240 HDD_G_MODE_RATETAB(120, 0x40, 0),
241 HDD_G_MODE_RATETAB(180, 0x80, 0),
242 HDD_G_MODE_RATETAB(240, 0x100, 0),
243 HDD_G_MODE_RATETAB(360, 0x200, 0),
244 HDD_G_MODE_RATETAB(480, 0x400, 0),
Jeff Johnson295189b2012-06-20 16:38:30 -0700245 HDD_G_MODE_RATETAB(540, 0x800, 0),
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530246};
Jeff Johnson295189b2012-06-20 16:38:30 -0700247
248static struct ieee80211_rate a_mode_rates[] =
249{
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530250 HDD_G_MODE_RATETAB(60, 0x10, 0),
251 HDD_G_MODE_RATETAB(90, 0x20, 0),
252 HDD_G_MODE_RATETAB(120, 0x40, 0),
253 HDD_G_MODE_RATETAB(180, 0x80, 0),
254 HDD_G_MODE_RATETAB(240, 0x100, 0),
255 HDD_G_MODE_RATETAB(360, 0x200, 0),
256 HDD_G_MODE_RATETAB(480, 0x400, 0),
Jeff Johnson295189b2012-06-20 16:38:30 -0700257 HDD_G_MODE_RATETAB(540, 0x800, 0),
258};
259
260static struct ieee80211_supported_band wlan_hdd_band_2_4_GHZ =
261{
262 .channels = hdd_channels_2_4_GHZ,
263 .n_channels = ARRAY_SIZE(hdd_channels_2_4_GHZ),
264 .band = IEEE80211_BAND_2GHZ,
265 .bitrates = g_mode_rates,
266 .n_bitrates = g_mode_rates_size,
267 .ht_cap.ht_supported = 1,
268 .ht_cap.cap = IEEE80211_HT_CAP_SGI_20
269 | IEEE80211_HT_CAP_GRN_FLD
270 | IEEE80211_HT_CAP_DSSSCCK40
271 | IEEE80211_HT_CAP_LSIG_TXOP_PROT,
272 .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
273 .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
274 .ht_cap.mcs.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
275 .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ),
276 .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
277};
278
Jeff Johnson295189b2012-06-20 16:38:30 -0700279static struct ieee80211_supported_band wlan_hdd_band_p2p_2_4_GHZ =
280{
281 .channels = hdd_social_channels_2_4_GHZ,
282 .n_channels = ARRAY_SIZE(hdd_social_channels_2_4_GHZ),
283 .band = IEEE80211_BAND_2GHZ,
284 .bitrates = g_mode_rates,
285 .n_bitrates = g_mode_rates_size,
286 .ht_cap.ht_supported = 1,
287 .ht_cap.cap = IEEE80211_HT_CAP_SGI_20
288 | IEEE80211_HT_CAP_GRN_FLD
289 | IEEE80211_HT_CAP_DSSSCCK40
290 | IEEE80211_HT_CAP_LSIG_TXOP_PROT,
291 .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
292 .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
293 .ht_cap.mcs.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
294 .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ),
295 .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
296};
Jeff Johnson295189b2012-06-20 16:38:30 -0700297
298static struct ieee80211_supported_band wlan_hdd_band_5_GHZ =
299{
300 .channels = hdd_channels_5_GHZ,
301 .n_channels = ARRAY_SIZE(hdd_channels_5_GHZ),
302 .band = IEEE80211_BAND_5GHZ,
303 .bitrates = a_mode_rates,
304 .n_bitrates = a_mode_rates_size,
305 .ht_cap.ht_supported = 1,
306 .ht_cap.cap = IEEE80211_HT_CAP_SGI_20
307 | IEEE80211_HT_CAP_GRN_FLD
308 | IEEE80211_HT_CAP_DSSSCCK40
309 | IEEE80211_HT_CAP_LSIG_TXOP_PROT
310 | IEEE80211_HT_CAP_SGI_40
311 | IEEE80211_HT_CAP_SUP_WIDTH_20_40,
312 .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
313 .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
314 .ht_cap.mcs.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
315 .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ),
316 .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
317};
318
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530319/* This structure contain information what kind of frame are expected in
Jeff Johnson295189b2012-06-20 16:38:30 -0700320 TX/RX direction for each kind of interface */
321static const struct ieee80211_txrx_stypes
322wlan_hdd_txrx_stypes[NUM_NL80211_IFTYPES] = {
323 [NL80211_IFTYPE_STATION] = {
324 .tx = 0xffff,
325 .rx = BIT(SIR_MAC_MGMT_ACTION) |
326 BIT(SIR_MAC_MGMT_PROBE_REQ),
327 },
328 [NL80211_IFTYPE_AP] = {
329 .tx = 0xffff,
330 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
331 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
332 BIT(SIR_MAC_MGMT_PROBE_REQ) |
333 BIT(SIR_MAC_MGMT_DISASSOC) |
334 BIT(SIR_MAC_MGMT_AUTH) |
335 BIT(SIR_MAC_MGMT_DEAUTH) |
336 BIT(SIR_MAC_MGMT_ACTION),
337 },
Jeff Johnsonbc006202013-04-29 14:05:30 -0700338 [NL80211_IFTYPE_ADHOC] = {
339 .tx = 0xffff,
340 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
341 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
342 BIT(SIR_MAC_MGMT_PROBE_REQ) |
343 BIT(SIR_MAC_MGMT_DISASSOC) |
344 BIT(SIR_MAC_MGMT_AUTH) |
345 BIT(SIR_MAC_MGMT_DEAUTH) |
346 BIT(SIR_MAC_MGMT_ACTION),
347 },
Jeff Johnson295189b2012-06-20 16:38:30 -0700348 [NL80211_IFTYPE_P2P_CLIENT] = {
349 .tx = 0xffff,
350 .rx = BIT(SIR_MAC_MGMT_ACTION) |
351 BIT(SIR_MAC_MGMT_PROBE_REQ),
352 },
353 [NL80211_IFTYPE_P2P_GO] = {
354 /* This is also same as for SoftAP */
355 .tx = 0xffff,
356 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
357 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
358 BIT(SIR_MAC_MGMT_PROBE_REQ) |
359 BIT(SIR_MAC_MGMT_DISASSOC) |
360 BIT(SIR_MAC_MGMT_AUTH) |
361 BIT(SIR_MAC_MGMT_DEAUTH) |
362 BIT(SIR_MAC_MGMT_ACTION),
363 },
Jeff Johnson295189b2012-06-20 16:38:30 -0700364};
365
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800366#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800367static const struct ieee80211_iface_limit
368wlan_hdd_iface_limit[] = {
369 {
Sunil Ravia72c3992013-01-31 06:12:22 -0800370 /* max = 3 ; Our driver create two interfaces during driver init
371 * wlan0 and p2p0 interfaces. p2p0 is considered as station
372 * interface until a group is formed. In JB architecture, once the
373 * group is formed, interface type of p2p0 is changed to P2P GO or
374 * Client.
375 * When supplicant remove the group, it first issue a set interface
376 * cmd to change the mode back to Station. In JB this works fine as
377 * we advertize two station type interface during driver init.
378 * Some vendors create separate interface for P2P GO/Client,
379 * after group formation(Third one). But while group remove
380 * supplicant first tries to change the mode(3rd interface) to STATION
381 * But as we advertized only two sta type interfaces nl80211 was
382 * returning error for the third one which was leading to failure in
383 * delete interface. Ideally while removing the group, supplicant
384 * should not try to change the 3rd interface mode to Station type.
385 * Till we get a fix in wpa_supplicant, we advertize max STA
386 * interface type to 3
387 */
388 .max = 3,
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800389 .types = BIT(NL80211_IFTYPE_STATION),
390 },
391 {
392 .max = 1,
Jeff Johnsonbc006202013-04-29 14:05:30 -0700393 .types = BIT(NL80211_IFTYPE_ADHOC) | BIT(NL80211_IFTYPE_AP),
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800394 },
395 {
396 .max = 1,
397 .types = BIT(NL80211_IFTYPE_P2P_GO) |
398 BIT(NL80211_IFTYPE_P2P_CLIENT),
399 },
400};
401
402/* By default, only single channel concurrency is allowed */
403static struct ieee80211_iface_combination
404wlan_hdd_iface_combination = {
405 .limits = wlan_hdd_iface_limit,
406 .num_different_channels = 1,
Sunil Ravia72c3992013-01-31 06:12:22 -0800407 /*
408 * max = WLAN_MAX_INTERFACES ; JellyBean architecture creates wlan0
409 * and p2p0 interfaces during driver init
410 * Some vendors create separate interface for P2P operations.
411 * wlan0: STA interface
412 * p2p0: P2P Device interface, action frames goes
413 * through this interface.
414 * p2p-xx: P2P interface, After GO negotiation this interface is
415 * created for p2p operations(GO/CLIENT interface).
416 */
417 .max_interfaces = WLAN_MAX_INTERFACES,
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800418 .n_limits = ARRAY_SIZE(wlan_hdd_iface_limit),
419 .beacon_int_infra_match = false,
420};
421#endif
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800422
Jeff Johnson295189b2012-06-20 16:38:30 -0700423static struct cfg80211_ops wlan_hdd_cfg80211_ops;
424
425/* Data rate 100KBPS based on IE Index */
426struct index_data_rate_type
427{
428 v_U8_t beacon_rate_index;
429 v_U16_t supported_rate[4];
430};
431
432/* 11B, 11G Rate table include Basic rate and Extended rate
433 The IDX field is the rate index
434 The HI field is the rate when RSSI is strong or being ignored
435 (in this case we report actual rate)
436 The MID field is the rate when RSSI is moderate
437 (in this case we cap 11b rates at 5.5 and 11g rates at 24)
438 The LO field is the rate when RSSI is low
439 (in this case we don't report rates, actual current rate used)
440 */
441static const struct
442{
443 v_U8_t beacon_rate_index;
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -0700444 v_U16_t supported_rate[4];
Jeff Johnson295189b2012-06-20 16:38:30 -0700445} supported_data_rate[] =
446{
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -0700447/* IDX HI HM LM LO (RSSI-based index */
448 {2, { 10, 10, 10, 0}},
449 {4, { 20, 20, 10, 0}},
450 {11, { 55, 20, 10, 0}},
451 {12, { 60, 55, 20, 0}},
452 {18, { 90, 55, 20, 0}},
453 {22, {110, 55, 20, 0}},
454 {24, {120, 90, 60, 0}},
455 {36, {180, 120, 60, 0}},
456 {44, {220, 180, 60, 0}},
457 {48, {240, 180, 90, 0}},
458 {66, {330, 180, 90, 0}},
459 {72, {360, 240, 90, 0}},
460 {96, {480, 240, 120, 0}},
461 {108, {540, 240, 120, 0}}
Jeff Johnson295189b2012-06-20 16:38:30 -0700462};
463
464/* MCS Based rate table */
465static struct index_data_rate_type supported_mcs_rate[] =
466{
467/* MCS L20 L40 S20 S40 */
468 {0, {65, 135, 72, 150}},
469 {1, {130, 270, 144, 300}},
470 {2, {195, 405, 217, 450}},
471 {3, {260, 540, 289, 600}},
472 {4, {390, 810, 433, 900}},
473 {5, {520, 1080, 578, 1200}},
474 {6, {585, 1215, 650, 1350}},
475 {7, {650, 1350, 722, 1500}}
476};
477
Leo Chang6f8870f2013-03-26 18:11:36 -0700478#ifdef WLAN_FEATURE_11AC
479
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530480#define DATA_RATE_11AC_MCS_MASK 0x03
Leo Chang6f8870f2013-03-26 18:11:36 -0700481
482struct index_vht_data_rate_type
483{
484 v_U8_t beacon_rate_index;
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530485 v_U16_t supported_VHT80_rate[2];
486 v_U16_t supported_VHT40_rate[2];
487 v_U16_t supported_VHT20_rate[2];
Leo Chang6f8870f2013-03-26 18:11:36 -0700488};
489
490typedef enum
491{
492 DATA_RATE_11AC_MAX_MCS_7,
493 DATA_RATE_11AC_MAX_MCS_8,
494 DATA_RATE_11AC_MAX_MCS_9,
495 DATA_RATE_11AC_MAX_MCS_NA
496} eDataRate11ACMaxMcs;
497
498/* MCS Based VHT rate table */
499static struct index_vht_data_rate_type supported_vht_mcs_rate[] =
500{
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530501/* MCS L80 S80 L40 S40 L20 S40*/
502 {0, {293, 325}, {135, 150}, {65, 72}},
503 {1, {585, 650}, {270, 300}, {130, 144}},
504 {2, {878, 975}, {405, 450}, {195, 217}},
505 {3, {1170, 1300}, {540, 600}, {260, 289}},
506 {4, {1755, 1950}, {810, 900}, {390, 433}},
507 {5, {2340, 2600}, {1080, 1200}, {520, 578}},
508 {6, {2633, 2925}, {1215, 1350}, {585, 650}},
509 {7, {2925, 3250}, {1350, 1500}, {650, 722}},
510 {8, {3510, 3900}, {1620, 1800}, {780, 867}},
511 {9, {3900, 4333}, {1800, 2000}, {780, 867}}
Leo Chang6f8870f2013-03-26 18:11:36 -0700512};
513#endif /* WLAN_FEATURE_11AC */
514
Jeff Johnson295189b2012-06-20 16:38:30 -0700515extern struct net_device_ops net_ops_struct;
516
Leo Chang9056f462013-08-01 19:21:11 -0700517#ifdef WLAN_NL80211_TESTMODE
518enum wlan_hdd_tm_attr
519{
520 WLAN_HDD_TM_ATTR_INVALID = 0,
521 WLAN_HDD_TM_ATTR_CMD = 1,
522 WLAN_HDD_TM_ATTR_DATA = 2,
523 WLAN_HDD_TM_ATTR_TYPE = 3,
524 /* keep last */
525 WLAN_HDD_TM_ATTR_AFTER_LAST,
526 WLAN_HDD_TM_ATTR_MAX = WLAN_HDD_TM_ATTR_AFTER_LAST - 1,
527};
528
529enum wlan_hdd_tm_cmd
530{
531 WLAN_HDD_TM_CMD_WLAN_HB = 1,
532};
533
534#define WLAN_HDD_TM_DATA_MAX_LEN 5000
535
536static const struct nla_policy wlan_hdd_tm_policy[WLAN_HDD_TM_ATTR_MAX + 1] =
537{
538 [WLAN_HDD_TM_ATTR_CMD] = { .type = NLA_U32 },
539 [WLAN_HDD_TM_ATTR_DATA] = { .type = NLA_BINARY,
540 .len = WLAN_HDD_TM_DATA_MAX_LEN },
541};
542#endif /* WLAN_NL80211_TESTMODE */
543
Rajesh Chauhan98a31f82014-01-06 20:15:25 -0800544#ifdef FEATURE_WLAN_CH_AVOID
545/*
546 * FUNCTION: wlan_hdd_send_avoid_freq_event
547 * This is called when wlan driver needs to send vendor specific
548 * avoid frequency range event to userspace
549 */
550int wlan_hdd_send_avoid_freq_event(hdd_context_t *pHddCtx,
551 tHddAvoidFreqList *pAvoidFreqList)
552{
553 struct sk_buff *vendor_event;
554
555 ENTER();
556
557 if (!pHddCtx)
558 {
559 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
560 "%s: HDD context is null", __func__);
561 return -1;
562 }
563
564 if (!pAvoidFreqList)
565 {
566 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
567 "%s: pAvoidFreqList is null", __func__);
568 return -1;
569 }
570
571 vendor_event = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
572 sizeof(tHddAvoidFreqList),
573 QCOM_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY_INDEX,
574 GFP_KERNEL);
575 if (!vendor_event)
576 {
577 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
578 "%s: cfg80211_vendor_event_alloc failed", __func__);
579 return -1;
580 }
581
582 memcpy(skb_put(vendor_event, sizeof(tHddAvoidFreqList)),
583 (void *)pAvoidFreqList, sizeof(tHddAvoidFreqList));
584
585 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
586
587 EXIT();
588 return 0;
589}
590#endif /* FEATURE_WLAN_CH_AVOID */
591
592/* vendor specific events */
593static const struct nl80211_vendor_cmd_info wlan_hdd_cfg80211_vendor_events[] =
594{
595#ifdef FEATURE_WLAN_CH_AVOID
596 {
597 .vendor_id = QCOM_NL80211_VENDOR_ID,
598 .subcmd = QCOM_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY
599 },
600#endif /* FEATURE_WLAN_CH_AVOID */
601};
602
Jeff Johnson295189b2012-06-20 16:38:30 -0700603/*
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +0530604 * FUNCTION: wlan_hdd_cfg80211_wiphy_alloc
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530605 * This function is called by hdd_wlan_startup()
606 * during initialization.
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +0530607 * This function is used to allocate wiphy structure.
Jeff Johnson295189b2012-06-20 16:38:30 -0700608 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +0530609struct wiphy *wlan_hdd_cfg80211_wiphy_alloc(int priv_size)
Jeff Johnson295189b2012-06-20 16:38:30 -0700610{
611 struct wiphy *wiphy;
612 ENTER();
613
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530614 /*
615 * Create wiphy device
Jeff Johnson295189b2012-06-20 16:38:30 -0700616 */
617 wiphy = wiphy_new(&wlan_hdd_cfg80211_ops, priv_size);
618
619 if (!wiphy)
620 {
621 /* Print error and jump into err label and free the memory */
622 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wiphy init failed", __func__);
623 return NULL;
624 }
625
626 return wiphy;
627}
628
629/*
630 * FUNCTION: wlan_hdd_cfg80211_update_band
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530631 * This function is called from the supplicant through a
Jeff Johnson295189b2012-06-20 16:38:30 -0700632 * private ioctl to change the band value
633 */
634int wlan_hdd_cfg80211_update_band(struct wiphy *wiphy, eCsrBand eBand)
635{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +0530636 int i, j;
637 eNVChannelEnabledType channelEnabledState;
638
Jeff Johnsone7245742012-09-05 17:12:55 -0700639 ENTER();
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +0530640 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
Jeff Johnson295189b2012-06-20 16:38:30 -0700641 {
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +0530642
643 if (NULL == wiphy->bands[i])
644 {
645 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[i] is NULL, i = %d",
646 __func__, i);
647 continue;
648 }
649
650 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
651 {
652 struct ieee80211_supported_band *band = wiphy->bands[i];
653
654 channelEnabledState = vos_nv_getChannelEnabledState(
655 band->channels[j].hw_value);
656
657 if (IEEE80211_BAND_2GHZ == i && eCSR_BAND_5G == eBand) // 5G only
658 {
659 // Enable Social channels for P2P
660 if (WLAN_HDD_IS_SOCIAL_CHANNEL(band->channels[j].center_freq) &&
661 NV_CHANNEL_ENABLE == channelEnabledState)
662 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
663 else
664 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
665 continue;
666 }
667 else if (IEEE80211_BAND_5GHZ == i && eCSR_BAND_24 == eBand) // 2G only
668 {
669 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
670 continue;
671 }
672
673 if (NV_CHANNEL_DISABLE == channelEnabledState ||
674 NV_CHANNEL_INVALID == channelEnabledState)
675 {
676 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
677 }
678 else if (NV_CHANNEL_DFS == channelEnabledState)
679 {
680 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
681 band->channels[j].flags |= IEEE80211_CHAN_RADAR;
682 }
683 else
684 {
685 band->channels[j].flags &= ~(IEEE80211_CHAN_DISABLED
686 |IEEE80211_CHAN_RADAR);
687 }
688 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700689 }
690 return 0;
691}
692/*
693 * FUNCTION: wlan_hdd_cfg80211_init
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530694 * This function is called by hdd_wlan_startup()
695 * during initialization.
Jeff Johnson295189b2012-06-20 16:38:30 -0700696 * This function is used to initialize and register wiphy structure.
697 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +0530698int wlan_hdd_cfg80211_init(struct device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -0700699 struct wiphy *wiphy,
700 hdd_config_t *pCfg
701 )
702{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +0530703 int i, j;
Jeff Johnsone7245742012-09-05 17:12:55 -0700704 ENTER();
705
Jeff Johnson295189b2012-06-20 16:38:30 -0700706 /* Now bind the underlying wlan device with wiphy */
707 set_wiphy_dev(wiphy, dev);
708
709 wiphy->mgmt_stypes = wlan_hdd_txrx_stypes;
Amar Singhalfddc28c2013-09-05 13:03:40 -0700710
Kiet Lam6c583332013-10-14 05:37:09 +0530711#ifndef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -0700712 /* the flag for the other case would be initialzed in
713 vos_init_wiphy_from_nv_bin */
Amar Singhal0a402232013-10-11 20:57:16 -0700714 wiphy->flags |= WIPHY_FLAG_STRICT_REGULATORY;
Kiet Lam6c583332013-10-14 05:37:09 +0530715#endif
Amar Singhala49cbc52013-10-08 18:37:44 -0700716
Amar Singhalfddc28c2013-09-05 13:03:40 -0700717 /* This will disable updating of NL channels from passive to
718 * active if a beacon is received on passive channel. */
719 wiphy->flags |= WIPHY_FLAG_DISABLE_BEACON_HINTS;
Amar Singhalf0073192013-09-20 12:34:56 -0700720
Amar Singhalfddc28c2013-09-05 13:03:40 -0700721
Amar Singhala49cbc52013-10-08 18:37:44 -0700722
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700723#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -0700724 wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME
725 | WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD
726 | WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL
Jeff Johnsone7245742012-09-05 17:12:55 -0700727 | WIPHY_FLAG_OFFCHAN_TX;
Kiet Lam6c583332013-10-14 05:37:09 +0530728 wiphy->country_ie_pref = NL80211_COUNTRY_IE_IGNORE_CORE;
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700729#endif
Amar Singhala49cbc52013-10-08 18:37:44 -0700730
Srinivas Girigowda640728a2013-03-28 12:21:54 -0700731#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_CCX) || defined(FEATURE_WLAN_LFR)
732 if (pCfg->isFastTransitionEnabled
James Zmuda77fb5ae2013-01-29 08:00:17 -0800733#ifdef FEATURE_WLAN_LFR
Srinivas Girigowda640728a2013-03-28 12:21:54 -0700734 || pCfg->isFastRoamIniFeatureEnabled
735#endif
736#ifdef FEATURE_WLAN_CCX
737 || pCfg->isCcxIniFeatureEnabled
738#endif
739 )
740 {
741 wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM;
742 }
James Zmuda77fb5ae2013-01-29 08:00:17 -0800743#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -0800744#ifdef FEATURE_WLAN_TDLS
745 wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS
746 | WIPHY_FLAG_TDLS_EXTERNAL_SETUP;
747#endif
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +0530748#ifdef FEATURE_WLAN_SCAN_PNO
Hardik Kantilal Patel3dfd8792013-11-13 20:34:57 +0530749 if (pCfg->configPNOScanSupport)
750 {
751 wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN;
752 wiphy->max_sched_scan_ssids = SIR_PNO_MAX_SUPP_NETWORKS;
753 wiphy->max_match_sets = SIR_PNO_MAX_SUPP_NETWORKS;
754 wiphy->max_sched_scan_ie_len = SIR_MAC_MAX_IE_LENGTH;
755 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +0530756#endif/*FEATURE_WLAN_SCAN_PNO*/
Mohit Khanna698ba2a2012-12-04 15:08:18 -0800757
Amar Singhalfddc28c2013-09-05 13:03:40 -0700758#ifdef CONFIG_ENABLE_LINUX_REG
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -0700759 /* even with WIPHY_FLAG_CUSTOM_REGULATORY,
760 driver can still register regulatory callback and
Amar Singhalfddc28c2013-09-05 13:03:40 -0700761 it will get regulatory settings in wiphy->band[], but
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -0700762 driver need to determine what to do with both
763 regulatory settings */
Amar Singhalfddc28c2013-09-05 13:03:40 -0700764
765 wiphy->reg_notifier = wlan_hdd_linux_reg_notifier;
Amar Singhala49cbc52013-10-08 18:37:44 -0700766#else
767 wiphy->reg_notifier = wlan_hdd_crda_reg_notifier;
Amar Singhalfddc28c2013-09-05 13:03:40 -0700768#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700769
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530770 wiphy->max_scan_ssids = MAX_SCAN_SSID;
771
Madan Mohan Koyyalamudi6815b162013-07-19 17:17:46 +0530772 wiphy->max_scan_ie_len = SIR_MAC_MAX_IE_LENGTH;
Jeff Johnson295189b2012-06-20 16:38:30 -0700773
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +0530774 wiphy->max_acl_mac_addrs = MAX_ACL_MAC_ADDRESS;
775
Jeff Johnson295189b2012-06-20 16:38:30 -0700776 /* Supports STATION & AD-HOC modes right now */
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530777 wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -0700778 | BIT(NL80211_IFTYPE_ADHOC)
Jeff Johnson295189b2012-06-20 16:38:30 -0700779 | BIT(NL80211_IFTYPE_P2P_CLIENT)
780 | BIT(NL80211_IFTYPE_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -0700781 | BIT(NL80211_IFTYPE_AP);
782
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800783#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800784 if( pCfg->enableMCC )
785 {
786 /* Currently, supports up to two channels */
787 wlan_hdd_iface_combination.num_different_channels = 2;
788
789 if( !pCfg->allowMCCGODiffBI )
790 wlan_hdd_iface_combination.beacon_int_infra_match = true;
791
792 }
793 wiphy->iface_combinations = &wlan_hdd_iface_combination;
794 wiphy->n_iface_combinations = 1;
795#endif
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800796
Jeff Johnson295189b2012-06-20 16:38:30 -0700797 /* Before registering we need to update the ht capabilitied based
798 * on ini values*/
799 if( !pCfg->ShortGI20MhzEnable )
800 {
801 wlan_hdd_band_2_4_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
802 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
803 wlan_hdd_band_p2p_2_4_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
804 }
805
806 if( !pCfg->ShortGI40MhzEnable )
807 {
808 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_40;
809 }
810
811 if( !pCfg->nChannelBondingMode5GHz )
812 {
813 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
814 }
815
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +0530816 wiphy->bands[IEEE80211_BAND_2GHZ] = &wlan_hdd_band_2_4_GHZ;
817 wiphy->bands[IEEE80211_BAND_5GHZ] = &wlan_hdd_band_5_GHZ;
818
819 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
820 {
821
822 if (NULL == wiphy->bands[i])
823 {
824 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[i] is NULL, i = %d",
825 __func__, i);
826 continue;
827 }
828
829 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
830 {
831 struct ieee80211_supported_band *band = wiphy->bands[i];
832
833 if (IEEE80211_BAND_2GHZ == i && eCSR_BAND_5G == pCfg->nBandCapability) // 5G only
834 {
835 // Enable social channels for P2P
836 if (WLAN_HDD_IS_SOCIAL_CHANNEL(band->channels[j].center_freq))
837 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
838 else
839 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
840 continue;
841 }
842 else if (IEEE80211_BAND_5GHZ == i && eCSR_BAND_24 == pCfg->nBandCapability) // 2G only
843 {
844 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
845 continue;
846 }
847 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700848 }
849 /*Initialise the supported cipher suite details*/
850 wiphy->cipher_suites = hdd_cipher_suites;
851 wiphy->n_cipher_suites = ARRAY_SIZE(hdd_cipher_suites);
852
853 /*signal strength in mBm (100*dBm) */
854 wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
855
856#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Jeff Johnson295189b2012-06-20 16:38:30 -0700857 wiphy->max_remain_on_channel_duration = 1000;
858#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700859
Rajesh Chauhan98a31f82014-01-06 20:15:25 -0800860 wiphy->n_vendor_commands = 0;
861 wiphy->vendor_events = wlan_hdd_cfg80211_vendor_events;
862 wiphy->n_vendor_events = ARRAY_SIZE(wlan_hdd_cfg80211_vendor_events);
863
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +0530864 EXIT();
865 return 0;
866}
867
868/* In this function we are registering wiphy. */
869int wlan_hdd_cfg80211_register(struct wiphy *wiphy)
870{
871 ENTER();
872 /* Register our wiphy dev with cfg80211 */
Jeff Johnson295189b2012-06-20 16:38:30 -0700873 if (0 > wiphy_register(wiphy))
874 {
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +0530875 /* print error */
Jeff Johnson295189b2012-06-20 16:38:30 -0700876 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
877 return -EIO;
878 }
879
880 EXIT();
881 return 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530882}
Jeff Johnson295189b2012-06-20 16:38:30 -0700883
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +0530884/* In this function we are updating channel list when,
885 regulatory domain is FCC and country code is US.
886 Here In FCC standard 5GHz UNII-1 Bands are indoor only.
887 As per FCC smart phone is not a indoor device.
888 GO should not opeate on indoor channels */
889void wlan_hdd_cfg80211_update_reg_info(struct wiphy *wiphy)
890{
891 int j;
892 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
893 tANI_U8 defaultCountryCode[3] = SME_INVALID_COUNTRY_CODE;
894 //Default counrtycode from NV at the time of wiphy initialization.
895 if (eHAL_STATUS_SUCCESS != sme_GetDefaultCountryCodeFrmNv(pHddCtx->hHal,
896 &defaultCountryCode[0]))
897 {
Jeff Johnson0299d0a2013-10-30 12:37:43 -0700898 hddLog(LOGE, FL("Failed to get default country code from NV"));
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +0530899 }
900 if ((defaultCountryCode[0]== 'U') && (defaultCountryCode[1]=='S'))
901 {
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +0530902 if (NULL == wiphy->bands[IEEE80211_BAND_5GHZ])
903 {
904 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[IEEE80211_BAND_5GHZ] is NULL",__func__ );
905 return;
906 }
907 for (j = 0; j < wiphy->bands[IEEE80211_BAND_5GHZ]->n_channels; j++)
908 {
909 struct ieee80211_supported_band *band = wiphy->bands[IEEE80211_BAND_5GHZ];
910 // Mark UNII -1 band channel as passive
911 if (WLAN_HDD_CHANNEL_IN_UNII_1_BAND(band->channels[j].center_freq))
912 band->channels[j].flags |= IEEE80211_CHAN_PASSIVE_SCAN;
913 }
914 }
915}
916
Jeff Johnson295189b2012-06-20 16:38:30 -0700917/* In this function we will do all post VOS start initialization.
918 In this function we will register for all frame in which supplicant
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530919 is interested.
Jeff Johnson295189b2012-06-20 16:38:30 -0700920*/
921void wlan_hdd_cfg80211_post_voss_start(hdd_adapter_t* pAdapter)
922{
Jeff Johnson295189b2012-06-20 16:38:30 -0700923 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
924 /* Register for all P2P action, public action etc frames */
925 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
926
Jeff Johnsone7245742012-09-05 17:12:55 -0700927 ENTER();
928
Jeff Johnson295189b2012-06-20 16:38:30 -0700929 /* Right now we are registering these frame when driver is getting
930 initialized. Once we will move to 2.6.37 kernel, in which we have
931 frame register ops, we will move this code as a part of that */
932 /* GAS Initial Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530933 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Jeff Johnson295189b2012-06-20 16:38:30 -0700934 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
935
936 /* GAS Initial Response */
937 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
938 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530939
Jeff Johnson295189b2012-06-20 16:38:30 -0700940 /* GAS Comeback Request */
941 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
942 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
943
944 /* GAS Comeback Response */
945 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
946 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
947
948 /* P2P Public Action */
949 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530950 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -0700951 P2P_PUBLIC_ACTION_FRAME_SIZE );
952
953 /* P2P Action */
954 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
955 (v_U8_t*)P2P_ACTION_FRAME,
956 P2P_ACTION_FRAME_SIZE );
Chet Lanctot186b5732013-03-18 10:26:30 -0700957
Gopichand Nakkalae3d56e72013-04-21 23:33:32 +0530958 /* WNM BSS Transition Request frame */
959 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
960 (v_U8_t*)WNM_BSS_ACTION_FRAME,
961 WNM_BSS_ACTION_FRAME_SIZE );
Jeff Johnson295189b2012-06-20 16:38:30 -0700962}
963
964void wlan_hdd_cfg80211_pre_voss_stop(hdd_adapter_t* pAdapter)
965{
Jeff Johnson295189b2012-06-20 16:38:30 -0700966 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
967 /* Register for all P2P action, public action etc frames */
968 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
969
Jeff Johnsone7245742012-09-05 17:12:55 -0700970 ENTER();
971
Jeff Johnson295189b2012-06-20 16:38:30 -0700972 /* Right now we are registering these frame when driver is getting
973 initialized. Once we will move to 2.6.37 kernel, in which we have
974 frame register ops, we will move this code as a part of that */
975 /* GAS Initial Request */
976
977 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
978 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
979
980 /* GAS Initial Response */
981 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
982 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530983
Jeff Johnson295189b2012-06-20 16:38:30 -0700984 /* GAS Comeback Request */
985 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
986 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
987
988 /* GAS Comeback Response */
989 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
990 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
991
992 /* P2P Public Action */
993 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530994 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -0700995 P2P_PUBLIC_ACTION_FRAME_SIZE );
996
997 /* P2P Action */
998 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
999 (v_U8_t*)P2P_ACTION_FRAME,
1000 P2P_ACTION_FRAME_SIZE );
Chet Lanctot186b5732013-03-18 10:26:30 -07001001
1002#ifdef WLAN_FEATURE_11W
1003 /* SA Query Response Action Frame */
1004 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
1005 (v_U8_t*)SA_QUERY_FRAME_RSP,
1006 SA_QUERY_FRAME_RSP_SIZE );
1007#endif /* WLAN_FEATURE_11W */
Jeff Johnson295189b2012-06-20 16:38:30 -07001008}
1009
1010#ifdef FEATURE_WLAN_WAPI
1011void wlan_hdd_cfg80211_set_key_wapi(hdd_adapter_t* pAdapter, u8 key_index,
1012 const u8 *mac_addr, u8 *key , int key_Len)
1013{
1014 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
1015 tCsrRoamSetKey setKey;
1016 v_BOOL_t isConnected = TRUE;
1017 int status = 0;
1018 v_U32_t roamId= 0xFF;
1019 tANI_U8 *pKeyPtr = NULL;
1020 int n = 0;
1021
Arif Hussain6d2a3322013-11-17 19:50:10 -08001022 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07001023 __func__,pAdapter->device_mode);
1024
Gopichand Nakkalae7480202013-02-11 15:24:22 +05301025 vos_mem_zero(&setKey, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -07001026 setKey.keyId = key_index; // Store Key ID
1027 setKey.encType = eCSR_ENCRYPT_TYPE_WPI; // SET WAPI Encryption
1028 setKey.keyDirection = eSIR_TX_RX; // Key Directionn both TX and RX
1029 setKey.paeRole = 0 ; // the PAE role
1030 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
1031 {
1032 vos_set_macaddr_broadcast( (v_MACADDR_t *)setKey.peerMac );
1033 }
1034 else
1035 {
1036 isConnected = hdd_connIsConnected(pHddStaCtx);
1037 vos_mem_copy(setKey.peerMac,&pHddStaCtx->conn_info.bssId,WNI_CFG_BSSID_LEN);
1038 }
1039 setKey.keyLength = key_Len;
1040 pKeyPtr = setKey.Key;
1041 memcpy( pKeyPtr, key, key_Len);
1042
Arif Hussain6d2a3322013-11-17 19:50:10 -08001043 hddLog(VOS_TRACE_LEVEL_INFO,"%s: WAPI KEY LENGTH:0x%04x",
Jeff Johnson295189b2012-06-20 16:38:30 -07001044 __func__, key_Len);
1045 for (n = 0 ; n < key_Len; n++)
1046 hddLog(VOS_TRACE_LEVEL_INFO, "%s WAPI KEY Data[%d]:%02x ",
1047 __func__,n,setKey.Key[n]);
1048
1049 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
1050 if ( isConnected )
1051 {
1052 status= sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
1053 pAdapter->sessionId, &setKey, &roamId );
1054 }
1055 if ( status != 0 )
1056 {
1057 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1058 "[%4d] sme_RoamSetKey returned ERROR status= %d",
1059 __LINE__, status );
1060 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
1061 }
1062}
1063#endif /* FEATURE_WLAN_WAPI*/
1064
1065#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301066int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07001067 beacon_data_t **ppBeacon,
1068 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001069#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301070int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001071 beacon_data_t **ppBeacon,
1072 struct cfg80211_beacon_data *params,
1073 int dtim_period)
1074#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301075{
Jeff Johnson295189b2012-06-20 16:38:30 -07001076 int size;
1077 beacon_data_t *beacon = NULL;
1078 beacon_data_t *old = NULL;
1079 int head_len,tail_len;
1080
Jeff Johnsone7245742012-09-05 17:12:55 -07001081 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07001082 if (params->head && !params->head_len)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05301083 {
1084 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1085 FL("head_len is NULL"));
Jeff Johnson295189b2012-06-20 16:38:30 -07001086 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05301087 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001088
1089 old = pAdapter->sessionCtx.ap.beacon;
1090
1091 if (!params->head && !old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05301092 {
1093 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1094 FL("session(%d) old and new heads points to NULL"),
1095 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07001096 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05301097 }
1098
1099 if (params->tail && !params->tail_len)
1100 {
1101 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1102 FL("tail_len is zero but tail is not NULL"));
1103 return -EINVAL;
1104 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001105
Jeff Johnson295189b2012-06-20 16:38:30 -07001106#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,38))
1107 /* Kernel 3.0 is not updating dtim_period for set beacon */
1108 if (!params->dtim_period)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05301109 {
1110 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1111 FL("dtim period is 0"));
Jeff Johnson295189b2012-06-20 16:38:30 -07001112 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05301113 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001114#endif
1115
1116 if(params->head)
1117 head_len = params->head_len;
1118 else
1119 head_len = old->head_len;
1120
1121 if(params->tail || !old)
1122 tail_len = params->tail_len;
1123 else
1124 tail_len = old->tail_len;
1125
1126 size = sizeof(beacon_data_t) + head_len + tail_len;
1127
1128 beacon = kzalloc(size, GFP_KERNEL);
1129
1130 if( beacon == NULL )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05301131 {
1132 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1133 FL("Mem allocation for beacon failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -07001134 return -ENOMEM;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05301135 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001136
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001137#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07001138 if(params->dtim_period || !old )
1139 beacon->dtim_period = params->dtim_period;
1140 else
1141 beacon->dtim_period = old->dtim_period;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001142#else
1143 if(dtim_period || !old )
1144 beacon->dtim_period = dtim_period;
1145 else
1146 beacon->dtim_period = old->dtim_period;
1147#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301148
Jeff Johnson295189b2012-06-20 16:38:30 -07001149 beacon->head = ((u8 *) beacon) + sizeof(beacon_data_t);
1150 beacon->tail = beacon->head + head_len;
1151 beacon->head_len = head_len;
1152 beacon->tail_len = tail_len;
1153
1154 if(params->head) {
1155 memcpy (beacon->head,params->head,beacon->head_len);
1156 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301157 else {
Jeff Johnson295189b2012-06-20 16:38:30 -07001158 if(old)
1159 memcpy (beacon->head,old->head,beacon->head_len);
1160 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301161
Jeff Johnson295189b2012-06-20 16:38:30 -07001162 if(params->tail) {
1163 memcpy (beacon->tail,params->tail,beacon->tail_len);
1164 }
1165 else {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301166 if(old)
Jeff Johnson295189b2012-06-20 16:38:30 -07001167 memcpy (beacon->tail,old->tail,beacon->tail_len);
1168 }
1169
1170 *ppBeacon = beacon;
1171
1172 kfree(old);
1173
1174 return 0;
1175
1176}
Jeff Johnson295189b2012-06-20 16:38:30 -07001177
1178v_U8_t* wlan_hdd_cfg80211_get_ie_ptr(v_U8_t *pIes, int length, v_U8_t eid)
1179{
1180 int left = length;
1181 v_U8_t *ptr = pIes;
1182 v_U8_t elem_id,elem_len;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301183
Jeff Johnson295189b2012-06-20 16:38:30 -07001184 while(left >= 2)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301185 {
Jeff Johnson295189b2012-06-20 16:38:30 -07001186 elem_id = ptr[0];
1187 elem_len = ptr[1];
1188 left -= 2;
1189 if(elem_len > left)
1190 {
1191 hddLog(VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07001192 FL("****Invalid IEs eid = %d elem_len=%d left=%d*****"),
Jeff Johnson295189b2012-06-20 16:38:30 -07001193 eid,elem_len,left);
1194 return NULL;
1195 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301196 if (elem_id == eid)
Jeff Johnson295189b2012-06-20 16:38:30 -07001197 {
1198 return ptr;
1199 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301200
Jeff Johnson295189b2012-06-20 16:38:30 -07001201 left -= elem_len;
1202 ptr += (elem_len + 2);
1203 }
1204 return NULL;
1205}
1206
Jeff Johnson295189b2012-06-20 16:38:30 -07001207/* Check if rate is 11g rate or not */
1208static int wlan_hdd_rate_is_11g(u8 rate)
1209{
Sanjay Devnani28322e22013-06-21 16:13:40 -07001210 static const u8 gRateArray[8] = {12, 18, 24, 36, 48, 72, 96, 108}; /* actual rate * 2 */
Jeff Johnson295189b2012-06-20 16:38:30 -07001211 u8 i;
1212 for (i = 0; i < 8; i++)
1213 {
1214 if(rate == gRateArray[i])
1215 return TRUE;
1216 }
1217 return FALSE;
1218}
1219
1220/* Check for 11g rate and set proper 11g only mode */
1221static void wlan_hdd_check_11gmode(u8 *pIe, u8* require_ht,
1222 u8* pCheckRatesfor11g, eSapPhyMode* pSapHw_mode)
1223{
1224 u8 i, num_rates = pIe[0];
1225
1226 pIe += 1;
1227 for ( i = 0; i < num_rates; i++)
1228 {
1229 if( *pCheckRatesfor11g && (TRUE == wlan_hdd_rate_is_11g(pIe[i] & RATE_MASK)))
1230 {
1231 /* If rate set have 11g rate than change the mode to 11G */
1232 *pSapHw_mode = eSAP_DOT11_MODE_11g;
1233 if (pIe[i] & BASIC_RATE_MASK)
1234 {
1235 /* If we have 11g rate as basic rate, it means mode
1236 is 11g only mode.
1237 */
1238 *pSapHw_mode = eSAP_DOT11_MODE_11g_ONLY;
1239 *pCheckRatesfor11g = FALSE;
1240 }
1241 }
1242 else if((BASIC_RATE_MASK | WLAN_BSS_MEMBERSHIP_SELECTOR_HT_PHY) == pIe[i])
1243 {
1244 *require_ht = TRUE;
1245 }
1246 }
1247 return;
1248}
1249
1250static void wlan_hdd_set_sapHwmode(hdd_adapter_t *pHostapdAdapter)
1251{
1252 tsap_Config_t *pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
1253 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
1254 struct ieee80211_mgmt *pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
1255 u8 checkRatesfor11g = TRUE;
1256 u8 require_ht = FALSE;
1257 u8 *pIe=NULL;
1258
1259 pConfig->SapHw_mode= eSAP_DOT11_MODE_11b;
1260
1261 pIe = wlan_hdd_cfg80211_get_ie_ptr(&pMgmt_frame->u.beacon.variable[0],
1262 pBeacon->head_len, WLAN_EID_SUPP_RATES);
1263 if (pIe != NULL)
1264 {
1265 pIe += 1;
1266 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
1267 &pConfig->SapHw_mode);
1268 }
1269
1270 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
1271 WLAN_EID_EXT_SUPP_RATES);
1272 if (pIe != NULL)
1273 {
1274
1275 pIe += 1;
1276 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
1277 &pConfig->SapHw_mode);
1278 }
1279
1280 if( pConfig->channel > 14 )
1281 {
1282 pConfig->SapHw_mode= eSAP_DOT11_MODE_11a;
1283 }
1284
1285 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
1286 WLAN_EID_HT_CAPABILITY);
1287
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301288 if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07001289 {
1290 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n;
1291 if(require_ht)
1292 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n_ONLY;
1293 }
1294}
1295
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05301296static int wlan_hdd_add_ie(hdd_adapter_t* pHostapdAdapter, v_U8_t *genie,
1297 v_U8_t *total_ielen, v_U8_t *oui, v_U8_t oui_size)
1298{
Arif Hussaine7f3ea52013-09-12 21:56:36 -07001299 v_U16_t ielen = 0;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05301300 v_U8_t *pIe = NULL;
1301 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
1302
1303 pIe = wlan_hdd_get_vendor_oui_ie_ptr(oui, oui_size,
1304 pBeacon->tail, pBeacon->tail_len);
1305
1306 if (pIe)
1307 {
1308 ielen = pIe[1] + 2;
1309 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
1310 {
1311 vos_mem_copy(&genie[*total_ielen], pIe, ielen);
1312 }
1313 else
1314 {
1315 hddLog( VOS_TRACE_LEVEL_ERROR, "**Ie Length is too big***");
1316 return -EINVAL;
1317 }
1318 *total_ielen += ielen;
1319 }
1320 return 0;
1321}
1322
Arif Hussaine7f3ea52013-09-12 21:56:36 -07001323static void wlan_hdd_add_hostapd_conf_vsie(hdd_adapter_t* pHostapdAdapter,
1324 v_U8_t *genie, v_U8_t *total_ielen)
1325{
1326 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
1327 int left = pBeacon->tail_len;
1328 v_U8_t *ptr = pBeacon->tail;
1329 v_U8_t elem_id, elem_len;
1330 v_U16_t ielen = 0;
1331
1332 if ( NULL == ptr || 0 == left )
1333 return;
1334
1335 while (left >= 2)
1336 {
1337 elem_id = ptr[0];
1338 elem_len = ptr[1];
1339 left -= 2;
1340 if (elem_len > left)
1341 {
1342 hddLog( VOS_TRACE_LEVEL_ERROR,
1343 "****Invalid IEs eid = %d elem_len=%d left=%d*****",
1344 elem_id, elem_len, left);
1345 return;
1346 }
1347 if (IE_EID_VENDOR == elem_id)
1348 {
1349 /* skipping the VSIE's which we don't want to include or
1350 * it will be included by existing code
1351 */
1352 if ((memcmp( &ptr[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) != 0 ) &&
1353#ifdef WLAN_FEATURE_WFD
1354 (memcmp( &ptr[2], WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE) != 0) &&
1355#endif
1356 (memcmp( &ptr[2], WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
1357 (memcmp( &ptr[2], BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
1358 (memcmp( &ptr[2], "\x00\x50\xf2\x02", WPA_OUI_TYPE_SIZE) != 0) &&
1359 (memcmp( &ptr[2], WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
1360 (memcmp( &ptr[2], P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE) != 0))
1361 {
1362 ielen = ptr[1] + 2;
1363 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
1364 {
1365 vos_mem_copy(&genie[*total_ielen], ptr, ielen);
1366 *total_ielen += ielen;
1367 }
1368 else
1369 {
1370 hddLog( VOS_TRACE_LEVEL_ERROR,
1371 "IE Length is too big "
1372 "IEs eid=%d elem_len=%d total_ie_lent=%d",
1373 elem_id, elem_len, *total_ielen);
1374 }
1375 }
1376 }
1377
1378 left -= elem_len;
1379 ptr += (elem_len + 2);
1380 }
1381 return;
1382}
1383
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001384#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07001385static int wlan_hdd_cfg80211_update_apies(hdd_adapter_t* pHostapdAdapter,
1386 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001387#else
1388static int wlan_hdd_cfg80211_update_apies(hdd_adapter_t* pHostapdAdapter,
1389 struct cfg80211_beacon_data *params)
1390#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07001391{
1392 v_U8_t *genie;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05301393 v_U8_t total_ielen = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07001394 v_U8_t addIE[1] = {0};
Jeff Johnsone7245742012-09-05 17:12:55 -07001395 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07001396
1397 genie = vos_mem_malloc(MAX_GENIE_LEN);
1398
1399 if(genie == NULL) {
1400
1401 return -ENOMEM;
1402 }
1403
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05301404 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
1405 &total_ielen, WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07001406 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05301407 hddLog(LOGE,
1408 FL("Adding WPS IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05301409 ret = -EINVAL;
1410 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001411 }
1412
1413#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05301414 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
1415 &total_ielen, WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE))
1416 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05301417 hddLog(LOGE,
1418 FL("Adding WFD IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05301419 ret = -EINVAL;
1420 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001421 }
1422#endif
1423
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05301424 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
1425 &total_ielen, P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07001426 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05301427 hddLog(LOGE,
1428 FL("Adding P2P IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05301429 ret = -EINVAL;
1430 goto done;
1431 }
1432
1433 if (WLAN_HDD_SOFTAP == pHostapdAdapter->device_mode)
1434 {
Arif Hussaine7f3ea52013-09-12 21:56:36 -07001435 wlan_hdd_add_hostapd_conf_vsie(pHostapdAdapter, genie, &total_ielen);
Jeff Johnson295189b2012-06-20 16:38:30 -07001436 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001437
1438 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1439 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, genie, total_ielen, NULL,
1440 eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
1441 {
1442 hddLog(LOGE,
1443 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001444 ret = -EINVAL;
1445 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001446 }
1447
1448 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1449 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
1450 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
1451 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
1452 ==eHAL_STATUS_FAILURE)
1453 {
1454 hddLog(LOGE,
1455 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001456 ret = -EINVAL;
1457 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001458 }
1459
1460 // Added for ProResp IE
1461 if ( (params->proberesp_ies != NULL) && (params->proberesp_ies_len != 0) )
1462 {
1463 u16 rem_probe_resp_ie_len = params->proberesp_ies_len;
1464 u8 probe_rsp_ie_len[3] = {0};
1465 u8 counter = 0;
1466 /* Check Probe Resp Length if it is greater then 255 then Store
1467 Probe Resp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1 &
1468 WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are not able
1469 Store More then 255 bytes into One Variable.
1470 */
1471 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
1472 {
1473 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
1474 {
1475 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
1476 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
1477 }
1478 else
1479 {
1480 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
1481 rem_probe_resp_ie_len = 0;
1482 }
1483 }
1484
1485 rem_probe_resp_ie_len = 0;
1486
1487 if (probe_rsp_ie_len[0] > 0)
1488 {
1489 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1490 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
1491 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
1492 probe_rsp_ie_len[0], NULL,
1493 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
1494 {
1495 hddLog(LOGE,
1496 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001497 ret = -EINVAL;
1498 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001499 }
1500 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
1501 }
1502
1503 if (probe_rsp_ie_len[1] > 0)
1504 {
1505 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1506 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
1507 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
1508 probe_rsp_ie_len[1], NULL,
1509 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
1510 {
1511 hddLog(LOGE,
1512 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001513 ret = -EINVAL;
1514 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001515 }
1516 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
1517 }
1518
1519 if (probe_rsp_ie_len[2] > 0)
1520 {
1521 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1522 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
1523 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
1524 probe_rsp_ie_len[2], NULL,
1525 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
1526 {
1527 hddLog(LOGE,
1528 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001529 ret = -EINVAL;
1530 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001531 }
1532 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
1533 }
1534
1535 if (probe_rsp_ie_len[1] == 0 )
1536 {
1537 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1538 WNI_CFG_PROBE_RSP_ADDNIE_DATA2, (tANI_U8*)addIE, 0, NULL,
1539 eANI_BOOLEAN_FALSE) )
1540 {
1541 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08001542 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07001543 }
1544 }
1545
1546 if (probe_rsp_ie_len[2] == 0 )
1547 {
1548 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1549 WNI_CFG_PROBE_RSP_ADDNIE_DATA3, (tANI_U8*)addIE, 0, NULL,
1550 eANI_BOOLEAN_FALSE) )
1551 {
1552 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08001553 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07001554 }
1555 }
1556
1557 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1558 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
1559 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
1560 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
1561 == eHAL_STATUS_FAILURE)
1562 {
1563 hddLog(LOGE,
1564 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001565 ret = -EINVAL;
1566 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001567 }
1568 }
1569 else
1570 {
1571 // Reset WNI_CFG_PROBE_RSP Flags
1572 wlan_hdd_reset_prob_rspies(pHostapdAdapter);
1573
1574 hddLog(VOS_TRACE_LEVEL_INFO,
1575 "%s: No Probe Response IE received in set beacon",
1576 __func__);
1577 }
1578
1579 // Added for AssocResp IE
1580 if ( (params->assocresp_ies != NULL) && (params->assocresp_ies_len != 0) )
1581 {
1582 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1583 WNI_CFG_ASSOC_RSP_ADDNIE_DATA, (tANI_U8*)params->assocresp_ies,
1584 params->assocresp_ies_len, NULL,
1585 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
1586 {
1587 hddLog(LOGE,
1588 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001589 ret = -EINVAL;
1590 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001591 }
1592
1593 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1594 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 1, NULL,
1595 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
1596 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
1597 == eHAL_STATUS_FAILURE)
1598 {
1599 hddLog(LOGE,
1600 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001601 ret = -EINVAL;
1602 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001603 }
1604 }
1605 else
1606 {
1607 hddLog(VOS_TRACE_LEVEL_INFO,
1608 "%s: No Assoc Response IE received in set beacon",
1609 __func__);
1610
1611 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1612 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
1613 eANI_BOOLEAN_FALSE) )
1614 {
1615 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08001616 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07001617 }
1618 }
1619
Jeff Johnsone7245742012-09-05 17:12:55 -07001620done:
Jeff Johnson295189b2012-06-20 16:38:30 -07001621 vos_mem_free(genie);
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05301622 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07001623}
Jeff Johnson295189b2012-06-20 16:38:30 -07001624
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301625/*
Jeff Johnson295189b2012-06-20 16:38:30 -07001626 * FUNCTION: wlan_hdd_validate_operation_channel
1627 * called by wlan_hdd_cfg80211_start_bss() and
1628 * wlan_hdd_cfg80211_set_channel()
1629 * This function validates whether given channel is part of valid
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301630 * channel list.
1631 */
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07001632VOS_STATUS wlan_hdd_validate_operation_channel(hdd_adapter_t *pAdapter,int channel)
Jeff Johnson295189b2012-06-20 16:38:30 -07001633{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301634
Jeff Johnson295189b2012-06-20 16:38:30 -07001635 v_U32_t num_ch = 0;
1636 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN];
1637 u32 indx = 0;
1638 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05301639 v_U8_t fValidChannel = FALSE, count = 0;
1640 hdd_config_t *hdd_pConfig_ini= (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301641
Jeff Johnson295189b2012-06-20 16:38:30 -07001642 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
1643
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05301644 if ( hdd_pConfig_ini->sapAllowAllChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -07001645 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05301646 /* Validate the channel */
1647 for (count = RF_CHAN_1 ; count <= RF_CHAN_165 ; count++)
Jeff Johnson295189b2012-06-20 16:38:30 -07001648 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05301649 if ( channel == rfChannels[count].channelNum )
1650 {
1651 fValidChannel = TRUE;
1652 break;
1653 }
1654 }
1655 if (fValidChannel != TRUE)
1656 {
1657 hddLog(VOS_TRACE_LEVEL_ERROR,
1658 "%s: Invalid Channel [%d]", __func__, channel);
1659 return VOS_STATUS_E_FAILURE;
Jeff Johnson295189b2012-06-20 16:38:30 -07001660 }
1661 }
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05301662 else
Jeff Johnson295189b2012-06-20 16:38:30 -07001663 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05301664 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
1665 valid_ch, &num_ch))
1666 {
1667 hddLog(VOS_TRACE_LEVEL_ERROR,
1668 "%s: failed to get valid channel list", __func__);
1669 return VOS_STATUS_E_FAILURE;
1670 }
1671 for (indx = 0; indx < num_ch; indx++)
1672 {
1673 if (channel == valid_ch[indx])
1674 {
1675 break;
1676 }
1677 }
1678
1679 if (indx >= num_ch)
1680 {
1681 hddLog(VOS_TRACE_LEVEL_ERROR,
1682 "%s: Invalid Channel [%d]", __func__, channel);
1683 return VOS_STATUS_E_FAILURE;
1684 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001685 }
1686 return VOS_STATUS_SUCCESS;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301687
Jeff Johnson295189b2012-06-20 16:38:30 -07001688}
1689
Viral Modi3a32cc52013-02-08 11:14:52 -08001690/**
1691 * FUNCTION: wlan_hdd_cfg80211_set_channel
1692 * This function is used to set the channel number
1693 */
1694static int wlan_hdd_cfg80211_set_channel( struct wiphy *wiphy, struct net_device *dev,
1695 struct ieee80211_channel *chan,
1696 enum nl80211_channel_type channel_type
1697 )
1698{
1699 v_U32_t num_ch = 0;
Jeff Johnson4416a782013-03-25 14:17:50 -07001700 int channel = 0;
Viral Modi3a32cc52013-02-08 11:14:52 -08001701 hdd_adapter_t *pAdapter = NULL;
1702 int freq = chan->center_freq; /* freq is in MHZ */
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05301703 hdd_context_t *pHddCtx;
1704 int status;
Viral Modi3a32cc52013-02-08 11:14:52 -08001705
1706 ENTER();
1707
1708 if( NULL == dev )
1709 {
1710 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08001711 "%s: Called with dev = NULL.", __func__);
Viral Modi3a32cc52013-02-08 11:14:52 -08001712 return -ENODEV;
1713 }
1714 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
1715
1716 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -08001717 "%s: device_mode = %d freq = %d", __func__,
Viral Modi3a32cc52013-02-08 11:14:52 -08001718 pAdapter->device_mode, chan->center_freq);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05301719
1720 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1721 status = wlan_hdd_validate_context(pHddCtx);
1722
1723 if (0 != status)
Viral Modi3a32cc52013-02-08 11:14:52 -08001724 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05301725 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1726 "%s: HDD context is not valid", __func__);
1727 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -08001728 }
1729
1730 /*
1731 * Do freq to chan conversion
1732 * TODO: for 11a
1733 */
1734
1735 channel = ieee80211_frequency_to_channel(freq);
1736
1737 /* Check freq range */
1738 if ((WNI_CFG_CURRENT_CHANNEL_STAMIN > channel) ||
1739 (WNI_CFG_CURRENT_CHANNEL_STAMAX < channel))
1740 {
1741 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08001742 "%s: Channel [%d] is outside valid range from %d to %d",
Viral Modi3a32cc52013-02-08 11:14:52 -08001743 __func__, channel, WNI_CFG_CURRENT_CHANNEL_STAMIN,
1744 WNI_CFG_CURRENT_CHANNEL_STAMAX);
1745 return -EINVAL;
1746 }
1747
1748 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
1749
Gopichand Nakkala6ab19562013-03-07 13:59:42 +05301750 if ((WLAN_HDD_SOFTAP != pAdapter->device_mode) &&
1751 (WLAN_HDD_P2P_GO != pAdapter->device_mode))
Viral Modi3a32cc52013-02-08 11:14:52 -08001752 {
1753 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pAdapter,channel))
1754 {
1755 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08001756 "%s: Invalid Channel [%d]", __func__, channel);
Viral Modi3a32cc52013-02-08 11:14:52 -08001757 return -EINVAL;
1758 }
1759 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
1760 "%s: set channel to [%d] for device mode =%d",
1761 __func__, channel,pAdapter->device_mode);
1762 }
1763 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Viral Modi3a32cc52013-02-08 11:14:52 -08001764 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Viral Modi3a32cc52013-02-08 11:14:52 -08001765 )
1766 {
1767 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
1768 tCsrRoamProfile * pRoamProfile = &pWextState->roamProfile;
1769 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
1770
1771 if (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState)
1772 {
1773 /* Link is up then return cant set channel*/
1774 hddLog( VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08001775 "%s: IBSS Associated, can't set the channel", __func__);
Viral Modi3a32cc52013-02-08 11:14:52 -08001776 return -EINVAL;
1777 }
1778
1779 num_ch = pRoamProfile->ChannelInfo.numOfChannels = 1;
1780 pHddStaCtx->conn_info.operationChannel = channel;
1781 pRoamProfile->ChannelInfo.ChannelList =
1782 &pHddStaCtx->conn_info.operationChannel;
1783 }
1784 else if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Viral Modi3a32cc52013-02-08 11:14:52 -08001785 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Viral Modi3a32cc52013-02-08 11:14:52 -08001786 )
1787 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05301788 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
1789 {
1790 if(VOS_STATUS_SUCCESS !=
1791 wlan_hdd_validate_operation_channel(pAdapter,channel))
1792 {
1793 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08001794 "%s: Invalid Channel [%d]", __func__, channel);
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05301795 return -EINVAL;
1796 }
1797 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
1798 }
1799 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
Viral Modi3a32cc52013-02-08 11:14:52 -08001800 {
1801 hdd_config_t *cfg_param = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
1802
1803 /* If auto channel selection is configured as enable/ 1 then ignore
1804 channel set by supplicant
1805 */
1806 if ( cfg_param->apAutoChannelSelection )
1807 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05301808 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel =
1809 AUTO_CHANNEL_SELECT;
Viral Modi3a32cc52013-02-08 11:14:52 -08001810 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
1811 "%s: set channel to auto channel (0) for device mode =%d",
1812 __func__, pAdapter->device_mode);
1813 }
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05301814 else
1815 {
1816 if(VOS_STATUS_SUCCESS !=
1817 wlan_hdd_validate_operation_channel(pAdapter,channel))
1818 {
1819 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08001820 "%s: Invalid Channel [%d]", __func__, channel);
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05301821 return -EINVAL;
1822 }
1823 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
1824 }
Viral Modi3a32cc52013-02-08 11:14:52 -08001825 }
1826 }
1827 else
1828 {
1829 hddLog(VOS_TRACE_LEVEL_FATAL,
1830 "%s: Invalid device mode failed to set valid channel", __func__);
1831 return -EINVAL;
1832 }
1833 EXIT();
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05301834 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -08001835}
1836
Jeff Johnson295189b2012-06-20 16:38:30 -07001837#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
1838static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
1839 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001840#else
1841static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
1842 struct cfg80211_beacon_data *params,
1843 const u8 *ssid, size_t ssid_len,
1844 enum nl80211_hidden_ssid hidden_ssid)
1845#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07001846{
1847 tsap_Config_t *pConfig;
1848 beacon_data_t *pBeacon = NULL;
1849 struct ieee80211_mgmt *pMgmt_frame;
1850 v_U8_t *pIe=NULL;
1851 v_U16_t capab_info;
1852 eCsrAuthType RSNAuthType;
1853 eCsrEncryptionType RSNEncryptType;
1854 eCsrEncryptionType mcRSNEncryptType;
1855 int status = VOS_STATUS_SUCCESS;
1856 tpWLAN_SAPEventCB pSapEventCallback;
1857 hdd_hostapd_state_t *pHostapdState;
1858 v_U8_t wpaRsnIEdata[(SIR_MAC_MAX_IE_LENGTH * 2)+4]; //Max ie length 255 * 2(WPA+RSN) + 2 bytes (vendor specific ID) * 2
1859 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05301860 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07001861 struct qc_mac_acl_entry *acl_entry = NULL;
1862 v_SINT_t i;
Madan Mohan Koyyalamudi543172b2012-12-05 16:40:18 -08001863 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
Chet Lanctot8cecea22014-02-11 19:09:36 -08001864 v_BOOL_t MFPCapable;
1865 v_BOOL_t MFPRequired;
Jeff Johnson295189b2012-06-20 16:38:30 -07001866
1867 ENTER();
1868
1869 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter);
1870
1871 pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
1872
1873 pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
1874
1875 pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
1876
1877 pConfig->beacon_int = pMgmt_frame->u.beacon.beacon_int;
1878
1879 //channel is already set in the set_channel Call back
1880 //pConfig->channel = pCommitConfig->channel;
1881
1882 /*Protection parameter to enable or disable*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301883 pConfig->protEnabled =
Jeff Johnson295189b2012-06-20 16:38:30 -07001884 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtEnabled;
1885
1886 pConfig->dtim_period = pBeacon->dtim_period;
1887
Arif Hussain6d2a3322013-11-17 19:50:10 -08001888 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"****pConfig->dtim_period=%d***",
Jeff Johnson295189b2012-06-20 16:38:30 -07001889 pConfig->dtim_period);
1890
1891
Madan Mohan Koyyalamudie0ca11f2012-11-27 15:57:52 -08001892 if (pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson32d95a32012-09-10 13:15:23 -07001893 {
1894 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -07001895 WLAN_EID_COUNTRY);
Kiet Lam083504c2013-11-25 14:17:45 +05301896 if(memcmp(pHddCtx->cfg_ini->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0)
1897 {
1898 tANI_BOOLEAN restartNeeded;
1899 pConfig->ieee80211d = 1;
1900 vos_mem_copy(pConfig->countryCode, pHddCtx->cfg_ini->apCntryCode, 3);
1901 sme_setRegInfo(hHal, pConfig->countryCode);
1902 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
1903 }
1904 else if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07001905 {
Jeff Johnson32d95a32012-09-10 13:15:23 -07001906 tANI_BOOLEAN restartNeeded;
Jeff Johnson32d95a32012-09-10 13:15:23 -07001907 pConfig->ieee80211d = 1;
1908 vos_mem_copy(pConfig->countryCode, &pIe[2], 3);
1909 sme_setRegInfo(hHal, pConfig->countryCode);
1910 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
Jeff Johnson295189b2012-06-20 16:38:30 -07001911 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07001912 else
1913 {
1914 pConfig->ieee80211d = 0;
1915 }
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05301916 /*
1917 * If auto channel is configured i.e. channel is 0,
1918 * so skip channel validation.
1919 */
1920 if( AUTO_CHANNEL_SELECT != pConfig->channel )
1921 {
1922 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pHostapdAdapter,pConfig->channel))
1923 {
1924 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08001925 "%s: Invalid Channel [%d]", __func__, pConfig->channel);
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05301926 return -EINVAL;
1927 }
1928 }
1929 else
1930 {
1931 if(1 != pHddCtx->is_dynamic_channel_range_set)
1932 {
1933 hdd_config_t *hdd_pConfig= (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini;
1934 WLANSAP_SetChannelRange(hHal, hdd_pConfig->apStartChannelNum,
1935 hdd_pConfig->apEndChannelNum,hdd_pConfig->apOperatingBand);
1936 }
1937 pHddCtx->is_dynamic_channel_range_set = 0;
1938 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001939 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07001940 else
Jeff Johnson295189b2012-06-20 16:38:30 -07001941 {
1942 pConfig->ieee80211d = 0;
1943 }
1944 pConfig->authType = eSAP_AUTO_SWITCH;
1945
1946 capab_info = pMgmt_frame->u.beacon.capab_info;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301947
1948 pConfig->privacy = (pMgmt_frame->u.beacon.capab_info &
Jeff Johnson295189b2012-06-20 16:38:30 -07001949 WLAN_CAPABILITY_PRIVACY) ? VOS_TRUE : VOS_FALSE;
1950
1951 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uPrivacy = pConfig->privacy;
1952
1953 /*Set wps station to configured*/
1954 pIe = wlan_hdd_get_wps_ie_ptr(pBeacon->tail, pBeacon->tail_len);
1955
1956 if(pIe)
1957 {
1958 if(pIe[1] < (2 + WPS_OUI_TYPE_SIZE))
1959 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08001960 hddLog( VOS_TRACE_LEVEL_ERROR, "**Wps Ie Length is too small***");
Jeff Johnson295189b2012-06-20 16:38:30 -07001961 return -EINVAL;
1962 }
1963 else if(memcmp(&pIe[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) == 0)
1964 {
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07001965 hddLog( VOS_TRACE_LEVEL_INFO, "** WPS IE(len %d) ***", (pIe[1]+2));
Jeff Johnson295189b2012-06-20 16:38:30 -07001966 /* Check 15 bit of WPS IE as it contain information for wps state
1967 * WPS state
1968 */
1969 if(SAP_WPS_ENABLED_UNCONFIGURED == pIe[15])
1970 {
1971 pConfig->wps_state = SAP_WPS_ENABLED_UNCONFIGURED;
1972 } else if(SAP_WPS_ENABLED_CONFIGURED == pIe[15])
1973 {
1974 pConfig->wps_state = SAP_WPS_ENABLED_CONFIGURED;
1975 }
1976 }
1977 }
1978 else
1979 {
1980 pConfig->wps_state = SAP_WPS_DISABLED;
1981 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301982 pConfig->fwdWPSPBCProbeReq = 1; // Forward WPS PBC probe request frame up
Jeff Johnson295189b2012-06-20 16:38:30 -07001983
1984 pConfig->RSNWPAReqIELength = 0;
1985 pConfig->pRSNWPAReqIE = NULL;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301986 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -07001987 WLAN_EID_RSN);
1988 if(pIe && pIe[1])
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301989 {
Jeff Johnson295189b2012-06-20 16:38:30 -07001990 pConfig->RSNWPAReqIELength = pIe[1] + 2;
1991 memcpy(&wpaRsnIEdata[0], pIe, pConfig->RSNWPAReqIELength);
1992 pConfig->pRSNWPAReqIE = &wpaRsnIEdata[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301993 /* The actual processing may eventually be more extensive than
1994 * this. Right now, just consume any PMKIDs that are sent in
Jeff Johnson295189b2012-06-20 16:38:30 -07001995 * by the app.
1996 * */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301997 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -07001998 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
1999 &RSNEncryptType,
2000 &mcRSNEncryptType,
2001 &RSNAuthType,
Chet Lanctot8cecea22014-02-11 19:09:36 -08002002 &MFPCapable,
2003 &MFPRequired,
Jeff Johnson295189b2012-06-20 16:38:30 -07002004 pConfig->pRSNWPAReqIE[1]+2,
2005 pConfig->pRSNWPAReqIE );
2006
2007 if( VOS_STATUS_SUCCESS == status )
2008 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302009 /* Now copy over all the security attributes you have
2010 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -07002011 * */
2012 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
2013 pConfig->mcRSNEncryptType = mcRSNEncryptType;
2014 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
2015 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05302016 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -08002017 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -07002018 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
2019 }
2020 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302021
Jeff Johnson295189b2012-06-20 16:38:30 -07002022 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE,
2023 pBeacon->tail, pBeacon->tail_len);
2024
2025 if(pIe && pIe[1] && (pIe[0] == DOT11F_EID_WPA))
2026 {
2027 if (pConfig->pRSNWPAReqIE)
2028 {
2029 /*Mixed mode WPA/WPA2*/
2030 memcpy((&wpaRsnIEdata[0] + pConfig->RSNWPAReqIELength), pIe, pIe[1] + 2);
2031 pConfig->RSNWPAReqIELength += pIe[1] + 2;
2032 }
2033 else
2034 {
2035 pConfig->RSNWPAReqIELength = pIe[1] + 2;
2036 memcpy(&wpaRsnIEdata[0], pIe, pConfig->RSNWPAReqIELength);
2037 pConfig->pRSNWPAReqIE = &wpaRsnIEdata[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302038 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -07002039 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
2040 &RSNEncryptType,
2041 &mcRSNEncryptType,
2042 &RSNAuthType,
Chet Lanctot8cecea22014-02-11 19:09:36 -08002043 &MFPCapable,
2044 &MFPRequired,
Jeff Johnson295189b2012-06-20 16:38:30 -07002045 pConfig->pRSNWPAReqIE[1]+2,
2046 pConfig->pRSNWPAReqIE );
2047
2048 if( VOS_STATUS_SUCCESS == status )
2049 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302050 /* Now copy over all the security attributes you have
2051 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -07002052 * */
2053 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
2054 pConfig->mcRSNEncryptType = mcRSNEncryptType;
2055 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
2056 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05302057 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -08002058 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -07002059 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
2060 }
2061 }
2062 }
2063
Jeff Johnson4416a782013-03-25 14:17:50 -07002064 if (pConfig->RSNWPAReqIELength > sizeof wpaRsnIEdata) {
2065 hddLog( VOS_TRACE_LEVEL_ERROR, "**RSNWPAReqIELength is too large***");
2066 return -EINVAL;
2067 }
2068
Jeff Johnson295189b2012-06-20 16:38:30 -07002069 pConfig->SSIDinfo.ssidHidden = VOS_FALSE;
2070
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002071#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07002072 if (params->ssid != NULL)
2073 {
2074 memcpy(pConfig->SSIDinfo.ssid.ssId, params->ssid, params->ssid_len);
2075 pConfig->SSIDinfo.ssid.length = params->ssid_len;
2076 if (params->hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
2077 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
2078 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002079#else
2080 if (ssid != NULL)
2081 {
2082 memcpy(pConfig->SSIDinfo.ssid.ssId, ssid, ssid_len);
2083 pConfig->SSIDinfo.ssid.length = ssid_len;
2084 if (hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
2085 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
2086 }
2087#endif
2088
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302089 vos_mem_copy(pConfig->self_macaddr.bytes,
Jeff Johnson295189b2012-06-20 16:38:30 -07002090 pHostapdAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302091
Jeff Johnson295189b2012-06-20 16:38:30 -07002092 /* default value */
2093 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
2094 pConfig->num_accept_mac = 0;
2095 pConfig->num_deny_mac = 0;
2096
2097 pIe = wlan_hdd_get_vendor_oui_ie_ptr(BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
2098 pBeacon->tail, pBeacon->tail_len);
2099
2100 /* pIe for black list is following form:
2101 type : 1 byte
2102 length : 1 byte
2103 OUI : 4 bytes
2104 acl type : 1 byte
2105 no of mac addr in black list: 1 byte
2106 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302107 */
2108 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07002109 {
2110 pConfig->SapMacaddr_acl = pIe[6];
2111 pConfig->num_deny_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -08002112 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no deny mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07002113 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05302114 if (pConfig->num_deny_mac > MAX_ACL_MAC_ADDRESS)
2115 pConfig->num_deny_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07002116 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
2117 for (i = 0; i < pConfig->num_deny_mac; i++)
2118 {
2119 vos_mem_copy(&pConfig->deny_mac[i], acl_entry->addr, sizeof(qcmacaddr));
2120 acl_entry++;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302121 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002122 }
2123 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
2124 pBeacon->tail, pBeacon->tail_len);
2125
2126 /* pIe for white list is following form:
2127 type : 1 byte
2128 length : 1 byte
2129 OUI : 4 bytes
2130 acl type : 1 byte
2131 no of mac addr in white list: 1 byte
2132 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302133 */
2134 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07002135 {
2136 pConfig->SapMacaddr_acl = pIe[6];
2137 pConfig->num_accept_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -08002138 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no accept mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07002139 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05302140 if (pConfig->num_accept_mac > MAX_ACL_MAC_ADDRESS)
2141 pConfig->num_accept_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07002142 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
2143 for (i = 0; i < pConfig->num_accept_mac; i++)
2144 {
2145 vos_mem_copy(&pConfig->accept_mac[i], acl_entry->addr, sizeof(qcmacaddr));
2146 acl_entry++;
2147 }
2148 }
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05302149
Jeff Johnson295189b2012-06-20 16:38:30 -07002150 wlan_hdd_set_sapHwmode(pHostapdAdapter);
2151
Jeff Johnsone7245742012-09-05 17:12:55 -07002152#ifdef WLAN_FEATURE_11AC
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -08002153 /* Overwrite the hostapd setting for HW mode only for 11ac.
Kiet Lam0f320422013-11-21 19:29:17 +05302154 * This is valid only if mode is set to 11n in hostapd, either AUTO or
2155 * 11ac in .ini and 11ac is supported by both host and firmware.
2156 * Otherwise, leave whatever is set in hostapd (a OR b OR g OR n mode)
2157 */
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -08002158 if( ((pConfig->SapHw_mode == eSAP_DOT11_MODE_11n) ||
2159 (pConfig->SapHw_mode == eSAP_DOT11_MODE_11n_ONLY)) &&
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302160 (((WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->dot11Mode == eHDD_DOT11_MODE_AUTO) ||
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -08002161 ((WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->dot11Mode == eHDD_DOT11_MODE_11ac) ||
Kiet Lam0f320422013-11-21 19:29:17 +05302162 ((WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->dot11Mode == eHDD_DOT11_MODE_11ac_ONLY)) &&
2163 (sme_IsFeatureSupportedByDriver(DOT11AC)) && (sme_IsFeatureSupportedByFW(DOT11AC)) )
Jeff Johnsone7245742012-09-05 17:12:55 -07002164 {
2165 pConfig->SapHw_mode = eSAP_DOT11_MODE_11ac;
Ravi Joshi83bfaa12013-05-28 22:12:08 -07002166
2167 /* Disable VHT support in 2.4 GHz band */
2168 if (pConfig->channel <= 14 &&
2169 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->enableVhtFor24GHzBand == FALSE)
2170 {
2171 pConfig->SapHw_mode = eSAP_DOT11_MODE_11n;
2172 }
Jeff Johnsone7245742012-09-05 17:12:55 -07002173 }
2174#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302175
Ravi Joshiaeb7d9e2013-05-02 12:28:14 -07002176 if ( AUTO_CHANNEL_SELECT != pConfig->channel )
2177 {
2178 sme_SelectCBMode(hHal,
2179 sapConvertSapPhyModeToCsrPhyMode(pConfig->SapHw_mode),
2180 pConfig->channel);
2181 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002182 // ht_capab is not what the name conveys,this is used for protection bitmap
2183 pConfig->ht_capab =
2184 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtection;
2185
2186 if ( 0 != wlan_hdd_cfg80211_update_apies(pHostapdAdapter, params) )
2187 {
2188 hddLog(LOGE, FL("SAP Not able to set AP IEs"));
2189 return -EINVAL;
2190 }
2191
2192 //Uapsd Enabled Bit
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302193 pConfig->UapsdEnable =
Jeff Johnson295189b2012-06-20 16:38:30 -07002194 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apUapsdEnabled;
2195 //Enable OBSS protection
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302196 pConfig->obssProtEnabled =
2197 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apOBSSProtEnabled;
Jeff Johnson295189b2012-06-20 16:38:30 -07002198
Chet Lanctot8cecea22014-02-11 19:09:36 -08002199#ifdef WLAN_FEATURE_11W
2200 pConfig->mfpCapable = MFPCapable;
2201 pConfig->mfpRequired = MFPRequired;
2202 hddLog(LOGW, FL("Soft AP MFP capable %d, MFP required %d\n"),
2203 pConfig->mfpCapable, pConfig->mfpRequired);
2204#endif
2205
Arif Hussain6d2a3322013-11-17 19:50:10 -08002206 hddLog(LOGW, FL("SOftAP macaddress : "MAC_ADDRESS_STR),
Jeff Johnson295189b2012-06-20 16:38:30 -07002207 MAC_ADDR_ARRAY(pHostapdAdapter->macAddressCurrent.bytes));
Arif Hussain6d2a3322013-11-17 19:50:10 -08002208 hddLog(LOGW,FL("ssid =%s, beaconint=%d, channel=%d"),
2209 pConfig->SSIDinfo.ssid.ssId, (int)pConfig->beacon_int,
2210 (int)pConfig->channel);
2211 hddLog(LOGW,FL("hw_mode=%x, privacy=%d, authType=%d"),
2212 pConfig->SapHw_mode, pConfig->privacy,
2213 pConfig->authType);
2214 hddLog(LOGW,FL("RSN/WPALen=%d, Uapsd = %d"),
2215 (int)pConfig->RSNWPAReqIELength, pConfig->UapsdEnable);
2216 hddLog(LOGW,FL("ProtEnabled = %d, OBSSProtEnabled = %d"),
2217 pConfig->protEnabled, pConfig->obssProtEnabled);
Jeff Johnson295189b2012-06-20 16:38:30 -07002218
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302219 if(test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -07002220 {
2221 //Bss already started. just return.
2222 //TODO Probably it should update some beacon params.
2223 hddLog( LOGE, "Bss Already started...Ignore the request");
2224 EXIT();
2225 return 0;
2226 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302227
Jeff Johnson295189b2012-06-20 16:38:30 -07002228 pConfig->persona = pHostapdAdapter->device_mode;
2229
2230 pSapEventCallback = hdd_hostapd_SAPEventCB;
2231 if(WLANSAP_StartBss(pVosContext, pSapEventCallback, pConfig,
2232 (v_PVOID_t)pHostapdAdapter->dev) != VOS_STATUS_SUCCESS)
2233 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08002234 hddLog(LOGE,FL("SAP Start Bss fail"));
Jeff Johnson295189b2012-06-20 16:38:30 -07002235 return -EINVAL;
2236 }
2237
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302238 hddLog(LOG1,
Jeff Johnson295189b2012-06-20 16:38:30 -07002239 FL("Waiting for Scan to complete(auto mode) and BSS to start"));
2240
2241 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302242
Jeff Johnson295189b2012-06-20 16:38:30 -07002243 if (!VOS_IS_STATUS_SUCCESS(status))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302244 {
2245 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08002246 ("ERROR: HDD vos wait for single_event failed!!"));
Tushnim Bhattacharyyaad37df12013-10-02 12:01:33 -07002247 smeGetCommandQStatus(hHal);
Jeff Johnson295189b2012-06-20 16:38:30 -07002248 VOS_ASSERT(0);
2249 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302250
Jeff Johnson295189b2012-06-20 16:38:30 -07002251 //Succesfully started Bss update the state bit.
2252 set_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags);
2253
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07002254#ifdef WLAN_FEATURE_P2P_DEBUG
2255 if (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO)
2256 {
2257 if(globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED)
2258 {
2259 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
2260 hddLog(LOGE,"[P2P State] From Go nego completed to "
Jeff Johnson1250df42012-12-10 14:31:52 -08002261 "Non-autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07002262 }
2263 else if(globalP2PConnectionStatus == P2P_NOT_ACTIVE)
2264 {
2265 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
2266 hddLog(LOGE,"[P2P State] From Inactive to "
Jeff Johnson1250df42012-12-10 14:31:52 -08002267 "Autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07002268 }
2269 }
2270#endif
2271
Jeff Johnson295189b2012-06-20 16:38:30 -07002272 pHostapdState->bCommit = TRUE;
2273 EXIT();
2274
2275 return 0;
2276}
2277
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002278#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302279static int wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy,
2280 struct net_device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -07002281 struct beacon_parameters *params)
2282{
2283 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302284 hdd_context_t *pHddCtx;
2285 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07002286
2287 ENTER();
2288
Arif Hussain6d2a3322013-11-17 19:50:10 -08002289 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "device mode=%d",pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07002290
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302291 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2292 status = wlan_hdd_validate_context(pHddCtx);
2293
2294 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002295 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302296 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2297 "%s: HDD context is not valid", __func__);
2298 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002299 }
2300
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302301 if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07002302 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07002303 )
2304 {
2305 beacon_data_t *old,*new;
2306
2307 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302308
Jeff Johnson295189b2012-06-20 16:38:30 -07002309 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302310 {
2311 hddLog(VOS_TRACE_LEVEL_WARN,
2312 FL("already beacon info added to session(%d)"),
2313 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07002314 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302315 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002316
2317 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
2318
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302319 if(status != VOS_STATUS_SUCCESS)
Jeff Johnson295189b2012-06-20 16:38:30 -07002320 {
2321 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08002322 "%s:Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002323 return -EINVAL;
2324 }
2325
2326 pAdapter->sessionCtx.ap.beacon = new;
2327
2328 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
2329 }
2330
2331 EXIT();
2332 return status;
2333}
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302334
2335static int wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07002336 struct net_device *dev,
2337 struct beacon_parameters *params)
2338{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302339 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302340 hdd_context_t *pHddCtx;
2341 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07002342
2343 ENTER();
2344
Arif Hussain6d2a3322013-11-17 19:50:10 -08002345 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07002346 __func__,pAdapter->device_mode);
2347
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302348 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2349 status = wlan_hdd_validate_context(pHddCtx);
2350
2351 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002352 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302353 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2354 "%s: HDD context is not valid", __func__);
2355 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002356 }
2357
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302358 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07002359 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302360 )
Jeff Johnson295189b2012-06-20 16:38:30 -07002361 {
2362 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302363
Jeff Johnson295189b2012-06-20 16:38:30 -07002364 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302365
Jeff Johnson295189b2012-06-20 16:38:30 -07002366 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302367 {
2368 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2369 FL("session(%d) old and new heads points to NULL"),
2370 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07002371 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302372 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002373
2374 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
2375
2376 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302377 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08002378 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002379 return -EINVAL;
2380 }
2381
2382 pAdapter->sessionCtx.ap.beacon = new;
2383
2384 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
2385 }
2386
2387 EXIT();
2388 return status;
2389}
2390
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002391#endif //(LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
2392
2393#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07002394static int wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy,
2395 struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002396#else
2397static int wlan_hdd_cfg80211_stop_ap (struct wiphy *wiphy,
2398 struct net_device *dev)
2399#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07002400{
2401 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnsone7245742012-09-05 17:12:55 -07002402 hdd_context_t *pHddCtx = NULL;
2403 hdd_scaninfo_t *pScanInfo = NULL;
2404 hdd_adapter_t *staAdapter = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302405 VOS_STATUS status;
Jeff Johnson295189b2012-06-20 16:38:30 -07002406
2407 ENTER();
2408
2409 if (NULL == pAdapter)
2410 {
2411 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002412 "%s: HDD adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002413 return -ENODEV;
2414 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07002415
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302416 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2417 status = wlan_hdd_validate_context(pHddCtx);
2418
2419 if (0 != status)
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07002420 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302421 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2422 "%s: HDD context is not valid", __func__);
2423 return status;
Jeff Johnson4416a782013-03-25 14:17:50 -07002424 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07002425
2426 staAdapter = hdd_get_adapter(pAdapter->pHddCtx, WLAN_HDD_INFRA_STATION);
2427 if (NULL == staAdapter)
2428 {
2429 staAdapter = hdd_get_adapter(pAdapter->pHddCtx, WLAN_HDD_P2P_CLIENT);
2430 if (NULL == staAdapter)
2431 {
Rajesh Chauhan52d885b2013-11-01 10:54:25 -07002432 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
2433 "%s: HDD adapter context for STA/P2P-CLI is Null",
2434 __func__);
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07002435 }
2436 }
2437
2438 pScanInfo = &pHddCtx->scan_info;
2439
Arif Hussain6d2a3322013-11-17 19:50:10 -08002440 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07002441 __func__,pAdapter->device_mode);
2442
Rajesh Chauhan52d885b2013-11-01 10:54:25 -07002443 if ((pScanInfo != NULL) && pScanInfo->mScanPending && staAdapter)
Jeff Johnsone7245742012-09-05 17:12:55 -07002444 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302445 long ret;
2446
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -08002447 INIT_COMPLETION(pScanInfo->abortscan_event_var);
Srinivas, Dasari138af4f2014-02-07 11:13:45 +05302448 hdd_abort_mac_scan(staAdapter->pHddCtx, pAdapter->sessionId,
2449 eCSR_SCAN_ABORT_DEFAULT);
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302450 ret = wait_for_completion_interruptible_timeout(
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -08002451 &pScanInfo->abortscan_event_var,
Jeff Johnsone7245742012-09-05 17:12:55 -07002452 msecs_to_jiffies(WLAN_WAIT_TIME_ABORTSCAN));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302453 if (ret <= 0)
Jeff Johnsone7245742012-09-05 17:12:55 -07002454 {
Rajesh Chauhan52d885b2013-11-01 10:54:25 -07002455 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302456 FL("Timeout occurred while waiting for abortscan %ld"),
2457 ret);
Yue Ma4f55ef32014-01-23 16:45:33 -08002458
2459 if (pHddCtx->isLogpInProgress)
2460 {
2461 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2462 "%s: LOGP in Progress. Ignore!!!", __func__);
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302463
2464 VOS_ASSERT(pScanInfo->mScanPending);
Yue Ma4f55ef32014-01-23 16:45:33 -08002465 return -EAGAIN;
2466 }
Jeff Johnsone7245742012-09-05 17:12:55 -07002467 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -07002468 }
2469 }
2470
Arun Kumar Khandavallia3bd8002014-01-17 16:21:19 +05302471 hdd_hostapd_stop(dev);
2472
Jeff Johnson295189b2012-06-20 16:38:30 -07002473 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07002474 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07002475 )
2476 {
2477 beacon_data_t *old;
2478
2479 old = pAdapter->sessionCtx.ap.beacon;
2480
2481 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302482 {
2483 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2484 FL("session(%d) beacon data points to NULL"),
2485 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07002486 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302487 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002488
Jeff Johnson295189b2012-06-20 16:38:30 -07002489 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07002490
2491 mutex_lock(&pHddCtx->sap_lock);
2492 if(test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
2493 {
Jeff Johnson4416a782013-03-25 14:17:50 -07002494 if ( VOS_STATUS_SUCCESS == (status = WLANSAP_StopBss(pHddCtx->pvosContext) ) )
Jeff Johnson295189b2012-06-20 16:38:30 -07002495 {
2496 hdd_hostapd_state_t *pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
2497
2498 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
2499
2500 if (!VOS_IS_STATUS_SUCCESS(status))
2501 {
2502 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08002503 ("ERROR: HDD vos wait for single_event failed!!"));
Jeff Johnson295189b2012-06-20 16:38:30 -07002504 VOS_ASSERT(0);
2505 }
2506 }
2507 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
2508 }
2509 mutex_unlock(&pHddCtx->sap_lock);
2510
2511 if(status != VOS_STATUS_SUCCESS)
2512 {
2513 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08002514 "%s:Error!!! Stopping the BSS",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002515 return -EINVAL;
2516 }
2517
Jeff Johnson4416a782013-03-25 14:17:50 -07002518 if (ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -07002519 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 0,NULL, eANI_BOOLEAN_FALSE)
2520 ==eHAL_STATUS_FAILURE)
2521 {
2522 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08002523 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07002524 }
2525
Jeff Johnson4416a782013-03-25 14:17:50 -07002526 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -07002527 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
2528 eANI_BOOLEAN_FALSE) )
2529 {
2530 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08002531 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07002532 }
2533
2534 // Reset WNI_CFG_PROBE_RSP Flags
2535 wlan_hdd_reset_prob_rspies(pAdapter);
2536
2537 pAdapter->sessionCtx.ap.beacon = NULL;
2538 kfree(old);
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07002539#ifdef WLAN_FEATURE_P2P_DEBUG
2540 if((pAdapter->device_mode == WLAN_HDD_P2P_GO) &&
2541 (globalP2PConnectionStatus == P2P_GO_COMPLETED_STATE))
2542 {
2543 hddLog(LOGE,"[P2P State] From GO completed to Inactive state "
2544 "GO got removed");
2545 globalP2PConnectionStatus = P2P_NOT_ACTIVE;
2546 }
2547#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07002548 }
2549 EXIT();
2550 return status;
2551}
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002552
2553#if (LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
2554
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302555static int wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
2556 struct net_device *dev,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002557 struct cfg80211_ap_settings *params)
2558{
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302559 hdd_adapter_t *pAdapter;
2560 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302561 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002562
2563 ENTER();
2564
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302565 if (NULL == dev)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07002566 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302567 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302568 "%s: Device is Null", __func__);
2569 return -ENODEV;
2570 }
2571
2572 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2573 if (NULL == pAdapter)
2574 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302575 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302576 "%s: HDD adapter is Null", __func__);
2577 return -ENODEV;
2578 }
2579
2580 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
2581 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302582 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302583 "%s: HDD adapter magic is invalid", __func__);
2584 return -ENODEV;
2585 }
2586
2587 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302588 status = wlan_hdd_validate_context(pHddCtx);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302589
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302590 if (0 != status)
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302591 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302592 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2593 "%s: HDD context is not valid", __func__);
2594 return status;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302595 }
2596
2597 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device mode = %d",
2598 __func__, pAdapter->device_mode);
2599
2600 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002601 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002602 )
2603 {
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302604 beacon_data_t *old, *new;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002605
2606 old = pAdapter->sessionCtx.ap.beacon;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302607
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002608 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302609 {
2610 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
2611 FL("already beacon info added to session(%d)"),
2612 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002613 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302614 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002615
2616 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter, &new, &params->beacon, params->dtim_period);
2617
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302618 if (status != 0)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002619 {
2620 hddLog(VOS_TRACE_LEVEL_FATAL,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302621 "%s:Error!!! Allocating the new beacon", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002622 return -EINVAL;
2623 }
2624 pAdapter->sessionCtx.ap.beacon = new;
Viral Modi3a32cc52013-02-08 11:14:52 -08002625#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
Yue Maf49ba872013-08-19 12:04:25 -07002626 wlan_hdd_cfg80211_set_channel(wiphy, dev,
2627#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
2628 params->channel, params->channel_type);
2629#else
2630 params->chandef.chan, cfg80211_get_chandef_type(&(params->chandef)));
2631#endif
Viral Modi3a32cc52013-02-08 11:14:52 -08002632#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002633 status = wlan_hdd_cfg80211_start_bss(pAdapter, &params->beacon, params->ssid,
2634 params->ssid_len, params->hidden_ssid);
2635 }
2636
2637 EXIT();
2638 return status;
2639}
2640
2641
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302642static int wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002643 struct net_device *dev,
2644 struct cfg80211_beacon_data *params)
2645{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302646 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302647 hdd_context_t *pHddCtx;
2648 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002649
2650 ENTER();
2651
Arif Hussain6d2a3322013-11-17 19:50:10 -08002652 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002653 __func__, pAdapter->device_mode);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302654
2655 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2656 status = wlan_hdd_validate_context(pHddCtx);
2657
2658 if (0 != status)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07002659 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302660 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2661 "%s: HDD context is not valid", __func__);
2662 return status;
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07002663 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002664
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302665 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002666 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302667 )
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002668 {
2669 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302670
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002671 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302672
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002673 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302674 {
2675 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2676 FL("session(%d) beacon data points to NULL"),
2677 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002678 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302679 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002680
2681 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter, &new, params, 0);
2682
2683 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302684 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08002685 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002686 return -EINVAL;
2687 }
2688
2689 pAdapter->sessionCtx.ap.beacon = new;
2690
2691 status = wlan_hdd_cfg80211_start_bss(pAdapter, params, NULL, 0, 0);
2692 }
2693
2694 EXIT();
2695 return status;
2696}
2697
2698#endif //(LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
2699
Jeff Johnson295189b2012-06-20 16:38:30 -07002700
2701static int wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
2702 struct net_device *dev,
2703 struct bss_parameters *params)
2704{
2705 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2706
2707 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302708
Arif Hussain6d2a3322013-11-17 19:50:10 -08002709 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07002710 __func__,pAdapter->device_mode);
2711
2712 if((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07002713 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302714 )
Jeff Johnson295189b2012-06-20 16:38:30 -07002715 {
2716 /* ap_isolate == -1 means that in change bss, upper layer doesn't
2717 * want to update this parameter */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302718 if (-1 != params->ap_isolate)
Jeff Johnson295189b2012-06-20 16:38:30 -07002719 {
2720 pAdapter->sessionCtx.ap.apDisableIntraBssFwd = !!params->ap_isolate;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302721 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002722 }
2723
2724 EXIT();
2725 return 0;
2726}
2727
Kiet Lam10841362013-11-01 11:36:50 +05302728/* FUNCTION: wlan_hdd_change_country_code_cd
2729* to wait for contry code completion
2730*/
2731void* wlan_hdd_change_country_code_cb(void *pAdapter)
2732{
2733 hdd_adapter_t *call_back_pAdapter = pAdapter;
2734 complete(&call_back_pAdapter->change_country_code);
2735 return NULL;
2736}
2737
Jeff Johnson295189b2012-06-20 16:38:30 -07002738/*
2739 * FUNCTION: wlan_hdd_cfg80211_change_iface
2740 * This function is used to set the interface type (INFRASTRUCTURE/ADHOC)
2741 */
2742int wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
2743 struct net_device *ndev,
2744 enum nl80211_iftype type,
2745 u32 *flags,
2746 struct vif_params *params
2747 )
2748{
2749 struct wireless_dev *wdev;
2750 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Rajesh Chauhana0516c62014-01-30 16:11:18 -08002751 hdd_context_t *pHddCtx;
Mohit Khanna0f232092012-09-11 14:46:08 -07002752 hdd_adapter_t *pP2pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07002753 tCsrRoamProfile *pRoamProfile = NULL;
2754 eCsrRoamBssType LastBSSType;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302755 hdd_config_t *pConfig = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07002756 eMib_dot11DesiredBssType connectedBssType;
2757 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302758 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07002759
2760 ENTER();
2761
Rajesh Chauhana0516c62014-01-30 16:11:18 -08002762 if (!pAdapter)
2763 {
2764 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2765 "%s: Adapter context is null", __func__);
2766 return VOS_STATUS_E_FAILURE;
2767 }
2768
2769 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2770 if (!pHddCtx)
2771 {
2772 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2773 "%s: HDD context is null", __func__);
2774 return VOS_STATUS_E_FAILURE;
2775 }
2776
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302777 status = wlan_hdd_validate_context(pHddCtx);
2778
2779 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -07002780 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302781 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2782 "%s: HDD context is not valid", __func__);
2783 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -07002784 }
2785
2786 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
2787 __func__, pAdapter->device_mode);
2788
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302789 pConfig = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -07002790 wdev = ndev->ieee80211_ptr;
2791
2792#ifdef WLAN_BTAMP_FEATURE
2793 if((NL80211_IFTYPE_P2P_CLIENT == type)||
2794 (NL80211_IFTYPE_ADHOC == type)||
2795 (NL80211_IFTYPE_AP == type)||
2796 (NL80211_IFTYPE_P2P_GO == type))
2797 {
2798 pHddCtx->isAmpAllowed = VOS_FALSE;
2799 // stop AMP traffic
2800 status = WLANBAP_StopAmp();
2801 if(VOS_STATUS_SUCCESS != status )
2802 {
2803 pHddCtx->isAmpAllowed = VOS_TRUE;
2804 hddLog(VOS_TRACE_LEVEL_FATAL,
2805 "%s: Failed to stop AMP", __func__);
2806 return -EINVAL;
2807 }
2808 }
2809#endif //WLAN_BTAMP_FEATURE
2810 /* Reset the current device mode bit mask*/
2811 wlan_hdd_clear_concurrency_mode(pHddCtx, pAdapter->device_mode);
2812
2813 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -07002814 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnsone7245742012-09-05 17:12:55 -07002815 || (pAdapter->device_mode == WLAN_HDD_P2P_DEVICE)
Jeff Johnson295189b2012-06-20 16:38:30 -07002816 )
2817 {
2818 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -08002819 if (!pWextState)
2820 {
2821 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2822 "%s: pWextState is null", __func__);
2823 return VOS_STATUS_E_FAILURE;
2824 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002825 pRoamProfile = &pWextState->roamProfile;
2826 LastBSSType = pRoamProfile->BSSType;
2827
2828 switch (type)
2829 {
2830 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -07002831 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -07002832 hddLog(VOS_TRACE_LEVEL_INFO,
2833 "%s: setting interface Type to INFRASTRUCTURE", __func__);
2834 pRoamProfile->BSSType = eCSR_BSS_TYPE_INFRASTRUCTURE;
Jeff Johnsone7245742012-09-05 17:12:55 -07002835#ifdef WLAN_FEATURE_11AC
2836 if(pConfig->dot11Mode == eHDD_DOT11_MODE_AUTO)
2837 {
2838 pConfig->dot11Mode = eHDD_DOT11_MODE_11ac;
2839 }
2840#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302841 pRoamProfile->phyMode =
Jeff Johnsone7245742012-09-05 17:12:55 -07002842 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07002843 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08002844 //Check for sub-string p2p to confirm its a p2p interface
2845 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302846 {
Gopichand Nakkala864d3552012-12-31 16:08:51 -08002847 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
2848 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
2849 }
2850 else
2851 {
2852 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -07002853 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -08002854 }
Madan Mohan Koyyalamudi81746922013-07-17 14:38:51 +05302855#ifdef FEATURE_WLAN_TDLS
2856 /* The open adapter for the p2p shall skip initializations in
2857 * tdls_init if the device mode is WLAN_HDD_P2P_DEVICE, for
2858 * TDLS is supported only on WLAN_HDD_P2P_CLIENT. Hence invoke
2859 * tdls_init when the change_iface sets the device mode to
2860 * WLAN_HDD_P2P_CLIENT.
2861 */
2862
2863 if ( pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
2864 {
2865 if (0 != wlan_hdd_tdls_init (pAdapter))
2866 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302867 hddLog(VOS_TRACE_LEVEL_ERROR,
2868 "%s: tdls initialization failed", __func__);
Madan Mohan Koyyalamudi81746922013-07-17 14:38:51 +05302869 return -EINVAL;
2870 }
2871 }
2872#endif
2873
Jeff Johnson295189b2012-06-20 16:38:30 -07002874 break;
2875 case NL80211_IFTYPE_ADHOC:
2876 hddLog(VOS_TRACE_LEVEL_INFO,
2877 "%s: setting interface Type to ADHOC", __func__);
2878 pRoamProfile->BSSType = eCSR_BSS_TYPE_START_IBSS;
2879 pRoamProfile->phyMode =
2880 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Shailender Karmuchia734f332013-04-19 14:02:48 -07002881 pAdapter->device_mode = WLAN_HDD_IBSS;
Jeff Johnson295189b2012-06-20 16:38:30 -07002882 wdev->iftype = type;
2883 break;
2884
2885 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -07002886 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07002887 {
2888 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
2889 "%s: setting interface Type to %s", __func__,
2890 (type == NL80211_IFTYPE_AP) ? "SoftAP" : "P2pGo");
2891
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08002892 //Cancel any remain on channel for GO mode
2893 if (NL80211_IFTYPE_P2P_GO == type)
2894 {
2895 wlan_hdd_cancel_existing_remain_on_channel(pAdapter);
2896 }
Mohit Khanna0f232092012-09-11 14:46:08 -07002897 if (NL80211_IFTYPE_AP == type)
2898 {
2899 /* As Loading WLAN Driver one interface being created for p2p device
2900 * address. This will take one HW STA and the max number of clients
2901 * that can connect to softAP will be reduced by one. so while changing
2902 * the interface type to NL80211_IFTYPE_AP (SoftAP) remove p2p0
2903 * interface as it is not required in SoftAP mode.
2904 */
2905
2906 // Get P2P Adapter
2907 pP2pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_DEVICE);
2908
2909 if (pP2pAdapter)
2910 {
2911 hdd_stop_adapter(pHddCtx, pP2pAdapter);
2912 hdd_deinit_adapter(pHddCtx, pP2pAdapter);
2913 hdd_close_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
2914 }
2915 }
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05302916#ifdef FEATURE_WLAN_TDLS
Mohit Khanna0f232092012-09-11 14:46:08 -07002917
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05302918 /* A Mutex Lock is introduced while changing the mode to
2919 * protect the concurrent access for the Adapters by TDLS
2920 * module.
2921 */
2922 if (mutex_lock_interruptible(&pHddCtx->tdls_lock))
2923 {
2924 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2925 "%s: unable to lock list", __func__);
2926 return -EINVAL;
2927 }
2928#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07002929 //De-init the adapter.
2930 hdd_stop_adapter( pHddCtx, pAdapter );
2931 hdd_deinit_adapter( pHddCtx, pAdapter );
2932 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
Jeff Johnson295189b2012-06-20 16:38:30 -07002933 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
2934 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05302935#ifdef FEATURE_WLAN_TDLS
2936 mutex_unlock(&pHddCtx->tdls_lock);
2937#endif
Jeff Johnson32d95a32012-09-10 13:15:23 -07002938
2939 //Disable BMPS and IMPS if enabled
2940 //before starting Go
2941 if(WLAN_HDD_P2P_GO == pAdapter->device_mode)
2942 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302943 if(VOS_STATUS_E_FAILURE ==
Jeff Johnson32d95a32012-09-10 13:15:23 -07002944 hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_P2P_GO))
2945 {
2946 //Fail to Exit BMPS
2947 VOS_ASSERT(0);
2948 }
2949 }
2950
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -07002951 if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) &&
2952 (pConfig->apRandomBssidEnabled))
2953 {
2954 /* To meet Android requirements create a randomized
2955 MAC address of the form 02:1A:11:Fx:xx:xx */
2956 get_random_bytes(&ndev->dev_addr[3], 3);
2957 ndev->dev_addr[0] = 0x02;
2958 ndev->dev_addr[1] = 0x1A;
2959 ndev->dev_addr[2] = 0x11;
2960 ndev->dev_addr[3] |= 0xF0;
2961 memcpy(pAdapter->macAddressCurrent.bytes, ndev->dev_addr,
2962 VOS_MAC_ADDR_SIZE);
Arif Hussain24bafea2013-11-15 15:10:03 -08002963 pr_info("wlan: Generated HotSpot BSSID " MAC_ADDRESS_STR"\n",
2964 MAC_ADDR_ARRAY(ndev->dev_addr));
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -07002965 }
2966
Jeff Johnson295189b2012-06-20 16:38:30 -07002967 hdd_set_ap_ops( pAdapter->dev );
2968
Kiet Lam10841362013-11-01 11:36:50 +05302969 /* This is for only SAP mode where users can
2970 * control country through ini.
2971 * P2P GO follows station country code
2972 * acquired during the STA scanning. */
2973 if((NL80211_IFTYPE_AP == type) &&
2974 (memcmp(pConfig->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0))
2975 {
2976 int status = 0;
2977 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_INFO,
2978 "%s: setting country code from INI ", __func__);
2979 init_completion(&pAdapter->change_country_code);
2980 status = (int)sme_ChangeCountryCode(pHddCtx->hHal,
2981 (void *)(tSmeChangeCountryCallback)
2982 wlan_hdd_change_country_code_cb,
2983 pConfig->apCntryCode, pAdapter,
2984 pHddCtx->pvosContext,
Abhishek Singha306a442013-11-07 18:39:01 +05302985 eSIR_FALSE,
2986 eSIR_TRUE);
Kiet Lam10841362013-11-01 11:36:50 +05302987 if (eHAL_STATUS_SUCCESS == status)
2988 {
2989 /* Wait for completion */
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302990 ret = wait_for_completion_interruptible_timeout(
Kiet Lam10841362013-11-01 11:36:50 +05302991 &pAdapter->change_country_code,
2992 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302993 if (ret <= 0)
Kiet Lam10841362013-11-01 11:36:50 +05302994 {
2995 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302996 FL("SME Timed out while setting country code %ld"),
2997 ret);
Yue Ma4f55ef32014-01-23 16:45:33 -08002998
2999 if (pHddCtx->isLogpInProgress)
3000 {
3001 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3002 "%s: LOGP in Progress. Ignore!!!", __func__);
3003 return -EAGAIN;
3004 }
Kiet Lam10841362013-11-01 11:36:50 +05303005 }
3006 }
3007 else
3008 {
3009 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08003010 "%s: SME Change Country code failed",__func__);
Kiet Lam10841362013-11-01 11:36:50 +05303011 return -EINVAL;
3012 }
3013 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003014 status = hdd_init_ap_mode(pAdapter);
3015 if(status != VOS_STATUS_SUCCESS)
3016 {
3017 hddLog(VOS_TRACE_LEVEL_FATAL,
3018 "%s: Error initializing the ap mode", __func__);
3019 return -EINVAL;
3020 }
3021 hdd_set_conparam(1);
3022
Jeff Johnson295189b2012-06-20 16:38:30 -07003023 /*interface type changed update in wiphy structure*/
3024 if(wdev)
3025 {
3026 wdev->iftype = type;
3027 pHddCtx->change_iface = type;
3028 }
3029 else
3030 {
3031 hddLog(VOS_TRACE_LEVEL_ERROR,
3032 "%s: ERROR !!!! Wireless dev is NULL", __func__);
3033 return -EINVAL;
3034 }
3035 goto done;
3036 }
3037
3038 default:
3039 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
3040 __func__);
3041 return -EOPNOTSUPP;
3042 }
3043 }
3044 else if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07003045 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07003046 )
3047 {
3048 switch(type)
3049 {
3050 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -07003051 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -07003052 case NL80211_IFTYPE_ADHOC:
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05303053#ifdef FEATURE_WLAN_TDLS
3054
3055 /* A Mutex Lock is introduced while changing the mode to
3056 * protect the concurrent access for the Adapters by TDLS
3057 * module.
3058 */
3059 if (mutex_lock_interruptible(&pHddCtx->tdls_lock))
3060 {
3061 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3062 "%s: unable to lock list", __func__);
3063 return -EINVAL;
3064 }
3065#endif
Jeff Johnson32d95a32012-09-10 13:15:23 -07003066 hdd_stop_adapter( pHddCtx, pAdapter );
3067 hdd_deinit_adapter( pHddCtx, pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07003068 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08003069 //Check for sub-string p2p to confirm its a p2p interface
3070 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala864d3552012-12-31 16:08:51 -08003071 {
3072 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
3073 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
3074 }
3075 else
3076 {
3077 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -07003078 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -08003079 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003080 hdd_set_conparam(0);
3081 pHddCtx->change_iface = type;
Jeff Johnson295189b2012-06-20 16:38:30 -07003082 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
3083 hdd_set_station_ops( pAdapter->dev );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05303084#ifdef FEATURE_WLAN_TDLS
3085 mutex_unlock(&pHddCtx->tdls_lock);
3086#endif
Sunil Dutt66485cb2013-12-19 19:05:03 +05303087 status = hdd_init_station_mode( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07003088 if( VOS_STATUS_SUCCESS != status )
3089 return -EOPNOTSUPP;
Jeff Johnsone7245742012-09-05 17:12:55 -07003090 /* In case of JB, for P2P-GO, only change interface will be called,
3091 * This is the right place to enable back bmps_imps()
3092 */
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05303093 if (pHddCtx->hdd_wlan_suspended)
3094 {
3095 hdd_set_pwrparams(pHddCtx);
3096 }
Jeff Johnsone7245742012-09-05 17:12:55 -07003097 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07003098 goto done;
3099 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -07003100 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07003101 wdev->iftype = type;
Jeff Johnson295189b2012-06-20 16:38:30 -07003102 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
3103 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Jeff Johnson295189b2012-06-20 16:38:30 -07003104 goto done;
3105 default:
3106 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
3107 __func__);
3108 return -EOPNOTSUPP;
3109
3110 }
3111
3112 }
3113 else
3114 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05303115 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: unsupported device mode(%d)",
3116 __func__, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07003117 return -EOPNOTSUPP;
3118 }
3119
3120
3121 if(pRoamProfile)
3122 {
3123 if ( LastBSSType != pRoamProfile->BSSType )
3124 {
3125 /*interface type changed update in wiphy structure*/
3126 wdev->iftype = type;
3127
3128 /*the BSS mode changed, We need to issue disconnect
3129 if connected or in IBSS disconnect state*/
3130 if ( hdd_connGetConnectedBssType(
3131 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), &connectedBssType ) ||
3132 ( eCSR_BSS_TYPE_START_IBSS == LastBSSType ) )
3133 {
3134 /*need to issue a disconnect to CSR.*/
3135 INIT_COMPLETION(pAdapter->disconnect_comp_var);
3136 if( eHAL_STATUS_SUCCESS ==
3137 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
3138 pAdapter->sessionId,
3139 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
3140 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05303141 ret = wait_for_completion_interruptible_timeout(
3142 &pAdapter->disconnect_comp_var,
3143 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
3144 if (ret <= 0)
3145 {
3146 hddLog(VOS_TRACE_LEVEL_ERROR,
3147 FL("wait on disconnect_comp_var failed %ld"), ret);
3148 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003149 }
3150 }
3151 }
3152 }
3153
3154done:
3155 /*set bitmask based on updated value*/
3156 wlan_hdd_set_concurrency_mode(pHddCtx, pAdapter->device_mode);
Leo Chang6fe1f922013-06-07 19:21:24 -07003157
3158 /* Only STA mode support TM now
3159 * all other mode, TM feature should be disabled */
3160 if ( (pHddCtx->cfg_ini->thermalMitigationEnable) &&
3161 (~VOS_STA & pHddCtx->concurrency_mode) )
3162 {
3163 hddDevTmLevelChangedHandler(pHddCtx->parent_dev, 0);
3164 }
3165
Jeff Johnson295189b2012-06-20 16:38:30 -07003166#ifdef WLAN_BTAMP_FEATURE
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303167 if((NL80211_IFTYPE_STATION == type) && (pHddCtx->concurrency_mode <= 1) &&
Jeff Johnson295189b2012-06-20 16:38:30 -07003168 (pHddCtx->no_of_sessions[WLAN_HDD_INFRA_STATION] <=1))
3169 {
3170 //we are ok to do AMP
3171 pHddCtx->isAmpAllowed = VOS_TRUE;
3172 }
3173#endif //WLAN_BTAMP_FEATURE
3174 EXIT();
3175 return 0;
3176}
3177
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003178#ifdef FEATURE_WLAN_TDLS
3179static int wlan_hdd_tdls_add_station(struct wiphy *wiphy,
3180 struct net_device *dev, u8 *mac, bool update, tCsrStaParams *StaParams)
3181{
3182 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3183 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3184 VOS_STATUS status;
Hoonki Lee5305c3a2013-04-29 23:28:59 -07003185 hddTdlsPeer_t *pTdlsPeer;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05303186 long ret;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003187
3188 ENTER();
3189
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05303190 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003191 {
3192 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3193 "Invalid arguments");
3194 return -EINVAL;
3195 }
Hoonki Lee27511902013-03-14 18:19:06 -07003196
3197 if ((eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode) ||
3198 (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode))
3199 {
3200 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
3201 "%s: TDLS mode is disabled OR not enabled in FW."
3202 MAC_ADDRESS_STR " Request declined.",
3203 __func__, MAC_ADDR_ARRAY(mac));
3204 return -ENOTSUPP;
3205 }
3206
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003207 if (pHddCtx->isLogpInProgress)
3208 {
3209 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3210 "%s:LOGP in Progress. Ignore!!!", __func__);
Gopichand Nakkala05922802013-03-14 12:23:19 -07003211 wlan_hdd_tdls_set_link_status(pAdapter, mac, eTDLS_LINK_IDLE);
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003212 return -EBUSY;
3213 }
3214
Naresh Jayaram9c6f4462014-02-13 12:20:31 +05303215 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, mac);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07003216
3217 if ( NULL == pTdlsPeer ) {
3218 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
3219 "%s: " MAC_ADDRESS_STR " (update %d) not exist. return invalid",
3220 __func__, MAC_ADDR_ARRAY(mac), update);
3221 return -EINVAL;
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07003222 }
Hoonki Lee5305c3a2013-04-29 23:28:59 -07003223
3224 /* in add station, we accept existing valid staId if there is */
3225 if ((0 == update) &&
3226 ((pTdlsPeer->link_status >= eTDLS_LINK_CONNECTING) ||
3227 (TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003228 {
Hoonki Lee5305c3a2013-04-29 23:28:59 -07003229 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003230 "%s: " MAC_ADDRESS_STR
Hoonki Lee5305c3a2013-04-29 23:28:59 -07003231 " link_status %d. staId %d. add station ignored.",
3232 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, pTdlsPeer->staId);
3233 return 0;
3234 }
3235 /* in change station, we accept only when staId is valid */
3236 if ((1 == update) &&
3237 ((pTdlsPeer->link_status > eTDLS_LINK_CONNECTING) ||
3238 (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
3239 {
3240 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
3241 "%s: " MAC_ADDRESS_STR
3242 " link status %d. staId %d. change station %s.",
3243 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, pTdlsPeer->staId,
3244 (TDLS_STA_INDEX_VALID(pTdlsPeer->staId)) ? "ignored" : "declined");
3245 return (TDLS_STA_INDEX_VALID(pTdlsPeer->staId)) ? 0 : -EPERM;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003246 }
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07003247
3248 /* when others are on-going, we want to change link_status to idle */
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05303249 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, mac, TRUE))
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003250 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07003251 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3252 "%s: " MAC_ADDRESS_STR
3253 " TDLS setup is ongoing. Request declined.",
3254 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala05922802013-03-14 12:23:19 -07003255 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003256 }
3257
3258 /* first to check if we reached to maximum supported TDLS peer.
3259 TODO: for now, return -EPERM looks working fine,
3260 but need to check if any other errno fit into this category.*/
3261 if (HDD_MAX_NUM_TDLS_STA <= wlan_hdd_tdlsConnectedPeers(pAdapter))
3262 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07003263 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3264 "%s: " MAC_ADDRESS_STR
3265 " TDLS Max peer already connected. Request declined.",
3266 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala05922802013-03-14 12:23:19 -07003267 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003268 }
3269 else
3270 {
3271 hddTdlsPeer_t *pTdlsPeer;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05303272 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, mac, TRUE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003273 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003274 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07003275 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3276 "%s: " MAC_ADDRESS_STR " already connected. Request declined.",
3277 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003278 return -EPERM;
3279 }
3280 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003281 if (0 == update)
3282 wlan_hdd_tdls_set_link_status(pAdapter, mac, eTDLS_LINK_CONNECTING);
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003283
Jeff Johnsond75fe012013-04-06 10:53:06 -07003284 /* debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05303285 if (NULL != StaParams)
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003286 {
3287 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
3288 "%s: TDLS Peer Parameters.", __func__);
Hoonki Lee66b75f32013-04-16 18:30:07 -07003289 if(StaParams->htcap_present)
3290 {
3291 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
3292 "ht_capa->cap_info: %0x", StaParams->HTCap.capInfo);
3293 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
3294 "ht_capa->extended_capabilities: %0x",
3295 StaParams->HTCap.extendedHtCapInfo);
3296 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003297 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
3298 "params->capability: %0x",StaParams->capability);
3299 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07003300 "params->ext_capab_len: %0x",StaParams->extn_capability[0]);
Hoonki Lee66b75f32013-04-16 18:30:07 -07003301 if(StaParams->vhtcap_present)
3302 {
3303 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
3304 "rxMcsMap %x rxHighest %x txMcsMap %x txHighest %x",
3305 StaParams->VHTCap.suppMcs.rxMcsMap, StaParams->VHTCap.suppMcs.rxHighest,
3306 StaParams->VHTCap.suppMcs.txMcsMap, StaParams->VHTCap.suppMcs.txHighest);
3307 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003308 {
3309 int i = 0;
Hoonki Lee5305c3a2013-04-29 23:28:59 -07003310 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "Supported rates:");
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003311 for (i = 0; i < sizeof(StaParams->supported_rates); i++)
3312 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
3313 "[%d]: %x ", i, StaParams->supported_rates[i]);
3314 }
Jeff Johnsond75fe012013-04-06 10:53:06 -07003315 } /* end debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05303316 else if ((1 == update) && (NULL == StaParams))
3317 {
3318 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3319 "%s : update is true, but staParams is NULL. Error!", __func__);
3320 return -EPERM;
3321 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003322
3323 INIT_COMPLETION(pAdapter->tdls_add_station_comp);
3324
3325 if (!update)
3326 {
3327 status = sme_AddTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
3328 pAdapter->sessionId, mac);
3329 }
3330 else
3331 {
3332 status = sme_ChangeTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
3333 pAdapter->sessionId, mac, StaParams);
3334 }
3335
c_hpothu6ff1c3c2013-10-01 19:01:57 +05303336 ret = wait_for_completion_interruptible_timeout(&pAdapter->tdls_add_station_comp,
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003337 msecs_to_jiffies(WAIT_TIME_TDLS_ADD_STA));
3338
c_hpothu6ff1c3c2013-10-01 19:01:57 +05303339 if (ret <= 0)
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003340 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07003341 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05303342 "%s: timeout waiting for tdls add station indication %ld",
3343 __func__, ret);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07003344 return -EPERM;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003345 }
c_hpothu6ff1c3c2013-10-01 19:01:57 +05303346
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003347 if ( eHAL_STATUS_SUCCESS != pAdapter->tdlsAddStaStatus)
3348 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07003349 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003350 "%s: Add Station is unsucessful", __func__);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07003351 return -EPERM;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003352 }
3353
3354 return 0;
Gopichand Nakkala05922802013-03-14 12:23:19 -07003355
3356error:
3357 wlan_hdd_tdls_set_link_status(pAdapter, mac, eTDLS_LINK_IDLE);
3358 return -EPERM;
3359
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003360}
3361#endif
3362
Jeff Johnson295189b2012-06-20 16:38:30 -07003363static int wlan_hdd_change_station(struct wiphy *wiphy,
3364 struct net_device *dev,
3365 u8 *mac,
3366 struct station_parameters *params)
3367{
3368 VOS_STATUS status = VOS_STATUS_SUCCESS;
3369 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Gopichand Nakkala29149562013-05-10 21:43:41 +05303370 hdd_context_t *pHddCtx;
3371 hdd_station_ctx_t *pHddStaCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07003372 v_MACADDR_t STAMacAddress;
Gopichand Nakkalab0856222013-03-12 22:39:05 -07003373#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003374 tCsrStaParams StaParams = {0};
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003375 tANI_U8 isBufSta = 0;
Naresh Jayaram3180aa42014-02-12 21:47:26 +05303376 tANI_U8 isOffChannelSupported = 0;
Gopichand Nakkalab0856222013-03-12 22:39:05 -07003377#endif
Jeff Johnsone7245742012-09-05 17:12:55 -07003378 ENTER();
3379
Gopichand Nakkala29149562013-05-10 21:43:41 +05303380 if ((NULL == pAdapter))
3381 {
3382 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
3383 "invalid adapter ");
3384 return -EINVAL;
3385 }
3386
3387 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
3388 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3389
3390 if ((NULL == pHddCtx) || (NULL == pHddStaCtx))
3391 {
3392 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
3393 "invalid HDD state or HDD station context");
3394 return -EINVAL;
3395 }
3396
3397 if (pHddCtx->isLogpInProgress)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07003398 {
3399 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3400 "%s:LOGP in Progress. Ignore!!!", __func__);
3401 return -EAGAIN;
3402 }
3403
Jeff Johnson295189b2012-06-20 16:38:30 -07003404 vos_mem_copy(STAMacAddress.bytes, mac, sizeof(v_MACADDR_t));
3405
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003406 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
3407 || (pAdapter->device_mode == WLAN_HDD_P2P_GO))
Jeff Johnson295189b2012-06-20 16:38:30 -07003408 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003409 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED))
Jeff Johnson295189b2012-06-20 16:38:30 -07003410 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303411 status = hdd_softap_change_STA_state( pAdapter, &STAMacAddress,
Jeff Johnson295189b2012-06-20 16:38:30 -07003412 WLANTL_STA_AUTHENTICATED);
3413
Gopichand Nakkala29149562013-05-10 21:43:41 +05303414 if (status != VOS_STATUS_SUCCESS)
3415 {
3416 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3417 "%s: Not able to change TL state to AUTHENTICATED", __func__);
3418 return -EINVAL;
3419 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003420 }
3421 }
Hoonki Leea6d49be2013-04-05 09:43:25 -07003422 else if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
3423 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)) {
Gopichand Nakkala29149562013-05-10 21:43:41 +05303424#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003425 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
3426 StaParams.capability = params->capability;
3427 StaParams.uapsd_queues = params->uapsd_queues;
3428 StaParams.max_sp = params->max_sp;
3429
Naresh Jayaram3180aa42014-02-12 21:47:26 +05303430 /* Convert (first channel , number of channels) tuple to
3431 * the total list of channels. This goes with the assumption
3432 * that if the first channel is < 14, then the next channels
3433 * are an incremental of 1 else an incremental of 4 till the number
3434 * of channels.
3435 */
3436 if (0 != params->supported_channels_len) {
3437 int i = 0,j = 0,k = 0, no_of_channels = 0 ;
3438 for ( i = 0 ; i < params->supported_channels_len ; i+=2)
3439 {
3440 int wifi_chan_index;
3441 StaParams.supported_channels[j] = params->supported_channels[i];
3442 wifi_chan_index =
3443 ((StaParams.supported_channels[j] <= HDD_CHANNEL_14 ) ? 1 : 4 );
3444 no_of_channels = params->supported_channels[i+1];
3445 for(k=1; k <= no_of_channels; k++)
3446 {
3447 StaParams.supported_channels[j+1] =
3448 StaParams.supported_channels[j] + wifi_chan_index;
3449 j+=1;
3450 }
3451 }
3452 StaParams.supported_channels_len = j;
3453 }
3454 vos_mem_copy(StaParams.supported_oper_classes,
3455 params->supported_oper_classes,
3456 params->supported_oper_classes_len);
3457 StaParams.supported_oper_classes_len =
3458 params->supported_oper_classes_len;
3459
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003460 if (0 != params->ext_capab_len)
3461 vos_mem_copy(StaParams.extn_capability, params->ext_capab,
3462 sizeof(StaParams.extn_capability));
3463
3464 if (NULL != params->ht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -07003465 {
3466 StaParams.htcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003467 vos_mem_copy(&StaParams.HTCap, params->ht_capa, sizeof(tSirHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -07003468 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003469
3470 StaParams.supported_rates_len = params->supported_rates_len;
3471
3472 /* Note : The Maximum sizeof supported_rates sent by the Supplicant is 32.
3473 * The supported_rates array , for all the structures propogating till Add Sta
3474 * to the firmware has to be modified , if the supplicant (ieee80211) is
3475 * modified to send more rates.
3476 */
3477
3478 /* To avoid Data Currption , set to max length to SIR_MAC_MAX_SUPP_RATES
3479 */
3480 if (StaParams.supported_rates_len > SIR_MAC_MAX_SUPP_RATES)
3481 StaParams.supported_rates_len = SIR_MAC_MAX_SUPP_RATES;
3482
3483 if (0 != StaParams.supported_rates_len) {
3484 int i = 0;
3485 vos_mem_copy(StaParams.supported_rates, params->supported_rates,
3486 StaParams.supported_rates_len);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07003487 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003488 "Supported Rates with Length %d", StaParams.supported_rates_len);
3489 for (i=0; i < StaParams.supported_rates_len; i++)
Hoonki Lee5305c3a2013-04-29 23:28:59 -07003490 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003491 "[%d]: %0x", i, StaParams.supported_rates[i]);
3492 }
3493
3494 if (NULL != params->vht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -07003495 {
3496 StaParams.vhtcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003497 vos_mem_copy(&StaParams.VHTCap, params->vht_capa, sizeof(tSirVHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -07003498 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003499
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003500 if (0 != params->ext_capab_len ) {
3501 /*Define A Macro : TODO Sunil*/
3502 if ((1<<4) & StaParams.extn_capability[3]) {
3503 isBufSta = 1;
3504 }
Naresh Jayaram3180aa42014-02-12 21:47:26 +05303505 /* TDLS Channel Switching Support */
3506 if ((1<<6) & StaParams.extn_capability[3]) {
3507 isOffChannelSupported = 1;
3508 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003509 }
Naresh Jayaram3180aa42014-02-12 21:47:26 +05303510 status = wlan_hdd_tdls_set_peer_caps( pAdapter, mac,
3511 &StaParams, isBufSta,
3512 isOffChannelSupported);
3513
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05303514 if (VOS_STATUS_SUCCESS != status) {
3515 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3516 "%s: wlan_hdd_tdls_set_peer_caps failed!", __func__);
3517 return -EINVAL;
3518 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003519 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 1, &StaParams);
3520
3521 if (VOS_STATUS_SUCCESS != status) {
3522 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3523 "%s: sme_ChangeTdlsPeerSta failed!", __func__);
3524 return -EINVAL;
3525 }
3526 }
Gopichand Nakkalab0856222013-03-12 22:39:05 -07003527#endif
Gopichand Nakkala6239acd2013-06-14 14:48:00 +05303528 }
Jeff Johnsone7245742012-09-05 17:12:55 -07003529 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07003530 return status;
3531}
3532
3533/*
Jeff Johnson295189b2012-06-20 16:38:30 -07003534 * FUNCTION: wlan_hdd_cfg80211_add_key
3535 * This function is used to initialize the key information
3536 */
3537#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003538static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07003539 struct net_device *ndev,
3540 u8 key_index, bool pairwise,
3541 const u8 *mac_addr,
3542 struct key_params *params
3543 )
3544#else
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003545static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07003546 struct net_device *ndev,
3547 u8 key_index, const u8 *mac_addr,
3548 struct key_params *params
3549 )
3550#endif
3551{
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003552 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -07003553 tCsrRoamSetKey setKey;
3554 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05303555 int status;
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003556 v_U32_t roamId= 0xFF;
3557 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07003558 hdd_hostapd_state_t *pHostapdState;
3559 VOS_STATUS vos_status;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07003560 eHalStatus halStatus;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05303561 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07003562
3563 ENTER();
3564
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05303565 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
3566 status = wlan_hdd_validate_context(pHddCtx);
3567
3568 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07003569 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05303570 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3571 "%s: HDD context is not valid", __func__);
3572 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07003573 }
3574
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003575 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
3576 __func__, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07003577
3578 if (CSR_MAX_NUM_KEY <= key_index)
3579 {
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003580 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07003581 key_index);
3582
3583 return -EINVAL;
3584 }
3585
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003586 if (CSR_MAX_KEY_LEN < params->key_len)
3587 {
3588 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key length %d", __func__,
3589 params->key_len);
3590
3591 return -EINVAL;
3592 }
3593
3594 hddLog(VOS_TRACE_LEVEL_INFO,
3595 "%s: called with key index = %d & key length %d",
3596 __func__, key_index, params->key_len);
Jeff Johnson295189b2012-06-20 16:38:30 -07003597
3598 /*extract key idx, key len and key*/
3599 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
3600 setKey.keyId = key_index;
3601 setKey.keyLength = params->key_len;
3602 vos_mem_copy(&setKey.Key[0],params->key, params->key_len);
3603
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003604 switch (params->cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -07003605 {
3606 case WLAN_CIPHER_SUITE_WEP40:
3607 setKey.encType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
3608 break;
3609
3610 case WLAN_CIPHER_SUITE_WEP104:
3611 setKey.encType = eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
3612 break;
3613
3614 case WLAN_CIPHER_SUITE_TKIP:
3615 {
3616 u8 *pKey = &setKey.Key[0];
3617 setKey.encType = eCSR_ENCRYPT_TYPE_TKIP;
3618
3619 vos_mem_zero(pKey, CSR_MAX_KEY_LEN);
3620
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003621 /*Supplicant sends the 32bytes key in this order
Jeff Johnson295189b2012-06-20 16:38:30 -07003622
3623 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003624 | Tk1 |TX-MIC | RX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -07003625 |--------------|----------|----------|
3626 <---16bytes---><--8bytes--><--8bytes-->
3627
3628 */
3629 /*Sme expects the 32 bytes key to be in the below order
3630
3631 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003632 | Tk1 |RX-MIC | TX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -07003633 |--------------|----------|----------|
3634 <---16bytes---><--8bytes--><--8bytes-->
3635 */
3636 /* Copy the Temporal Key 1 (TK1) */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003637 vos_mem_copy(pKey, params->key, 16);
Jeff Johnson295189b2012-06-20 16:38:30 -07003638
3639 /*Copy the rx mic first*/
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003640 vos_mem_copy(&pKey[16], &params->key[24], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -07003641
3642 /*Copy the tx mic */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003643 vos_mem_copy(&pKey[24], &params->key[16], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -07003644
3645
3646 break;
3647 }
3648
3649 case WLAN_CIPHER_SUITE_CCMP:
3650 setKey.encType = eCSR_ENCRYPT_TYPE_AES;
3651 break;
3652
3653#ifdef FEATURE_WLAN_WAPI
3654 case WLAN_CIPHER_SUITE_SMS4:
3655 {
3656 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
3657 wlan_hdd_cfg80211_set_key_wapi(pAdapter, key_index, mac_addr,
3658 params->key, params->key_len);
3659 return 0;
3660 }
3661#endif
Chet Lanctot186b5732013-03-18 10:26:30 -07003662
Jeff Johnson295189b2012-06-20 16:38:30 -07003663#ifdef FEATURE_WLAN_CCX
3664 case WLAN_CIPHER_SUITE_KRK:
3665 setKey.encType = eCSR_ENCRYPT_TYPE_KRK;
3666 break;
3667#endif
Chet Lanctot186b5732013-03-18 10:26:30 -07003668
3669#ifdef WLAN_FEATURE_11W
3670 case WLAN_CIPHER_SUITE_AES_CMAC:
3671 setKey.encType = eCSR_ENCRYPT_TYPE_AES_CMAC;
Chet Lanctot3b5158a2013-03-31 16:45:21 -07003672 break;
Chet Lanctot186b5732013-03-18 10:26:30 -07003673#endif
3674
Jeff Johnson295189b2012-06-20 16:38:30 -07003675 default:
Jeff Johnson0299d0a2013-10-30 12:37:43 -07003676 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unsupported cipher type %u",
Jeff Johnson295189b2012-06-20 16:38:30 -07003677 __func__, params->cipher);
3678 return -EOPNOTSUPP;
3679 }
3680
3681 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: encryption type %d",
3682 __func__, setKey.encType);
3683
Shailender Karmuchi642e9812013-05-30 14:34:49 -07003684 if (
Jeff Johnson295189b2012-06-20 16:38:30 -07003685#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
3686 (!pairwise)
3687#else
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003688 (!mac_addr || is_broadcast_ether_addr(mac_addr))
Jeff Johnson295189b2012-06-20 16:38:30 -07003689#endif
Shailender Karmuchi642e9812013-05-30 14:34:49 -07003690 )
3691 {
3692 /* set group key*/
3693 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3694 "%s- %d: setting Broadcast key",
3695 __func__, __LINE__);
3696 setKey.keyDirection = eSIR_RX_ONLY;
3697 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
3698 }
3699 else
3700 {
3701 /* set pairwise key*/
3702 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3703 "%s- %d: setting pairwise key",
3704 __func__, __LINE__);
3705 setKey.keyDirection = eSIR_TX_RX;
3706 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
3707 }
3708 if ((WLAN_HDD_IBSS == pAdapter->device_mode) && !pairwise)
3709 {
3710 setKey.keyDirection = eSIR_TX_RX;
3711 /*Set the group key*/
3712 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
3713 pAdapter->sessionId, &setKey, &roamId );
Jeff Johnson295189b2012-06-20 16:38:30 -07003714
Shailender Karmuchi642e9812013-05-30 14:34:49 -07003715 if ( 0 != status )
3716 {
3717 hddLog(VOS_TRACE_LEVEL_ERROR,
3718 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
3719 return -EINVAL;
3720 }
3721 /*Save the keys here and call sme_RoamSetKey for setting
3722 the PTK after peer joins the IBSS network*/
3723 vos_mem_copy(&pAdapter->sessionCtx.station.ibss_enc_key,
3724 &setKey, sizeof(tCsrRoamSetKey));
3725 return status;
3726 }
Gopichand Nakkala29149562013-05-10 21:43:41 +05303727 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP) ||
3728 (pAdapter->device_mode == WLAN_HDD_P2P_GO))
3729 {
Jeff Johnson295189b2012-06-20 16:38:30 -07003730 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003731 if( pHostapdState->bssState == BSS_START )
3732 {
c_hpothu7c55da62014-01-23 18:34:02 +05303733 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3734 vos_status = wlan_hdd_check_ula_done(pAdapter);
3735
3736 if ( vos_status != VOS_STATUS_SUCCESS )
3737 {
3738 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3739 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
3740 __LINE__, vos_status );
3741
3742 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
3743
3744 return -EINVAL;
3745 }
3746
Jeff Johnson295189b2012-06-20 16:38:30 -07003747 status = WLANSAP_SetKeySta( pVosContext, &setKey);
3748
3749 if ( status != eHAL_STATUS_SUCCESS )
3750 {
3751 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3752 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
3753 __LINE__, status );
3754 }
3755 }
3756
3757 /* Saving WEP keys */
3758 else if( eCSR_ENCRYPT_TYPE_WEP40_STATICKEY == setKey.encType ||
3759 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY == setKey.encType )
3760 {
3761 //Save the wep key in ap context. Issue setkey after the BSS is started.
3762 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
3763 vos_mem_copy(&pAPCtx->wepKey[key_index], &setKey, sizeof(tCsrRoamSetKey));
3764 }
3765 else
3766 {
3767 //Save the key in ap context. Issue setkey after the BSS is started.
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003768 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07003769 vos_mem_copy(&pAPCtx->groupKey, &setKey, sizeof(tCsrRoamSetKey));
3770 }
3771 }
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003772 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION) ||
3773 (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT) )
Jeff Johnson295189b2012-06-20 16:38:30 -07003774 {
3775 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
3776 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3777
Gopichand Nakkala3d295922013-05-07 16:19:14 +05303778#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
3779 if (!pairwise)
3780#else
3781 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
3782#endif
3783 {
3784 /* set group key*/
3785 if (pHddStaCtx->roam_info.deferKeyComplete)
3786 {
3787 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3788 "%s- %d: Perform Set key Complete",
3789 __func__, __LINE__);
3790 hdd_PerformRoamSetKeyComplete(pAdapter);
3791 }
3792 }
3793
Jeff Johnson295189b2012-06-20 16:38:30 -07003794 pWextState->roamProfile.Keys.KeyLength[key_index] = (u8)params->key_len;
3795
Venkata Prathyusha Kuntupalliee2ce712013-01-17 14:09:24 -08003796 pWextState->roamProfile.Keys.defaultIndex = key_index;
3797
3798
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003799 vos_mem_copy(&pWextState->roamProfile.Keys.KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -07003800 params->key, params->key_len);
3801
Gopichand Nakkala3d295922013-05-07 16:19:14 +05303802
Jeff Johnson295189b2012-06-20 16:38:30 -07003803 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
3804
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303805 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -07003806 "%s: set key for peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303807 __func__, setKey.peerMac[0], setKey.peerMac[1],
3808 setKey.peerMac[2], setKey.peerMac[3],
3809 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -07003810 setKey.keyDirection);
3811
3812 vos_status = wlan_hdd_check_ula_done(pAdapter);
3813
3814 if ( vos_status != VOS_STATUS_SUCCESS )
3815 {
3816 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3817 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
3818 __LINE__, vos_status );
3819
3820 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
3821
3822 return -EINVAL;
3823
3824 }
3825
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07003826#ifdef WLAN_FEATURE_VOWIFI_11R
Gopichand Nakkala3d295922013-05-07 16:19:14 +05303827 /* The supplicant may attempt to set the PTK once pre-authentication
3828 is done. Save the key in the UMAC and include it in the ADD BSS
3829 request */
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07003830 halStatus = sme_FTUpdateKey( WLAN_HDD_GET_HAL_CTX(pAdapter), &setKey);
Gopichand Nakkala3d295922013-05-07 16:19:14 +05303831 if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_SUCCESS )
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07003832 {
Gopichand Nakkala3d295922013-05-07 16:19:14 +05303833 hddLog(VOS_TRACE_LEVEL_INFO_MED,
3834 "%s: Update PreAuth Key success", __func__);
3835 return 0;
3836 }
3837 else if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_FAILED )
3838 {
3839 hddLog(VOS_TRACE_LEVEL_ERROR,
3840 "%s: Update PreAuth Key failed", __func__);
Gopichand Nakkalad7d13652013-02-15 01:48:00 +05303841 return -EINVAL;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07003842 }
3843#endif /* WLAN_FEATURE_VOWIFI_11R */
Jeff Johnson295189b2012-06-20 16:38:30 -07003844
3845 /* issue set key request to SME*/
3846 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
3847 pAdapter->sessionId, &setKey, &roamId );
3848
3849 if ( 0 != status )
3850 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303851 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07003852 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
3853 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
3854 return -EINVAL;
3855 }
3856
3857
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303858 /* in case of IBSS as there was no information available about WEP keys during
3859 * IBSS join, group key intialized with NULL key, so re-initialize group key
Jeff Johnson295189b2012-06-20 16:38:30 -07003860 * with correct value*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303861 if ( (eCSR_BSS_TYPE_START_IBSS == pWextState->roamProfile.BSSType) &&
3862 !( ( IW_AUTH_KEY_MGMT_802_1X
3863 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X))
Jeff Johnson295189b2012-06-20 16:38:30 -07003864 && (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType)
3865 )
3866 &&
3867 ( (WLAN_CIPHER_SUITE_WEP40 == params->cipher)
3868 || (WLAN_CIPHER_SUITE_WEP104 == params->cipher)
3869 )
3870 )
3871 {
3872 setKey.keyDirection = eSIR_RX_ONLY;
3873 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
3874
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303875 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -07003876 "%s: set key peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303877 __func__, setKey.peerMac[0], setKey.peerMac[1],
3878 setKey.peerMac[2], setKey.peerMac[3],
3879 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -07003880 setKey.keyDirection);
3881
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303882 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07003883 pAdapter->sessionId, &setKey, &roamId );
3884
3885 if ( 0 != status )
3886 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303887 hddLog(VOS_TRACE_LEVEL_ERROR,
3888 "%s: sme_RoamSetKey failed for group key (IBSS), returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07003889 __func__, status);
3890 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
3891 return -EINVAL;
3892 }
3893 }
3894 }
3895
3896 return 0;
3897}
3898
3899/*
3900 * FUNCTION: wlan_hdd_cfg80211_get_key
3901 * This function is used to get the key information
3902 */
3903#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303904static int wlan_hdd_cfg80211_get_key(
3905 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07003906 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303907 u8 key_index, bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -07003908 const u8 *mac_addr, void *cookie,
3909 void (*callback)(void *cookie, struct key_params*)
3910 )
3911#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303912static int wlan_hdd_cfg80211_get_key(
3913 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07003914 struct net_device *ndev,
3915 u8 key_index, const u8 *mac_addr, void *cookie,
3916 void (*callback)(void *cookie, struct key_params*)
3917 )
3918#endif
3919{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303920 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -07003921 hdd_wext_state_t *pWextState= WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
3922 tCsrRoamProfile *pRoamProfile = &(pWextState->roamProfile);
3923 struct key_params params;
3924
3925 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303926
Arif Hussain6d2a3322013-11-17 19:50:10 -08003927 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07003928 __func__,pAdapter->device_mode);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303929
Jeff Johnson295189b2012-06-20 16:38:30 -07003930 memset(&params, 0, sizeof(params));
3931
3932 if (CSR_MAX_NUM_KEY <= key_index)
3933 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05303934 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid key index %d"), key_index);
Jeff Johnson295189b2012-06-20 16:38:30 -07003935 return -EINVAL;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303936 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003937
3938 switch(pRoamProfile->EncryptionType.encryptionType[0])
3939 {
3940 case eCSR_ENCRYPT_TYPE_NONE:
3941 params.cipher = IW_AUTH_CIPHER_NONE;
3942 break;
3943
3944 case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY:
3945 case eCSR_ENCRYPT_TYPE_WEP40:
3946 params.cipher = WLAN_CIPHER_SUITE_WEP40;
3947 break;
3948
3949 case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY:
3950 case eCSR_ENCRYPT_TYPE_WEP104:
3951 params.cipher = WLAN_CIPHER_SUITE_WEP104;
3952 break;
3953
3954 case eCSR_ENCRYPT_TYPE_TKIP:
3955 params.cipher = WLAN_CIPHER_SUITE_TKIP;
3956 break;
3957
3958 case eCSR_ENCRYPT_TYPE_AES:
3959 params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
3960 break;
3961
3962 default:
3963 params.cipher = IW_AUTH_CIPHER_NONE;
3964 break;
3965 }
3966
3967 params.key_len = pRoamProfile->Keys.KeyLength[key_index];
3968 params.seq_len = 0;
3969 params.seq = NULL;
3970 params.key = &pRoamProfile->Keys.KeyMaterial[key_index][0];
3971 callback(cookie, &params);
3972 return 0;
3973}
3974
3975/*
3976 * FUNCTION: wlan_hdd_cfg80211_del_key
3977 * This function is used to delete the key information
3978 */
3979#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303980static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07003981 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303982 u8 key_index,
3983 bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -07003984 const u8 *mac_addr
3985 )
3986#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303987static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07003988 struct net_device *ndev,
3989 u8 key_index,
3990 const u8 *mac_addr
3991 )
3992#endif
3993{
3994 int status = 0;
3995
3996 //This code needs to be revisited. There is sme_removeKey API, we should
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303997 //plan to use that. After the change to use correct index in setkey,
Jeff Johnson295189b2012-06-20 16:38:30 -07003998 //it is observed that this is invalidating peer
3999 //key index whenever re-key is done. This is affecting data link.
4000 //It should be ok to ignore del_key.
4001#if 0
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304002 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
4003 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07004004 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
4005 tCsrRoamSetKey setKey;
4006 v_U32_t roamId= 0xFF;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304007
Jeff Johnson295189b2012-06-20 16:38:30 -07004008 ENTER();
4009
4010 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device_mode = %d\n",
4011 __func__,pAdapter->device_mode);
4012
4013 if (CSR_MAX_NUM_KEY <= key_index)
4014 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304015 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07004016 key_index);
4017
4018 return -EINVAL;
4019 }
4020
4021 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
4022 setKey.keyId = key_index;
4023
4024 if (mac_addr)
4025 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
4026 else
4027 vos_mem_copy(setKey.peerMac, groupmacaddr, WNI_CFG_BSSID_LEN);
4028
4029 setKey.encType = eCSR_ENCRYPT_TYPE_NONE;
4030
4031 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07004032 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304033 )
4034 {
4035
4036 hdd_hostapd_state_t *pHostapdState =
Jeff Johnson295189b2012-06-20 16:38:30 -07004037 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
4038 if( pHostapdState->bssState == BSS_START)
4039 {
4040 status = WLANSAP_SetKeySta( pVosContext, &setKey);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304041
Jeff Johnson295189b2012-06-20 16:38:30 -07004042 if ( status != eHAL_STATUS_SUCCESS )
4043 {
4044 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4045 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
4046 __LINE__, status );
4047 }
4048 }
4049 }
4050 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304051 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnson295189b2012-06-20 16:38:30 -07004052 )
4053 {
4054 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4055
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304056 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
4057
4058 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -07004059 "%s: delete key for peerMac %2x:%2x:%2x:%2x:%2x:%2x",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304060 __func__, setKey.peerMac[0], setKey.peerMac[1],
4061 setKey.peerMac[2], setKey.peerMac[3],
Jeff Johnson295189b2012-06-20 16:38:30 -07004062 setKey.peerMac[4], setKey.peerMac[5]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304063 if(pAdapter->sessionCtx.station.conn_info.connState ==
4064 eConnectionState_Associated)
Jeff Johnson295189b2012-06-20 16:38:30 -07004065 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304066 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07004067 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304068
Jeff Johnson295189b2012-06-20 16:38:30 -07004069 if ( 0 != status )
4070 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304071 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07004072 "%s: sme_RoamSetKey failure, returned %d",
4073 __func__, status);
4074 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
4075 return -EINVAL;
4076 }
4077 }
4078 }
4079#endif
Jeff Johnsone7245742012-09-05 17:12:55 -07004080 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07004081 return status;
4082}
4083
4084/*
4085 * FUNCTION: wlan_hdd_cfg80211_set_default_key
4086 * This function is used to set the default tx key index
4087 */
4088#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
4089static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
4090 struct net_device *ndev,
4091 u8 key_index,
4092 bool unicast, bool multicast)
4093#else
4094static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
4095 struct net_device *ndev,
4096 u8 key_index)
4097#endif
4098{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304099 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05304100 int status;
Gopichand Nakkala29149562013-05-10 21:43:41 +05304101 hdd_wext_state_t *pWextState;
4102 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05304103 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07004104
4105 ENTER();
4106
Gopichand Nakkala29149562013-05-10 21:43:41 +05304107 if ((NULL == pAdapter))
4108 {
4109 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
4110 "invalid adapter");
4111 return -EINVAL;
4112 }
4113
4114 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
4115 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4116
4117 if ((NULL == pWextState) || (NULL == pHddStaCtx))
4118 {
4119 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
4120 "invalid Wext state or HDD context");
4121 return -EINVAL;
4122 }
4123
Arif Hussain6d2a3322013-11-17 19:50:10 -08004124 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d key_index = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07004125 __func__,pAdapter->device_mode, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304126
Jeff Johnson295189b2012-06-20 16:38:30 -07004127 if (CSR_MAX_NUM_KEY <= key_index)
4128 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304129 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07004130 key_index);
4131
4132 return -EINVAL;
4133 }
4134
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05304135 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
4136 status = wlan_hdd_validate_context(pHddCtx);
4137
4138 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004139 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05304140 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4141 "%s: HDD context is not valid", __func__);
4142 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004143 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304144
Jeff Johnson295189b2012-06-20 16:38:30 -07004145 if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -07004146 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304147 )
Jeff Johnson295189b2012-06-20 16:38:30 -07004148 {
Gopichand Nakkala29149562013-05-10 21:43:41 +05304149 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
Arif Hussain6943f522013-11-04 20:10:10 -08004150 pHddStaCtx->conn_info.ucEncryptionType) &&
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304151 (eCSR_ENCRYPT_TYPE_AES !=
Arif Hussain6943f522013-11-04 20:10:10 -08004152 pHddStaCtx->conn_info.ucEncryptionType)
Jeff Johnson295189b2012-06-20 16:38:30 -07004153 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304154 {
4155 /* if default key index is not same as previous one,
Jeff Johnson295189b2012-06-20 16:38:30 -07004156 * then update the default key index */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304157
Jeff Johnson295189b2012-06-20 16:38:30 -07004158 tCsrRoamSetKey setKey;
4159 v_U32_t roamId= 0xFF;
4160 tCsrKeys *Keys = &pWextState->roamProfile.Keys;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304161
4162 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: default tx key index %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07004163 __func__, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304164
Jeff Johnson295189b2012-06-20 16:38:30 -07004165 Keys->defaultIndex = (u8)key_index;
4166 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
4167 setKey.keyId = key_index;
4168 setKey.keyLength = Keys->KeyLength[key_index];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304169
4170 vos_mem_copy(&setKey.Key[0],
4171 &Keys->KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -07004172 Keys->KeyLength[key_index]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304173
Gopichand Nakkala29149562013-05-10 21:43:41 +05304174 setKey.keyDirection = eSIR_TX_RX;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304175
4176 vos_mem_copy(setKey.peerMac,
Jeff Johnson295189b2012-06-20 16:38:30 -07004177 &pHddStaCtx->conn_info.bssId[0],
4178 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304179
Gopichand Nakkala29149562013-05-10 21:43:41 +05304180 if (Keys->KeyLength[key_index] == CSR_WEP40_KEY_LEN &&
4181 pWextState->roamProfile.EncryptionType.encryptionType[0] ==
4182 eCSR_ENCRYPT_TYPE_WEP104)
4183 {
4184 /*In the case of dynamic wep supplicant hardcodes DWEP type to eCSR_ENCRYPT_TYPE_WEP104
4185 even though ap is configured for WEP-40 encryption. In this canse the key length
4186 is 5 but the encryption type is 104 hence checking the key langht(5) and encryption
4187 type(104) and switching encryption type to 40*/
4188 pWextState->roamProfile.EncryptionType.encryptionType[0] =
4189 eCSR_ENCRYPT_TYPE_WEP40;
4190 pWextState->roamProfile.mcEncryptionType.encryptionType[0] =
4191 eCSR_ENCRYPT_TYPE_WEP40;
4192 }
4193
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304194 setKey.encType =
Jeff Johnson295189b2012-06-20 16:38:30 -07004195 pWextState->roamProfile.EncryptionType.encryptionType[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304196
Jeff Johnson295189b2012-06-20 16:38:30 -07004197 /* issue set key request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304198 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07004199 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304200
Jeff Johnson295189b2012-06-20 16:38:30 -07004201 if ( 0 != status )
4202 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304203 hddLog(VOS_TRACE_LEVEL_ERROR,
4204 "%s: sme_RoamSetKey failed, returned %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07004205 status);
4206 return -EINVAL;
4207 }
4208 }
4209 }
4210
4211 /* In SoftAp mode setting key direction for default mode */
4212 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
4213 {
4214 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
4215 pWextState->roamProfile.EncryptionType.encryptionType[0]) &&
4216 (eCSR_ENCRYPT_TYPE_AES !=
4217 pWextState->roamProfile.EncryptionType.encryptionType[0])
4218 )
4219 {
4220 /* Saving key direction for default key index to TX default */
4221 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
4222 pAPCtx->wepKey[key_index].keyDirection = eSIR_TX_DEFAULT;
4223 }
4224 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304225
Jeff Johnson295189b2012-06-20 16:38:30 -07004226 return status;
4227}
4228
Jeff Johnson295189b2012-06-20 16:38:30 -07004229/*
4230 * FUNCTION: wlan_hdd_cfg80211_inform_bss
4231 * This function is used to inform the BSS details to nl80211 interface.
4232 */
4233static struct cfg80211_bss* wlan_hdd_cfg80211_inform_bss(
4234 hdd_adapter_t *pAdapter, tCsrRoamConnectedProfile *roamProfile)
4235{
4236 struct net_device *dev = pAdapter->dev;
4237 struct wireless_dev *wdev = dev->ieee80211_ptr;
4238 struct wiphy *wiphy = wdev->wiphy;
4239 tSirBssDescription *pBssDesc = roamProfile->pBssDesc;
4240 int chan_no;
4241 int ie_length;
4242 const char *ie;
4243 unsigned int freq;
4244 struct ieee80211_channel *chan;
4245 int rssi = 0;
4246 struct cfg80211_bss *bss = NULL;
4247
4248 ENTER();
4249
4250 if( NULL == pBssDesc )
4251 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08004252 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pBssDesc is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004253 return bss;
4254 }
4255
4256 chan_no = pBssDesc->channelId;
4257 ie_length = GET_IE_LEN_IN_BSS_DESC( pBssDesc->length );
4258 ie = ((ie_length != 0) ? (const char *)&pBssDesc->ieFields: NULL);
4259
4260 if( NULL == ie )
4261 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08004262 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: IE of BSS descriptor is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004263 return bss;
4264 }
4265
4266#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
4267 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
4268 {
4269 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
4270 }
4271 else
4272 {
4273 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
4274 }
4275#else
4276 freq = ieee80211_channel_to_frequency(chan_no);
4277#endif
4278
4279 chan = __ieee80211_get_channel(wiphy, freq);
4280
4281 bss = cfg80211_get_bss(wiphy, chan, pBssDesc->bssId,
4282 &roamProfile->SSID.ssId[0], roamProfile->SSID.length,
4283 WLAN_CAPABILITY_ESS, WLAN_CAPABILITY_ESS);
4284 if (bss == NULL)
4285 {
4286 rssi = (VOS_MIN ((pBssDesc->rssi + pBssDesc->sinr), 0))*100;
4287
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304288 return (cfg80211_inform_bss(wiphy, chan, pBssDesc->bssId,
4289 le64_to_cpu(*(__le64 *)pBssDesc->timeStamp),
Jeff Johnson295189b2012-06-20 16:38:30 -07004290 pBssDesc->capabilityInfo,
4291 pBssDesc->beaconInterval, ie, ie_length,
4292 rssi, GFP_KERNEL ));
4293}
4294 else
4295 {
4296 return bss;
4297 }
4298}
4299
4300
4301
4302/*
4303 * FUNCTION: wlan_hdd_cfg80211_inform_bss_frame
4304 * This function is used to inform the BSS details to nl80211 interface.
4305 */
4306struct cfg80211_bss*
4307wlan_hdd_cfg80211_inform_bss_frame( hdd_adapter_t *pAdapter,
4308 tSirBssDescription *bss_desc
4309 )
4310{
4311 /*
4312 cfg80211_inform_bss() is not updating ie field of bss entry, if entry
4313 already exists in bss data base of cfg80211 for that particular BSS ID.
4314 Using cfg80211_inform_bss_frame to update the bss entry instead of
4315 cfg80211_inform_bss, But this call expects mgmt packet as input. As of
4316 now there is no possibility to get the mgmt(probe response) frame from PE,
4317 converting bss_desc to ieee80211_mgmt(probe response) and passing to
4318 cfg80211_inform_bss_frame.
4319 */
4320 struct net_device *dev = pAdapter->dev;
4321 struct wireless_dev *wdev = dev->ieee80211_ptr;
4322 struct wiphy *wiphy = wdev->wiphy;
4323 int chan_no = bss_desc->channelId;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08004324#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
4325 qcom_ie_age *qie_age = NULL;
4326 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length ) + sizeof(qcom_ie_age);
4327#else
Jeff Johnson295189b2012-06-20 16:38:30 -07004328 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length );
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08004329#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07004330 const char *ie =
4331 ((ie_length != 0) ? (const char *)&bss_desc->ieFields: NULL);
4332 unsigned int freq;
4333 struct ieee80211_channel *chan;
Abhishek Singh1e2bfa32014-01-02 15:44:15 +05304334 struct ieee80211_mgmt *mgmt = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07004335 struct cfg80211_bss *bss_status = NULL;
4336 size_t frame_len = sizeof (struct ieee80211_mgmt) + ie_length;
4337 int rssi = 0;
Wilson Yangf80a0542013-10-07 13:02:37 -07004338 hdd_context_t *pHddCtx;
4339 int status;
Jeff Johnsone7245742012-09-05 17:12:55 -07004340#ifdef WLAN_OPEN_SOURCE
4341 struct timespec ts;
4342#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07004343
Wilson Yangf80a0542013-10-07 13:02:37 -07004344 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
4345 status = wlan_hdd_validate_context(pHddCtx);
4346
4347 /*bss_update is not allowed during wlan driver loading or unloading*/
4348 if (pHddCtx->isLoadUnloadInProgress)
4349 {
4350 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4351 "%s:Loading_unloading in Progress. Ignore!!!",__func__);
4352 return NULL;
4353 }
4354
4355
4356 if (0 != status)
4357 {
4358 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4359 "%s: HDD context is not valid", __func__);
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -07004360 return NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -07004361 }
4362
Abhishek Singh1e2bfa32014-01-02 15:44:15 +05304363 mgmt = kzalloc((sizeof (struct ieee80211_mgmt) + ie_length), GFP_KERNEL);
Wilson Yangf80a0542013-10-07 13:02:37 -07004364 if (!mgmt)
4365 {
4366 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4367 "%s: memory allocation failed ", __func__);
4368 return NULL;
4369 }
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -07004370
Jeff Johnson295189b2012-06-20 16:38:30 -07004371 memcpy(mgmt->bssid, bss_desc->bssId, ETH_ALEN);
Jeff Johnsone7245742012-09-05 17:12:55 -07004372
4373#ifdef WLAN_OPEN_SOURCE
4374 /* Android does not want the timestamp from the frame.
4375 Instead it wants a monotonic increasing value */
4376 get_monotonic_boottime(&ts);
4377 mgmt->u.probe_resp.timestamp =
4378 ((u64)ts.tv_sec * 1000000) + (ts.tv_nsec / 1000);
4379#else
4380 /* keep old behavior for non-open source (for now) */
Jeff Johnson295189b2012-06-20 16:38:30 -07004381 memcpy(&mgmt->u.probe_resp.timestamp, bss_desc->timeStamp,
4382 sizeof (bss_desc->timeStamp));
Jeff Johnsone7245742012-09-05 17:12:55 -07004383
4384#endif
4385
Jeff Johnson295189b2012-06-20 16:38:30 -07004386 mgmt->u.probe_resp.beacon_int = bss_desc->beaconInterval;
4387 mgmt->u.probe_resp.capab_info = bss_desc->capabilityInfo;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08004388
4389#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
4390 /* GPS Requirement: need age ie per entry. Using vendor specific. */
4391 /* Assuming this is the last IE, copy at the end */
4392 ie_length -=sizeof(qcom_ie_age);
4393 qie_age = (qcom_ie_age *)(mgmt->u.probe_resp.variable + ie_length);
4394 qie_age->element_id = QCOM_VENDOR_IE_ID;
4395 qie_age->len = QCOM_VENDOR_IE_AGE_LEN;
4396 qie_age->oui_1 = QCOM_OUI1;
4397 qie_age->oui_2 = QCOM_OUI2;
4398 qie_age->oui_3 = QCOM_OUI3;
4399 qie_age->type = QCOM_VENDOR_IE_AGE_TYPE;
4400 qie_age->age = vos_timer_get_system_ticks() - bss_desc->nReceivedTime;
4401#endif
4402
Jeff Johnson295189b2012-06-20 16:38:30 -07004403 memcpy(mgmt->u.probe_resp.variable, ie, ie_length);
Gopichand Nakkalad908ec82013-05-16 19:32:19 +05304404 if (bss_desc->fProbeRsp)
4405 {
4406 mgmt->frame_control |=
4407 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_RESP);
4408 }
4409 else
4410 {
4411 mgmt->frame_control |=
4412 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_BEACON);
4413 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004414
4415#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304416 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ) &&
Jeff Johnson295189b2012-06-20 16:38:30 -07004417 (wiphy->bands[IEEE80211_BAND_2GHZ] != NULL))
4418 {
4419 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
4420 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304421 else if ((chan_no > ARRAY_SIZE(hdd_channels_2_4_GHZ)) &&
Jeff Johnson295189b2012-06-20 16:38:30 -07004422 (wiphy->bands[IEEE80211_BAND_5GHZ] != NULL))
4423
4424 {
4425 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
4426 }
4427 else
4428 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05304429 hddLog(VOS_TRACE_LEVEL_ERROR, "%s Invalid chan_no:%d",
4430 __func__, chan_no);
Jeff Johnson295189b2012-06-20 16:38:30 -07004431 kfree(mgmt);
4432 return NULL;
4433 }
4434#else
4435 freq = ieee80211_channel_to_frequency(chan_no);
4436#endif
4437 chan = __ieee80211_get_channel(wiphy, freq);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -08004438 /*when the band is changed on the fly using the GUI, three things are done
4439 * 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)
4440 * as part of the scan abort, message willbe queued to PE and we proceed with flushing and changinh the band.
4441 * pe will stop the scanning further and report back the results what ever it had till now by calling the call back function.
4442 * if the time between update band and scandone call back is sufficent enough the band change reflects in SME, SME validates the channels
4443 * and discards the channels correponding to previous band and calls back with zero bss results.
4444 * 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
4445 * all the channels correponding to previous band.this is due to race condition.but those channels are invalid to the new band and so
4446 * this function __ieee80211_get_channel will return NULL.Each time we report scan result with this pointer null warning kernel trace is printed.
4447 * if the scan results contain large number of APs continuosly kernel warning trace is printed and it will lead to apps watch dog bark.
4448 * So drop the bss and continue to next bss.
4449 */
4450 if(chan == NULL)
4451 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05304452 hddLog(VOS_TRACE_LEVEL_ERROR, "%s chan pointer is NULL", __func__);
Chilam Ngc4244af2013-04-01 15:37:32 -07004453 kfree(mgmt);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -08004454 return NULL;
4455 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004456 /*To keep the rssi icon of the connected AP in the scan window
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304457 *and the rssi icon of the wireless networks in sync
Jeff Johnson295189b2012-06-20 16:38:30 -07004458 * */
4459 if (( eConnectionState_Associated ==
4460 pAdapter->sessionCtx.station.conn_info.connState ) &&
4461 ( VOS_TRUE == vos_mem_compare(bss_desc->bssId,
4462 pAdapter->sessionCtx.station.conn_info.bssId,
4463 WNI_CFG_BSSID_LEN)))
4464 {
4465 /* supplicant takes the signal strength in terms of mBm(100*dBm) */
4466 rssi = (pAdapter->rssi * 100);
4467 }
4468 else
4469 {
4470 rssi = (VOS_MIN ((bss_desc->rssi + bss_desc->sinr), 0))*100;
4471 }
4472
Nirav Shah20ac06f2013-12-12 18:14:06 +05304473 hddLog(VOS_TRACE_LEVEL_INFO, "%s: BSSID:" MAC_ADDRESS_STR " Channel:%d"
4474 "RSSI:%d", __func__, MAC_ADDR_ARRAY(mgmt->bssid),
4475 chan->center_freq, (int)(rssi/100));
4476
Jeff Johnson295189b2012-06-20 16:38:30 -07004477 bss_status = cfg80211_inform_bss_frame(wiphy, chan, mgmt,
4478 frame_len, rssi, GFP_KERNEL);
4479 kfree(mgmt);
4480 return bss_status;
4481}
4482
4483/*
4484 * FUNCTION: wlan_hdd_cfg80211_update_bss_db
4485 * This function is used to update the BSS data base of CFG8011
4486 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304487struct cfg80211_bss* wlan_hdd_cfg80211_update_bss_db( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07004488 tCsrRoamInfo *pRoamInfo
4489 )
4490{
4491 tCsrRoamConnectedProfile roamProfile;
4492 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
4493 struct cfg80211_bss *bss = NULL;
4494
4495 ENTER();
4496
4497 memset(&roamProfile, 0, sizeof(tCsrRoamConnectedProfile));
4498 sme_RoamGetConnectProfile(hHal, pAdapter->sessionId, &roamProfile);
4499
4500 if (NULL != roamProfile.pBssDesc)
4501 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304502 bss = wlan_hdd_cfg80211_inform_bss(pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07004503 &roamProfile);
4504
4505 if (NULL == bss)
4506 {
4507 hddLog(VOS_TRACE_LEVEL_INFO, "%s: cfg80211_inform_bss return NULL",
4508 __func__);
4509 }
4510
4511 sme_RoamFreeConnectProfile(hHal, &roamProfile);
4512 }
4513 else
4514 {
4515 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: roamProfile.pBssDesc is NULL",
4516 __func__);
4517 }
4518 return bss;
4519}
4520
4521/*
4522 * FUNCTION: wlan_hdd_cfg80211_update_bss
4523 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304524static int wlan_hdd_cfg80211_update_bss( struct wiphy *wiphy,
4525 hdd_adapter_t *pAdapter
Jeff Johnson295189b2012-06-20 16:38:30 -07004526 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304527{
Jeff Johnson295189b2012-06-20 16:38:30 -07004528 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
4529 tCsrScanResultInfo *pScanResult;
4530 eHalStatus status = 0;
4531 tScanResultHandle pResult;
4532 struct cfg80211_bss *bss_status = NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -07004533 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07004534
4535 ENTER();
4536
Wilson Yangf80a0542013-10-07 13:02:37 -07004537 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
4538
4539 if (pHddCtx->isLogpInProgress)
Jeff Johnson295189b2012-06-20 16:38:30 -07004540 {
Wilson Yangf80a0542013-10-07 13:02:37 -07004541 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
4542 "%s:LOGP in Progress. Ignore!!!",__func__);
4543 return -EAGAIN;
Jeff Johnson295189b2012-06-20 16:38:30 -07004544 }
4545
Wilson Yangf80a0542013-10-07 13:02:37 -07004546
4547 /*bss_update is not allowed during wlan driver loading or unloading*/
4548 if (pHddCtx->isLoadUnloadInProgress)
4549 {
4550 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4551 "%s:Loading_unloading in Progress. Ignore!!!",__func__);
4552 return VOS_STATUS_E_PERM;
4553 }
4554
4555
Jeff Johnson295189b2012-06-20 16:38:30 -07004556 /*
4557 * start getting scan results and populate cgf80211 BSS database
4558 */
4559 status = sme_ScanGetResult(hHal, pAdapter->sessionId, NULL, &pResult);
4560
4561 /* no scan results */
4562 if (NULL == pResult)
4563 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05304564 hddLog(VOS_TRACE_LEVEL_INFO, "%s: No scan result Status %d",
4565 __func__, status);
Jeff Johnson295189b2012-06-20 16:38:30 -07004566 return status;
4567 }
4568
4569 pScanResult = sme_ScanResultGetFirst(hHal, pResult);
4570
4571 while (pScanResult)
4572 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304573 /*
4574 * cfg80211_inform_bss() is not updating ie field of bss entry, if
4575 * entry already exists in bss data base of cfg80211 for that
4576 * particular BSS ID. Using cfg80211_inform_bss_frame to update the
4577 * bss entry instead of cfg80211_inform_bss, But this call expects
4578 * mgmt packet as input. As of now there is no possibility to get
4579 * the mgmt(probe response) frame from PE, converting bss_desc to
Jeff Johnson295189b2012-06-20 16:38:30 -07004580 * ieee80211_mgmt(probe response) and passing to c
4581 * fg80211_inform_bss_frame.
4582 * */
4583
4584 bss_status = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
4585 &pScanResult->BssDescriptor);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304586
Jeff Johnson295189b2012-06-20 16:38:30 -07004587
4588 if (NULL == bss_status)
4589 {
4590 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -08004591 "%s: NULL returned by cfg80211_inform_bss", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004592 }
4593 else
4594 {
Yue Maf49ba872013-08-19 12:04:25 -07004595 cfg80211_put_bss(
4596#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0))
4597 wiphy,
4598#endif
4599 bss_status);
Jeff Johnson295189b2012-06-20 16:38:30 -07004600 }
4601
4602 pScanResult = sme_ScanResultGetNext(hHal, pResult);
4603 }
4604
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304605 sme_ScanResultPurge(hHal, pResult);
Jeff Johnson295189b2012-06-20 16:38:30 -07004606
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304607 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07004608}
4609
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004610void
4611hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel)
4612{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304613 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussaina7c8e412013-11-20 11:06:42 -08004614 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(macAddr));
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004615} /****** end hddPrintMacAddr() ******/
4616
4617void
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07004618hddPrintPmkId(tANI_U8 *pmkId, tANI_U8 logLevel)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004619{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304620 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussain6d2a3322013-11-17 19:50:10 -08004621 "%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X",
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07004622 pmkId[0], pmkId[1], pmkId[2], pmkId[3], pmkId[4],
4623 pmkId[5], pmkId[6], pmkId[7], pmkId[8], pmkId[9], pmkId[10],
4624 pmkId[11], pmkId[12], pmkId[13], pmkId[14], pmkId[15]);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004625} /****** end hddPrintPmkId() ******/
4626
4627//hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel);
4628//hddPrintMacAddr(macAddr, VOS_TRACE_LEVEL_FATAL);
4629
4630//void sirDumpBuf(tpAniSirGlobal pMac, tANI_U8 modId, tANI_U32 level, tANI_U8 *buf, tANI_U32 size);
4631//sirDumpBuf(pMac, VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, pmkid, 16);
4632
4633#define dump_bssid(bssid) \
4634 { \
Jeff Johnsone7245742012-09-05 17:12:55 -07004635 hddLog(VOS_TRACE_LEVEL_INFO, "BSSID (MAC) address:\t"); \
4636 hddPrintMacAddr(bssid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004637 }
4638
4639#define dump_pmkid(pMac, pmkid) \
4640 { \
Jeff Johnsone7245742012-09-05 17:12:55 -07004641 hddLog(VOS_TRACE_LEVEL_INFO, "PMKSA-ID:\t"); \
4642 hddPrintPmkId(pmkid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004643 }
4644
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -07004645#if defined(FEATURE_WLAN_LFR) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004646/*
4647 * FUNCTION: wlan_hdd_cfg80211_pmksa_candidate_notify
4648 * This function is used to notify the supplicant of a new PMKSA candidate.
4649 */
4650int wlan_hdd_cfg80211_pmksa_candidate_notify(
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304651 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004652 int index, bool preauth )
4653{
Jeff Johnsone7245742012-09-05 17:12:55 -07004654#ifdef FEATURE_WLAN_OKC
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004655 struct net_device *dev = pAdapter->dev;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004656 hdd_context_t *pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004657
4658 ENTER();
Jeff Johnsone7245742012-09-05 17:12:55 -07004659 hddLog(VOS_TRACE_LEVEL_INFO, "%s is going to notify supplicant of:", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004660
4661 if( NULL == pRoamInfo )
4662 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08004663 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pRoamInfo is NULL", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004664 return -EINVAL;
4665 }
4666
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004667 if (eANI_BOOLEAN_TRUE == hdd_is_okc_mode_enabled(pHddCtx))
4668 {
4669 dump_bssid(pRoamInfo->bssid);
4670 cfg80211_pmksa_candidate_notify(dev, index,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004671 pRoamInfo->bssid, preauth, GFP_KERNEL);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004672 }
Jeff Johnsone7245742012-09-05 17:12:55 -07004673#endif /* FEATURE_WLAN_OKC */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304674 return 0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004675}
4676#endif //FEATURE_WLAN_LFR
4677
Yue Maef608272013-04-08 23:09:17 -07004678#ifdef FEATURE_WLAN_LFR_METRICS
4679/*
4680 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth
4681 * 802.11r/LFR metrics reporting function to report preauth initiation
4682 *
4683 */
4684#define MAX_LFR_METRICS_EVENT_LENGTH 100
4685VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth(hdd_adapter_t *pAdapter,
4686 tCsrRoamInfo *pRoamInfo)
4687{
4688 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
4689 union iwreq_data wrqu;
4690
4691 ENTER();
4692
4693 if (NULL == pAdapter)
4694 {
4695 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
4696 return VOS_STATUS_E_FAILURE;
4697 }
4698
4699 /* create the event */
4700 memset(&wrqu, 0, sizeof(wrqu));
4701 memset(metrics_notification, 0, sizeof(metrics_notification));
4702
4703 wrqu.data.pointer = metrics_notification;
4704 wrqu.data.length = scnprintf(metrics_notification,
4705 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_INIT "
4706 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
4707
4708 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
4709
4710 EXIT();
4711
4712 return VOS_STATUS_SUCCESS;
4713}
4714
4715/*
4716 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth_status
4717 * 802.11r/LFR metrics reporting function to report preauth completion
4718 * or failure
4719 */
4720VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth_status(
4721 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo, bool preauth_status)
4722{
4723 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
4724 union iwreq_data wrqu;
4725
4726 ENTER();
4727
4728 if (NULL == pAdapter)
4729 {
4730 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
4731 return VOS_STATUS_E_FAILURE;
4732 }
4733
4734 /* create the event */
4735 memset(&wrqu, 0, sizeof(wrqu));
4736 memset(metrics_notification, 0, sizeof(metrics_notification));
4737
4738 scnprintf(metrics_notification, sizeof(metrics_notification),
4739 "QCOM: LFR_PREAUTH_STATUS "MAC_ADDRESS_STR,
4740 MAC_ADDR_ARRAY(pRoamInfo->bssid));
4741
4742 if (1 == preauth_status)
4743 strncat(metrics_notification, " TRUE", 5);
4744 else
4745 strncat(metrics_notification, " FALSE", 6);
4746
4747 wrqu.data.pointer = metrics_notification;
4748 wrqu.data.length = strlen(metrics_notification);
4749
4750 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
4751
4752 EXIT();
4753
4754 return VOS_STATUS_SUCCESS;
4755}
4756
4757/*
4758 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_handover
4759 * 802.11r/LFR metrics reporting function to report handover initiation
4760 *
4761 */
4762VOS_STATUS wlan_hdd_cfg80211_roam_metrics_handover(hdd_adapter_t * pAdapter,
4763 tCsrRoamInfo *pRoamInfo)
4764{
4765 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
4766 union iwreq_data wrqu;
4767
4768 ENTER();
4769
4770 if (NULL == pAdapter)
4771 {
4772 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
4773 return VOS_STATUS_E_FAILURE;
4774 }
4775
4776 /* create the event */
4777 memset(&wrqu, 0, sizeof(wrqu));
4778 memset(metrics_notification, 0, sizeof(metrics_notification));
4779
4780 wrqu.data.pointer = metrics_notification;
4781 wrqu.data.length = scnprintf(metrics_notification,
4782 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_HANDOVER "
4783 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
4784
4785 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
4786
4787 EXIT();
4788
4789 return VOS_STATUS_SUCCESS;
4790}
4791#endif
4792
Jeff Johnson295189b2012-06-20 16:38:30 -07004793/*
4794 * FUNCTION: hdd_cfg80211_scan_done_callback
4795 * scanning callback function, called after finishing scan
4796 *
4797 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304798static eHalStatus hdd_cfg80211_scan_done_callback(tHalHandle halHandle,
Jeff Johnson295189b2012-06-20 16:38:30 -07004799 void *pContext, tANI_U32 scanId, eCsrScanStatus status)
4800{
4801 struct net_device *dev = (struct net_device *) pContext;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304802 //struct wireless_dev *wdev = dev->ieee80211_ptr;
Jeff Johnson295189b2012-06-20 16:38:30 -07004803 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07004804 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
4805 hdd_scaninfo_t *pScanInfo = &pHddCtx->scan_info;
Jeff Johnson295189b2012-06-20 16:38:30 -07004806 struct cfg80211_scan_request *req = NULL;
4807 int ret = 0;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05304808 long waitRet = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07004809
4810 ENTER();
4811
4812 hddLog(VOS_TRACE_LEVEL_INFO,
4813 "%s called with halHandle = %p, pContext = %p,"
Arif Hussain6d2a3322013-11-17 19:50:10 -08004814 "scanID = %d, returned status = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07004815 __func__, halHandle, pContext, (int) scanId, (int) status);
4816
Kiet Lamac06e2c2013-10-23 16:25:07 +05304817 pScanInfo->mScanPendingCounter = 0;
4818
Jeff Johnson295189b2012-06-20 16:38:30 -07004819 //Block on scan req completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +05304820 waitRet = wait_for_completion_interruptible_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07004821 &pScanInfo->scan_req_completion_event,
4822 msecs_to_jiffies(WLAN_WAIT_TIME_SCAN_REQ));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05304823 if (waitRet <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -07004824 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05304825 hddLog(VOS_TRACE_LEVEL_ERROR,
4826 "%s wait on scan_req_completion_event failed %ld",__func__, waitRet);
Jeff Johnson295189b2012-06-20 16:38:30 -07004827 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -07004828 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -07004829 }
4830
Yue Maef608272013-04-08 23:09:17 -07004831 if (pScanInfo->mScanPending != VOS_TRUE)
Jeff Johnson295189b2012-06-20 16:38:30 -07004832 {
4833 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -07004834 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -07004835 }
4836
4837 /* Check the scanId */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304838 if (pScanInfo->scanId != scanId)
Jeff Johnson295189b2012-06-20 16:38:30 -07004839 {
4840 hddLog(VOS_TRACE_LEVEL_INFO,
4841 "%s called with mismatched scanId pScanInfo->scanId = %d "
Arif Hussain6d2a3322013-11-17 19:50:10 -08004842 "scanId = %d", __func__, (int) pScanInfo->scanId,
Jeff Johnson295189b2012-06-20 16:38:30 -07004843 (int) scanId);
4844 }
4845
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304846 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07004847 pAdapter);
4848
4849 if (0 > ret)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304850 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004851
4852
4853 /* If any client wait scan result through WEXT
4854 * send scan done event to client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07004855 if (pHddCtx->scan_info.waitScanResult)
Jeff Johnson295189b2012-06-20 16:38:30 -07004856 {
4857 /* The other scan request waiting for current scan finish
4858 * Send event to notify current scan finished */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07004859 if(WEXT_SCAN_PENDING_DELAY == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -07004860 {
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07004861 vos_event_set(&pHddCtx->scan_info.scan_finished_event);
Jeff Johnson295189b2012-06-20 16:38:30 -07004862 }
4863 /* Send notify to WEXT client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07004864 else if(WEXT_SCAN_PENDING_PIGGYBACK == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -07004865 {
4866 struct net_device *dev = pAdapter->dev;
4867 union iwreq_data wrqu;
4868 int we_event;
4869 char *msg;
4870
4871 memset(&wrqu, '\0', sizeof(wrqu));
4872 we_event = SIOCGIWSCAN;
4873 msg = NULL;
4874 wireless_send_event(dev, we_event, &wrqu, msg);
4875 }
4876 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07004877 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07004878
4879 /* Get the Scan Req */
4880 req = pAdapter->request;
4881
4882 if (!req)
4883 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08004884 hddLog(VOS_TRACE_LEVEL_ERROR, "request is became NULL");
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07004885 pScanInfo->mScanPending = VOS_FALSE;
Jeff Johnsone7245742012-09-05 17:12:55 -07004886 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -07004887 }
4888
4889 /*
4890 * setting up 0, just in case.
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304891 */
Jeff Johnson295189b2012-06-20 16:38:30 -07004892 req->n_ssids = 0;
4893 req->n_channels = 0;
4894 req->ie = 0;
4895
Jeff Johnson295189b2012-06-20 16:38:30 -07004896 pAdapter->request = NULL;
Jeff Johnsone7245742012-09-05 17:12:55 -07004897 /* Scan is no longer pending */
4898 pScanInfo->mScanPending = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07004899
Madan Mohan Koyyalamudib764bf82012-10-11 16:38:51 -07004900 /*
4901 * cfg80211_scan_done informing NL80211 about completion
4902 * of scanning
4903 */
4904 cfg80211_scan_done(req, false);
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -08004905 complete(&pScanInfo->abortscan_event_var);
Jeff Johnson295189b2012-06-20 16:38:30 -07004906
Jeff Johnsone7245742012-09-05 17:12:55 -07004907allow_suspend:
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07004908 /* release the wake lock at the end of the scan*/
4909 hdd_allow_suspend();
Jeff Johnsone7245742012-09-05 17:12:55 -07004910
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -07004911 /* Acquire wakelock to handle the case where APP's tries to suspend
4912 * immediatly after the driver gets connect request(i.e after scan)
4913 * from supplicant, this result in app's is suspending and not able
4914 * to process the connect request to AP */
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +05304915 hdd_prevent_suspend_timeout(1000);
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -07004916
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07004917#ifdef FEATURE_WLAN_TDLS
4918 wlan_hdd_tdls_scan_done_callback(pAdapter);
4919#endif
4920
Jeff Johnson295189b2012-06-20 16:38:30 -07004921 EXIT();
4922 return 0;
4923}
4924
4925/*
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08004926 * FUNCTION: hdd_isScanAllowed
4927 * Go through each adapter and check if scan allowed
4928 *
4929 */
4930v_BOOL_t hdd_isScanAllowed( hdd_context_t *pHddCtx )
4931{
4932 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
4933 hdd_station_ctx_t *pHddStaCtx = NULL;
4934 hdd_adapter_t *pAdapter = NULL;
4935 VOS_STATUS status = 0;
4936 v_U8_t staId = 0;
4937 v_U8_t *staMac = NULL;
4938
c_hpothu9b781ba2013-12-30 20:57:45 +05304939 if (TRUE == pHddCtx->btCoexModeSet)
4940 {
4941 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4942 FL("BTCoex Mode operation in progress, Do not allow scan"));
4943 return VOS_FALSE;
4944 }
4945
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08004946 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
4947
4948 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
4949 {
4950 pAdapter = pAdapterNode->pAdapter;
4951
4952 if( pAdapter )
4953 {
4954 hddLog(VOS_TRACE_LEVEL_INFO,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304955 "%s: Adapter with device mode %d exists",
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08004956 __func__, pAdapter->device_mode);
4957 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
4958 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
4959 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
4960 {
4961 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4962 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
4963 (VOS_FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
4964 {
4965 staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]);
4966 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain24bafea2013-11-15 15:10:03 -08004967 "%s: client " MAC_ADDRESS_STR
4968 " is in the middle of WPS/EAPOL exchange.", __func__,
4969 MAC_ADDR_ARRAY(staMac));
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08004970 return VOS_FALSE;
4971 }
4972 }
4973 else if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) ||
4974 (WLAN_HDD_P2P_GO == pAdapter->device_mode))
4975 {
4976 for (staId = 0; staId < WLAN_MAX_STA_COUNT; staId++)
4977 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304978 if ((pAdapter->aStaInfo[staId].isUsed) &&
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08004979 (WLANTL_STA_CONNECTED == pAdapter->aStaInfo[staId].tlSTAState))
4980 {
4981 staMac = (v_U8_t *) &(pAdapter->aStaInfo[staId].macAddrSTA.bytes[0]);
4982
4983 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain24bafea2013-11-15 15:10:03 -08004984 "%s: client " MAC_ADDRESS_STR " of SoftAP/P2P-GO is in the "
4985 "middle of WPS/EAPOL exchange.", __func__,
4986 MAC_ADDR_ARRAY(staMac));
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08004987 return VOS_FALSE;
4988 }
4989 }
4990 }
4991 }
4992 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
4993 pAdapterNode = pNext;
4994 }
4995 hddLog(VOS_TRACE_LEVEL_INFO,
4996 "%s: Scan allowed", __func__);
4997 return VOS_TRUE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304998}
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08004999
5000/*
Jeff Johnson295189b2012-06-20 16:38:30 -07005001 * FUNCTION: wlan_hdd_cfg80211_scan
5002 * this scan respond to scan trigger and update cfg80211 scan database
5003 * later, scan dump command can be used to recieve scan results
5004 */
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -08005005int wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
5006#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
5007 struct net_device *dev,
5008#endif
5009 struct cfg80211_scan_request *request)
5010{
5011#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
5012 struct net_device *dev = request->wdev->netdev;
5013#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305014 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Jeff Johnson295189b2012-06-20 16:38:30 -07005015 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
5016 hdd_wext_state_t *pwextBuf = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305017 hdd_config_t *cfg_param = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07005018 tCsrScanRequest scanRequest;
5019 tANI_U8 *channelList = NULL, i;
5020 v_U32_t scanId = 0;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305021 int status;
5022 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07005023 v_U8_t* pP2pIe = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07005024
5025 ENTER();
5026
Arif Hussain6d2a3322013-11-17 19:50:10 -08005027 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07005028 __func__,pAdapter->device_mode);
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08005029
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305030 status = wlan_hdd_validate_context(pHddCtx);
5031
5032 if (0 != status)
5033 {
5034 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5035 "%s: HDD context is not valid", __func__);
5036 return status;
5037 }
5038
5039 cfg_param = pHddCtx->cfg_ini;
5040 pScanInfo = &pHddCtx->scan_info;
5041
Gopichand Nakkala681989c2013-03-06 22:27:48 -08005042 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08005043 (eConnectionState_Connecting ==
Gopichand Nakkala681989c2013-03-06 22:27:48 -08005044 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08005045 {
5046 hddLog(VOS_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08005047 "%s: %p(%d) Connection in progress: Scan request denied (EBUSY)", __func__, \
5048 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08005049 return -EBUSY;
5050 }
5051
Jeff Johnson295189b2012-06-20 16:38:30 -07005052#ifdef WLAN_BTAMP_FEATURE
5053 //Scan not supported when AMP traffic is on.
Gopichand Nakkala681989c2013-03-06 22:27:48 -08005054 if (VOS_TRUE == WLANBAP_AmpSessionOn())
Jeff Johnson295189b2012-06-20 16:38:30 -07005055 {
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08005056 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07005057 "%s: No scanning when AMP is on", __func__);
5058 return -EOPNOTSUPP;
5059 }
5060#endif
5061 //Scan on any other interface is not supported.
Gopichand Nakkala681989c2013-03-06 22:27:48 -08005062 if (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07005063 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -08005064 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07005065 "%s: Not scanning on device_mode = %d",
5066 __func__, pAdapter->device_mode);
5067 return -EOPNOTSUPP;
5068 }
5069
5070 if (TRUE == pScanInfo->mScanPending)
5071 {
Kiet Lamac06e2c2013-10-23 16:25:07 +05305072 if ( MAX_PENDING_LOG > pScanInfo->mScanPendingCounter++ )
5073 {
5074 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: mScanPending is TRUE", __func__);
5075 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08005076 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -07005077 }
5078
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305079 //Don't Allow Scan and return busy if Remain On
Jeff Johnson32d95a32012-09-10 13:15:23 -07005080 //Channel and action frame is pending
5081 //Otherwise Cancel Remain On Channel and allow Scan
5082 //If no action frame pending
Gopichand Nakkala681989c2013-03-06 22:27:48 -08005083 if (0 != wlan_hdd_check_remain_on_channel(pAdapter))
Jeff Johnson32d95a32012-09-10 13:15:23 -07005084 {
Kiet Lamac06e2c2013-10-23 16:25:07 +05305085 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Remain On Channel Pending", __func__);
Jeff Johnson32d95a32012-09-10 13:15:23 -07005086 return -EBUSY;
5087 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08005088#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07005089 /* if tdls disagree scan right now, return immediately.
5090 tdls will schedule the scan when scan is allowed. (return SUCCESS)
5091 or will reject the scan if any TDLS is in progress. (return -EBUSY)
5092 */
5093 status = wlan_hdd_tdls_scan_callback (pAdapter,
5094 wiphy,
5095#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
5096 dev,
Gopichand Nakkalac3c42b92013-03-20 19:42:34 -07005097#endif
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07005098 request);
5099 if(status <= 0)
5100 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05305101 if(!status)
5102 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS in progress."
5103 "scan rejected %d", __func__, status);
5104 else
5105 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS teardown is ongoing %d",
5106 __func__, status);
5107
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07005108 return status;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08005109 }
5110#endif
Jeff Johnson32d95a32012-09-10 13:15:23 -07005111
Jeff Johnson295189b2012-06-20 16:38:30 -07005112 if (mutex_lock_interruptible(&pHddCtx->tmInfo.tmOperationLock))
5113 {
5114 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_ERROR,
Jeff Johnson1250df42012-12-10 14:31:52 -08005115 "%s: Acquire lock fail", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005116 return -EAGAIN;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305117 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005118 if (TRUE == pHddCtx->tmInfo.tmAction.enterImps)
5119 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05305120 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07005121 "%s: MAX TM Level Scan not allowed", __func__);
5122 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305123 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -07005124 }
5125 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
5126
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08005127 /* Check if scan is allowed at this point of time.
5128 */
5129 if (!hdd_isScanAllowed(pHddCtx))
5130 {
5131 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Scan not allowed", __func__);
5132 return -EBUSY;
5133 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305134
Jeff Johnson295189b2012-06-20 16:38:30 -07005135 vos_mem_zero( &scanRequest, sizeof(scanRequest));
5136
5137 if (NULL != request)
5138 {
5139 hddLog(VOS_TRACE_LEVEL_INFO, "scan request for ssid = %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305140 (int)request->n_ssids);
Jeff Johnson295189b2012-06-20 16:38:30 -07005141
5142 /* Even though supplicant doesn't provide any SSIDs, n_ssids is set to 1.
5143 * Becasue of this, driver is assuming that this is not wildcard scan and so
5144 * is not aging out the scan results.
5145 */
Jeff Johnson32d95a32012-09-10 13:15:23 -07005146 if (request->ssids && '\0' == request->ssids->ssid[0])
Jeff Johnson295189b2012-06-20 16:38:30 -07005147 {
5148 request->n_ssids = 0;
5149 }
5150
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07005151 if ((request->ssids) && (0 < request->n_ssids))
Jeff Johnson295189b2012-06-20 16:38:30 -07005152 {
5153 tCsrSSIDInfo *SsidInfo;
5154 int j;
5155 scanRequest.SSIDs.numOfSSIDs = request->n_ssids;
5156 /* Allocate num_ssid tCsrSSIDInfo structure */
5157 SsidInfo = scanRequest.SSIDs.SSIDList =
5158 ( tCsrSSIDInfo *)vos_mem_malloc(
5159 request->n_ssids*sizeof(tCsrSSIDInfo));
5160
5161 if(NULL == scanRequest.SSIDs.SSIDList)
5162 {
5163 hddLog(VOS_TRACE_LEVEL_ERROR,
Nirav Shah20ac06f2013-12-12 18:14:06 +05305164 "%s: memory alloc failed SSIDInfo buffer", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005165 return -ENOMEM;
5166 }
5167
5168 /* copy all the ssid's and their length */
5169 for(j = 0; j < request->n_ssids; j++, SsidInfo++)
5170 {
5171 /* get the ssid length */
5172 SsidInfo->SSID.length = request->ssids[j].ssid_len;
5173 vos_mem_copy(SsidInfo->SSID.ssId, &request->ssids[j].ssid[0],
5174 SsidInfo->SSID.length);
5175 SsidInfo->SSID.ssId[SsidInfo->SSID.length] = '\0';
Nirav Shah20ac06f2013-12-12 18:14:06 +05305176 hddLog(VOS_TRACE_LEVEL_INFO, "SSID number %d: %s",
Jeff Johnson295189b2012-06-20 16:38:30 -07005177 j, SsidInfo->SSID.ssId);
5178 }
5179 /* set the scan type to active */
5180 scanRequest.scanType = eSIR_ACTIVE_SCAN;
5181 }
5182 else if(WLAN_HDD_P2P_GO == pAdapter->device_mode)
5183 {
5184 /* set the scan type to active */
5185 scanRequest.scanType = eSIR_ACTIVE_SCAN;
5186 }
5187 else
5188 {
5189 /*Set the scan type to default type, in this case it is ACTIVE*/
5190 scanRequest.scanType = pScanInfo->scan_mode;
5191 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305192 scanRequest.minChnTime = cfg_param->nActiveMinChnTime;
Jeff Johnson295189b2012-06-20 16:38:30 -07005193 scanRequest.maxChnTime = cfg_param->nActiveMaxChnTime;
5194 }
5195 else
5196 {
5197 /* set the scan type to active */
5198 scanRequest.scanType = eSIR_ACTIVE_SCAN;
5199 vos_mem_set( scanRequest.bssid, sizeof( tCsrBssid ), 0xff );
5200
5201 /* set min and max channel time to zero */
5202 scanRequest.minChnTime = 0;
5203 scanRequest.maxChnTime = 0;
5204 }
5205
5206 /* set BSSType to default type */
5207 scanRequest.BSSType = eCSR_BSS_TYPE_ANY;
5208
5209 /*TODO: scan the requested channels only*/
5210
5211 /*Right now scanning all the channels */
5212 if( request )
5213 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05305214 hddLog(VOS_TRACE_LEVEL_INFO,
5215 "No of Scan Channels: %d", request->n_channels);
Jeff Johnson295189b2012-06-20 16:38:30 -07005216 if( request->n_channels )
5217 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05305218 char chList [(request->n_channels*5)+1];
5219 int len;
Jeff Johnson295189b2012-06-20 16:38:30 -07005220 channelList = vos_mem_malloc( request->n_channels );
5221 if( NULL == channelList )
5222 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305223 hddLog(VOS_TRACE_LEVEL_ERROR,
Nirav Shah20ac06f2013-12-12 18:14:06 +05305224 "%s: memory alloc failed channelList", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005225 status = -ENOMEM;
5226 goto free_mem;
5227 }
5228
Nirav Shah20ac06f2013-12-12 18:14:06 +05305229 for( i = 0, len = 0; i < request->n_channels ; i++ )
5230 {
Jeff Johnson295189b2012-06-20 16:38:30 -07005231 channelList[i] = request->channels[i]->hw_value;
Nirav Shah20ac06f2013-12-12 18:14:06 +05305232 len += snprintf(chList+len, 5, "%d ", channelList[i]);
5233 }
5234
5235 hddLog(VOS_TRACE_LEVEL_INFO,
5236 "Channel-List: %s ", chList);
Jeff Johnson295189b2012-06-20 16:38:30 -07005237 }
5238
5239 scanRequest.ChannelInfo.numOfChannels = request->n_channels;
5240 scanRequest.ChannelInfo.ChannelList = channelList;
5241
5242 /* set requestType to full scan */
5243 scanRequest.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305244
5245 /* Flush the scan results(only p2p beacons) for STA scan and P2P
Madan Mohan Koyyalamudi8d50f312012-11-27 15:48:57 -08005246 * search (Flush on both full scan and social scan but not on single
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305247 * channel scan).P2P search happens on 3 social channels (1, 6, 11)
Madan Mohan Koyyalamudi8d50f312012-11-27 15:48:57 -08005248 */
5249
5250 /* Supplicant does single channel scan after 8-way handshake
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305251 * and in that case driver shoudnt flush scan results. If
5252 * driver flushes the scan results here and unfortunately if
5253 * the AP doesnt respond to our probe req then association
Madan Mohan Koyyalamudi8d50f312012-11-27 15:48:57 -08005254 * fails which is not desired
5255 */
5256
5257 if( request->n_channels != WLAN_HDD_P2P_SINGLE_CHANNEL_SCAN )
5258 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05305259 hddLog(VOS_TRACE_LEVEL_DEBUG, "Flushing P2P Results");
Madan Mohan Koyyalamudi8d50f312012-11-27 15:48:57 -08005260 sme_ScanFlushP2PResult( WLAN_HDD_GET_HAL_CTX(pAdapter),
5261 pAdapter->sessionId );
5262 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005263
5264 if( request->ie_len )
5265 {
5266 /* save this for future association (join requires this) */
Agarwal Ashish4f616132013-12-30 23:32:50 +05305267 /*TODO: Array needs to be converted to dynamic allocation,
5268 * as multiple ie.s can be sent in cfg80211_scan_request structure
5269 * CR 597966
5270 */
Jeff Johnson295189b2012-06-20 16:38:30 -07005271 memset( &pScanInfo->scanAddIE, 0, sizeof(pScanInfo->scanAddIE) );
5272 memcpy( pScanInfo->scanAddIE.addIEdata, request->ie, request->ie_len);
5273 pScanInfo->scanAddIE.length = request->ie_len;
5274
Agarwal Ashish4f616132013-12-30 23:32:50 +05305275 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Jeff Johnsone7245742012-09-05 17:12:55 -07005276 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
Agarwal Ashish4f616132013-12-30 23:32:50 +05305277 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -07005278 {
Agarwal Ashish4f616132013-12-30 23:32:50 +05305279 if ( request->ie_len <= SIR_MAC_MAX_IE_LENGTH)
5280 {
5281 pwextBuf->roamProfile.nAddIEScanLength = request->ie_len;
5282 memcpy( pwextBuf->roamProfile.addIEScan,
5283 request->ie, request->ie_len);
5284 }
5285 else
5286 {
5287 hddLog(VOS_TRACE_LEVEL_ERROR, "Scan Ie length is invalid:"
5288 "%d", request->ie_len);
5289 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005290
Agarwal Ashish4f616132013-12-30 23:32:50 +05305291 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005292 scanRequest.uIEFieldLen = pScanInfo->scanAddIE.length;
5293 scanRequest.pIEField = pScanInfo->scanAddIE.addIEdata;
5294
Jeff Johnson295189b2012-06-20 16:38:30 -07005295 pP2pIe = wlan_hdd_get_p2p_ie_ptr((v_U8_t*)request->ie,
5296 request->ie_len);
5297 if (pP2pIe != NULL)
5298 {
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07005299#ifdef WLAN_FEATURE_P2P_DEBUG
5300 if (((globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED) ||
5301 (globalP2PConnectionStatus == P2P_GO_NEG_PROCESS)) &&
5302 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
5303 {
5304 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_1;
5305 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
5306 "Go nego completed to Connection is started");
5307 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
5308 "for 8way Handshake");
5309 }
5310 else if((globalP2PConnectionStatus == P2P_CLIENT_DISCONNECTED_STATE) &&
5311 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
5312 {
5313 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_2;
5314 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
5315 "Disconnected state to Connection is started");
5316 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
5317 "for 4way Handshake");
5318 }
5319#endif
5320
Jeff Johnsone7245742012-09-05 17:12:55 -07005321 /* no_cck will be set during p2p find to disable 11b rates */
5322 if(TRUE == request->no_cck)
Jeff Johnson295189b2012-06-20 16:38:30 -07005323 {
Jeff Johnson295189b2012-06-20 16:38:30 -07005324 hddLog(VOS_TRACE_LEVEL_INFO,
5325 "%s: This is a P2P Search", __func__);
5326 scanRequest.p2pSearch = 1;
Jeff Johnsone7245742012-09-05 17:12:55 -07005327
Jeff Johnsone7245742012-09-05 17:12:55 -07005328 if( request->n_channels == WLAN_HDD_P2P_SOCIAL_CHANNELS )
5329 {
Madan Mohan Koyyalamudi1b1d9e82012-10-21 11:38:33 -07005330 /* set requestType to P2P Discovery */
5331 scanRequest.requestType = eCSR_SCAN_P2P_DISCOVERY;
Jeff Johnsone7245742012-09-05 17:12:55 -07005332 }
5333
5334 /*
5335 Skip Dfs Channel in case of P2P Search
5336 if it is set in ini file
5337 */
5338 if(cfg_param->skipDfsChnlInP2pSearch)
5339 {
5340 scanRequest.skipDfsChnlInP2pSearch = 1;
5341 }
5342 else
5343 {
5344 scanRequest.skipDfsChnlInP2pSearch = 0;
5345 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005346
Jeff Johnson295189b2012-06-20 16:38:30 -07005347 }
5348 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005349 }
5350 }
5351
5352 INIT_COMPLETION(pScanInfo->scan_req_completion_event);
5353
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07005354 /* acquire the wakelock to avoid the apps suspend during the scan. To
5355 * address the following issues.
5356 * 1) Disconnected scenario: we are not allowing the suspend as WLAN is not in
5357 * BMPS/IMPS this result in android trying to suspend aggressively and backing off
5358 * for long time, this result in apps running at full power for long time.
5359 * 2) Connected scenario: If we allow the suspend during the scan, RIVA will
5360 * be stuck in full power because of resume BMPS
5361 */
5362 hdd_prevent_suspend();
Jeff Johnsone7245742012-09-05 17:12:55 -07005363
Nirav Shah20ac06f2013-12-12 18:14:06 +05305364 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
5365 "requestType %d, scanType %d, minChnTime %d, maxChnTime %d,"
5366 "p2pSearch %d, skipDfsChnlInP2pSearch %d", scanRequest.requestType,
5367 scanRequest.scanType, scanRequest.minChnTime, scanRequest.maxChnTime,
5368 scanRequest.p2pSearch, scanRequest.skipDfsChnlInP2pSearch);
5369
Jeff Johnsone7245742012-09-05 17:12:55 -07005370 status = sme_ScanRequest( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07005371 pAdapter->sessionId, &scanRequest, &scanId,
5372 &hdd_cfg80211_scan_done_callback, dev );
Jeff Johnsone7245742012-09-05 17:12:55 -07005373
Jeff Johnson295189b2012-06-20 16:38:30 -07005374 if (eHAL_STATUS_SUCCESS != status)
5375 {
5376 hddLog(VOS_TRACE_LEVEL_ERROR,
5377 "%s: sme_ScanRequest returned error %d", __func__, status);
5378 complete(&pScanInfo->scan_req_completion_event);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -07005379 if(eHAL_STATUS_RESOURCES == status)
5380 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05305381 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: HO is in progress."
5382 "So defer the scan by informing busy",__func__);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -07005383 status = -EBUSY;
5384 } else {
5385 status = -EIO;
5386 }
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07005387 hdd_allow_suspend();
Jeff Johnson295189b2012-06-20 16:38:30 -07005388 goto free_mem;
5389 }
5390
5391 pScanInfo->mScanPending = TRUE;
5392 pAdapter->request = request;
5393 pScanInfo->scanId = scanId;
5394
5395 complete(&pScanInfo->scan_req_completion_event);
5396
5397free_mem:
5398 if( scanRequest.SSIDs.SSIDList )
5399 {
5400 vos_mem_free(scanRequest.SSIDs.SSIDList);
5401 }
5402
5403 if( channelList )
5404 vos_mem_free( channelList );
5405
5406 EXIT();
5407
5408 return status;
5409}
5410
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07005411
5412void hdd_select_cbmode( hdd_adapter_t *pAdapter,v_U8_t operationChannel)
5413{
5414 v_U8_t iniDot11Mode =
5415 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->dot11Mode;
5416 eHddDot11Mode hddDot11Mode = iniDot11Mode;
5417
5418 switch ( iniDot11Mode )
5419 {
5420 case eHDD_DOT11_MODE_AUTO:
5421 case eHDD_DOT11_MODE_11ac:
5422 case eHDD_DOT11_MODE_11ac_ONLY:
5423#ifdef WLAN_FEATURE_11AC
5424 hddDot11Mode = eHDD_DOT11_MODE_11ac;
5425#else
5426 hddDot11Mode = eHDD_DOT11_MODE_11n;
5427#endif
5428 break;
5429 case eHDD_DOT11_MODE_11n:
5430 case eHDD_DOT11_MODE_11n_ONLY:
5431 hddDot11Mode = eHDD_DOT11_MODE_11n;
5432 break;
5433 default:
5434 hddDot11Mode = iniDot11Mode;
5435 break;
5436 }
5437 /* This call decides required channel bonding mode */
5438 sme_SelectCBMode((WLAN_HDD_GET_CTX(pAdapter)->hHal),
5439 hdd_cfg_xlate_to_csr_phy_mode(hddDot11Mode),
5440 operationChannel);
5441}
5442
Jeff Johnson295189b2012-06-20 16:38:30 -07005443/*
5444 * FUNCTION: wlan_hdd_cfg80211_connect_start
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305445 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -07005446 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305447int wlan_hdd_cfg80211_connect_start( hdd_adapter_t *pAdapter,
Jeff Johnson32d95a32012-09-10 13:15:23 -07005448 const u8 *ssid, size_t ssid_len, const u8 *bssid, u8 operatingChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -07005449{
5450 int status = 0;
5451 hdd_wext_state_t *pWextState;
5452 v_U32_t roamId;
5453 tCsrRoamProfile *pRoamProfile;
Jeff Johnson295189b2012-06-20 16:38:30 -07005454 eCsrAuthType RSNAuthType;
5455
5456 ENTER();
5457
5458 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305459
Jeff Johnson295189b2012-06-20 16:38:30 -07005460 if (SIR_MAC_MAX_SSID_LENGTH < ssid_len)
5461 {
5462 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wrong SSID len", __func__);
5463 return -EINVAL;
5464 }
5465
5466 pRoamProfile = &pWextState->roamProfile;
5467
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305468 if (pRoamProfile)
Jeff Johnson295189b2012-06-20 16:38:30 -07005469 {
Jeff Johnsone7245742012-09-05 17:12:55 -07005470 hdd_station_ctx_t *pHddStaCtx;
5471 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07005472
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305473 if (HDD_WMM_USER_MODE_NO_QOS ==
Jeff Johnson295189b2012-06-20 16:38:30 -07005474 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->WmmMode)
5475 {
5476 /*QoS not enabled in cfg file*/
5477 pRoamProfile->uapsd_mask = 0;
5478 }
5479 else
5480 {
5481 /*QoS enabled, update uapsd mask from cfg file*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305482 pRoamProfile->uapsd_mask =
Jeff Johnson295189b2012-06-20 16:38:30 -07005483 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask;
5484 }
5485
5486 pRoamProfile->SSIDs.numOfSSIDs = 1;
5487 pRoamProfile->SSIDs.SSIDList->SSID.length = ssid_len;
5488 vos_mem_zero(pRoamProfile->SSIDs.SSIDList->SSID.ssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305489 sizeof(pRoamProfile->SSIDs.SSIDList->SSID.ssId));
Jeff Johnson295189b2012-06-20 16:38:30 -07005490 vos_mem_copy((void *)(pRoamProfile->SSIDs.SSIDList->SSID.ssId),
5491 ssid, ssid_len);
5492
5493 if (bssid)
5494 {
5495 pRoamProfile->BSSIDs.numOfBSSIDs = 1;
5496 vos_mem_copy((void *)(pRoamProfile->BSSIDs.bssid), bssid,
5497 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305498 /* Save BSSID in seperate variable as well, as RoamProfile
5499 BSSID is getting zeroed out in the association process. And in
Jeff Johnson295189b2012-06-20 16:38:30 -07005500 case of join failure we should send valid BSSID to supplicant
5501 */
5502 vos_mem_copy((void *)(pWextState->req_bssId), bssid,
5503 WNI_CFG_BSSID_LEN);
5504 }
Dhanashri Atre51981c62013-06-13 11:47:57 -07005505 else
5506 {
5507 vos_mem_zero((void *)(pRoamProfile->BSSIDs.bssid),WNI_CFG_BSSID_LEN);
5508 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005509
5510 if ((IW_AUTH_WPA_VERSION_WPA == pWextState->wpaVersion) ||
5511 (IW_AUTH_WPA_VERSION_WPA2 == pWextState->wpaVersion))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305512 {
Jeff Johnson295189b2012-06-20 16:38:30 -07005513 /*set gen ie*/
5514 hdd_SetGENIEToCsr(pAdapter, &RSNAuthType);
5515 /*set auth*/
5516 hdd_set_csr_auth_type(pAdapter, RSNAuthType);
5517 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005518#ifdef FEATURE_WLAN_WAPI
5519 if (pAdapter->wapi_info.nWapiMode)
5520 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005521 hddLog(LOG1, "%s: Setting WAPI AUTH Type and Encryption Mode values", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005522 switch (pAdapter->wapi_info.wapiAuthMode)
5523 {
5524 case WAPI_AUTH_MODE_PSK:
5525 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005526 hddLog(LOG1, "%s: WAPI AUTH TYPE: PSK: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07005527 pAdapter->wapi_info.wapiAuthMode);
5528 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_PSK;
5529 break;
5530 }
5531 case WAPI_AUTH_MODE_CERT:
5532 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005533 hddLog(LOG1, "%s: WAPI AUTH TYPE: CERT: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07005534 pAdapter->wapi_info.wapiAuthMode);
5535 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE;
5536 break;
5537 }
5538 } // End of switch
5539 if ( pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_PSK ||
5540 pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_CERT)
5541 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005542 hddLog(LOG1, "%s: WAPI PAIRWISE/GROUP ENCRYPTION: WPI", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005543 pRoamProfile->AuthType.numEntries = 1;
5544 pRoamProfile->EncryptionType.numEntries = 1;
5545 pRoamProfile->EncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
5546 pRoamProfile->mcEncryptionType.numEntries = 1;
5547 pRoamProfile->mcEncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
5548 }
5549 }
5550#endif /* FEATURE_WLAN_WAPI */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05305551#ifdef WLAN_FEATURE_GTK_OFFLOAD
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05305552 /* Initializing gtkOffloadReqParams */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05305553 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
5554 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
5555 {
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05305556 memset(&pHddStaCtx->gtkOffloadReqParams, 0,
5557 sizeof (tSirGtkOffloadParams));
5558 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_DISABLE;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05305559 }
5560#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005561 pRoamProfile->csrPersona = pAdapter->device_mode;
5562
Jeff Johnson32d95a32012-09-10 13:15:23 -07005563 if( operatingChannel )
5564 {
5565 pRoamProfile->ChannelInfo.ChannelList = &operatingChannel;
5566 pRoamProfile->ChannelInfo.numOfChannels = 1;
5567 }
Chet Lanctot186b5732013-03-18 10:26:30 -07005568 else
5569 {
5570 pRoamProfile->ChannelInfo.ChannelList = NULL;
5571 pRoamProfile->ChannelInfo.numOfChannels = 0;
5572 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07005573 if ( (WLAN_HDD_IBSS == pAdapter->device_mode) && operatingChannel)
5574 {
5575 hdd_select_cbmode(pAdapter,operatingChannel);
5576 }
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08005577 /* change conn_state to connecting before sme_RoamConnect(), because sme_RoamConnect()
5578 * has a direct path to call hdd_smeRoamCallback(), which will change the conn_state
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305579 * If direct path, conn_state will be accordingly changed to NotConnected or Associated
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08005580 * by either hdd_AssociationCompletionHandler() or hdd_DisConnectHandler() in sme_RoamCallback()
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -08005581 * if sme_RomConnect is to be queued, Connecting state will remain until it is completed.
5582 */
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05305583 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
5584 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode)
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -08005585 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
5586 eConnectionState_Connecting);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305587
5588 status = sme_RoamConnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07005589 pAdapter->sessionId, pRoamProfile, &roamId);
5590
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05305591 if ((eHAL_STATUS_SUCCESS != status) &&
5592 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
5593 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +05305594
5595 {
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08005596 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: sme_RoamConnect (session %d) failed with "
5597 "status %d. -> NotConnected", __func__, pAdapter->sessionId, status);
5598 /* change back to NotAssociated */
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +05305599 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08005600 eConnectionState_NotConnected);
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +05305601 }
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -08005602
5603 pRoamProfile->ChannelInfo.ChannelList = NULL;
5604 pRoamProfile->ChannelInfo.numOfChannels = 0;
5605
Jeff Johnson295189b2012-06-20 16:38:30 -07005606 }
5607 else
5608 {
5609 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid Roam profile", __func__);
5610 return -EINVAL;
5611 }
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08005612 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07005613 return status;
5614}
5615
5616/*
5617 * FUNCTION: wlan_hdd_set_cfg80211_auth_type
5618 * This function is used to set the authentication type (OPEN/SHARED).
5619 *
5620 */
5621static int wlan_hdd_cfg80211_set_auth_type(hdd_adapter_t *pAdapter,
5622 enum nl80211_auth_type auth_type)
5623{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305624 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07005625 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
5626
5627 ENTER();
5628
5629 /*set authentication type*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305630 switch (auth_type)
Jeff Johnson295189b2012-06-20 16:38:30 -07005631 {
Jeff Johnson295189b2012-06-20 16:38:30 -07005632 case NL80211_AUTHTYPE_AUTOMATIC:
Gopichand Nakkala29149562013-05-10 21:43:41 +05305633 hddLog(VOS_TRACE_LEVEL_INFO,
5634 "%s: set authentication type to AUTOSWITCH", __func__);
5635 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_AUTOSWITCH;
5636 break;
5637
5638 case NL80211_AUTHTYPE_OPEN_SYSTEM:
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07005639#ifdef WLAN_FEATURE_VOWIFI_11R
5640 case NL80211_AUTHTYPE_FT:
5641#endif /* WLAN_FEATURE_VOWIFI_11R */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305642 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -07005643 "%s: set authentication type to OPEN", __func__);
5644 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
5645 break;
5646
5647 case NL80211_AUTHTYPE_SHARED_KEY:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305648 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -07005649 "%s: set authentication type to SHARED", __func__);
5650 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_SHARED_KEY;
5651 break;
5652#ifdef FEATURE_WLAN_CCX
5653 case NL80211_AUTHTYPE_NETWORK_EAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305654 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -07005655 "%s: set authentication type to CCKM WPA", __func__);
5656 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_CCKM_WPA;//eCSR_AUTH_TYPE_CCKM_RSN needs to be handled as well if required.
5657 break;
5658#endif
5659
5660
5661 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305662 hddLog(VOS_TRACE_LEVEL_ERROR,
5663 "%s: Unsupported authentication type %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07005664 auth_type);
5665 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_UNKNOWN;
5666 return -EINVAL;
5667 }
5668
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305669 pWextState->roamProfile.AuthType.authType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -07005670 pHddStaCtx->conn_info.authType;
5671 return 0;
5672}
5673
5674/*
5675 * FUNCTION: wlan_hdd_set_akm_suite
5676 * This function is used to set the key mgmt type(PSK/8021x).
5677 *
5678 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305679static int wlan_hdd_set_akm_suite( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07005680 u32 key_mgmt
5681 )
5682{
5683 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
5684 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305685
Jeff Johnson295189b2012-06-20 16:38:30 -07005686 /*set key mgmt type*/
5687 switch(key_mgmt)
5688 {
5689 case WLAN_AKM_SUITE_PSK:
Gopichand Nakkala356fb102013-03-06 12:34:04 +05305690#ifdef WLAN_FEATURE_VOWIFI_11R
5691 case WLAN_AKM_SUITE_FT_PSK:
5692#endif
5693 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to PSK",
Jeff Johnson295189b2012-06-20 16:38:30 -07005694 __func__);
5695 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_PSK;
5696 break;
5697
5698 case WLAN_AKM_SUITE_8021X:
Gopichand Nakkala356fb102013-03-06 12:34:04 +05305699#ifdef WLAN_FEATURE_VOWIFI_11R
5700 case WLAN_AKM_SUITE_FT_8021X:
5701#endif
5702 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to 8021x",
Jeff Johnson295189b2012-06-20 16:38:30 -07005703 __func__);
5704 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
5705 break;
5706#ifdef FEATURE_WLAN_CCX
5707#define WLAN_AKM_SUITE_CCKM 0x00409600 /* Should be in ieee802_11_defs.h */
5708#define IW_AUTH_KEY_MGMT_CCKM 8 /* Should be in linux/wireless.h */
5709 case WLAN_AKM_SUITE_CCKM:
5710 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to CCKM",
5711 __func__);
5712 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_CCKM;
5713 break;
5714#endif
5715
5716 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305717 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported key mgmt type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07005718 __func__, key_mgmt);
5719 return -EINVAL;
5720
5721 }
5722 return 0;
5723}
5724
5725/*
5726 * FUNCTION: wlan_hdd_cfg80211_set_cipher
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305727 * This function is used to set the encryption type
Jeff Johnson295189b2012-06-20 16:38:30 -07005728 * (NONE/WEP40/WEP104/TKIP/CCMP).
5729 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305730static int wlan_hdd_cfg80211_set_cipher( hdd_adapter_t *pAdapter,
5731 u32 cipher,
Jeff Johnson295189b2012-06-20 16:38:30 -07005732 bool ucast
5733 )
5734{
5735 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305736 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07005737 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
5738
5739 ENTER();
5740
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305741 if (!cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -07005742 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305743 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: received cipher %d - considering none",
Jeff Johnson295189b2012-06-20 16:38:30 -07005744 __func__, cipher);
5745 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
5746 }
5747 else
5748 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305749
Jeff Johnson295189b2012-06-20 16:38:30 -07005750 /*set encryption method*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305751 switch (cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -07005752 {
5753 case IW_AUTH_CIPHER_NONE:
5754 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
5755 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305756
Jeff Johnson295189b2012-06-20 16:38:30 -07005757 case WLAN_CIPHER_SUITE_WEP40:
Gopichand Nakkala29149562013-05-10 21:43:41 +05305758 encryptionType = eCSR_ENCRYPT_TYPE_WEP40;
Jeff Johnson295189b2012-06-20 16:38:30 -07005759 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305760
Jeff Johnson295189b2012-06-20 16:38:30 -07005761 case WLAN_CIPHER_SUITE_WEP104:
Gopichand Nakkala29149562013-05-10 21:43:41 +05305762 encryptionType = eCSR_ENCRYPT_TYPE_WEP104;
Jeff Johnson295189b2012-06-20 16:38:30 -07005763 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305764
Jeff Johnson295189b2012-06-20 16:38:30 -07005765 case WLAN_CIPHER_SUITE_TKIP:
5766 encryptionType = eCSR_ENCRYPT_TYPE_TKIP;
5767 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305768
Jeff Johnson295189b2012-06-20 16:38:30 -07005769 case WLAN_CIPHER_SUITE_CCMP:
5770 encryptionType = eCSR_ENCRYPT_TYPE_AES;
5771 break;
5772#ifdef FEATURE_WLAN_WAPI
5773 case WLAN_CIPHER_SUITE_SMS4:
5774 encryptionType = eCSR_ENCRYPT_TYPE_WPI;
5775 break;
5776#endif
5777
5778#ifdef FEATURE_WLAN_CCX
5779 case WLAN_CIPHER_SUITE_KRK:
5780 encryptionType = eCSR_ENCRYPT_TYPE_KRK;
5781 break;
5782#endif
5783 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305784 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported cipher type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07005785 __func__, cipher);
5786 return -EOPNOTSUPP;
5787 }
5788 }
5789
5790 if (ucast)
5791 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305792 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting unicast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07005793 __func__, encryptionType);
5794 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
5795 pWextState->roamProfile.EncryptionType.numEntries = 1;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305796 pWextState->roamProfile.EncryptionType.encryptionType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -07005797 encryptionType;
5798 }
5799 else
5800 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305801 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting mcast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07005802 __func__, encryptionType);
5803 pHddStaCtx->conn_info.mcEncryptionType = encryptionType;
5804 pWextState->roamProfile.mcEncryptionType.numEntries = 1;
5805 pWextState->roamProfile.mcEncryptionType.encryptionType[0] = encryptionType;
5806 }
5807
5808 return 0;
5809}
5810
5811
5812/*
5813 * FUNCTION: wlan_hdd_cfg80211_set_ie
5814 * This function is used to parse WPA/RSN IE's.
5815 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305816int wlan_hdd_cfg80211_set_ie( hdd_adapter_t *pAdapter,
5817 u8 *ie,
Jeff Johnson295189b2012-06-20 16:38:30 -07005818 size_t ie_len
5819 )
5820{
5821 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
5822 u8 *genie = ie;
5823 v_U16_t remLen = ie_len;
5824#ifdef FEATURE_WLAN_WAPI
5825 v_U32_t akmsuite[MAX_NUM_AKM_SUITES];
5826 u16 *tmp;
5827 v_U16_t akmsuiteCount;
5828 int *akmlist;
5829#endif
5830 ENTER();
5831
5832 /* clear previous assocAddIE */
5833 pWextState->assocAddIE.length = 0;
5834 pWextState->roamProfile.bWPSAssociation = VOS_FALSE;
5835
5836 while (remLen >= 2)
5837 {
5838 v_U16_t eLen = 0;
5839 v_U8_t elementId;
5840 elementId = *genie++;
5841 eLen = *genie++;
5842 remLen -= 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305843
Arif Hussain6d2a3322013-11-17 19:50:10 -08005844 hddLog(VOS_TRACE_LEVEL_INFO, "%s: IE[0x%X], LEN[%d]",
Jeff Johnson295189b2012-06-20 16:38:30 -07005845 __func__, elementId, eLen);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305846
5847 switch ( elementId )
Jeff Johnson295189b2012-06-20 16:38:30 -07005848 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305849 case DOT11F_EID_WPA:
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005850 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 -07005851 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305852 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07005853 "%s: Invalid WPA IE", __func__);
5854 return -EINVAL;
5855 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305856 else if (0 == memcmp(&genie[0], "\x00\x50\xf2\x04", 4))
Jeff Johnson295189b2012-06-20 16:38:30 -07005857 {
5858 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305859 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPS IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -07005860 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305861
Jeff Johnson295189b2012-06-20 16:38:30 -07005862 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
5863 {
Jeff Johnson902c9832012-12-10 14:28:09 -08005864 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE. "
5865 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -07005866 VOS_ASSERT(0);
5867 return -ENOMEM;
5868 }
5869 // WSC IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
5870 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
5871 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305872
Jeff Johnson295189b2012-06-20 16:38:30 -07005873 pWextState->roamProfile.bWPSAssociation = VOS_TRUE;
5874 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
5875 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
5876 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305877 else if (0 == memcmp(&genie[0], "\x00\x50\xf2", 3))
5878 {
Jeff Johnson295189b2012-06-20 16:38:30 -07005879 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPA IE (len %d)",__func__, eLen + 2);
5880 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
5881 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2) /*ie_len*/);
5882 pWextState->roamProfile.pWPAReqIE = pWextState->WPARSNIE;
5883 pWextState->roamProfile.nWPAReqIELength = eLen + 2;//ie_len;
5884 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305885 else if ( (0 == memcmp(&genie[0], P2P_OUI_TYPE,
Kiet Lam8da98992013-11-21 15:59:07 +05305886 P2P_OUI_TYPE_SIZE)))
Jeff Johnson295189b2012-06-20 16:38:30 -07005887 {
5888 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305889 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set P2P IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -07005890 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305891
Jeff Johnson295189b2012-06-20 16:38:30 -07005892 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
5893 {
Jeff Johnson902c9832012-12-10 14:28:09 -08005894 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
5895 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -07005896 VOS_ASSERT(0);
5897 return -ENOMEM;
5898 }
5899 // P2P IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
5900 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
5901 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305902
Jeff Johnson295189b2012-06-20 16:38:30 -07005903 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
5904 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
5905 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005906#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305907 else if ( (0 == memcmp(&genie[0], WFD_OUI_TYPE,
5908 WFD_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07005909 /*Consider WFD IE, only for P2P Client */
5910 && (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
5911 {
5912 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305913 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WFD IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -07005914 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305915
Jeff Johnson295189b2012-06-20 16:38:30 -07005916 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
5917 {
Jeff Johnson902c9832012-12-10 14:28:09 -08005918 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
5919 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -07005920 VOS_ASSERT(0);
5921 return -ENOMEM;
5922 }
5923 // WFD IE is saved to Additional IE ; it should be accumulated to handle
5924 // WPS IE + P2P IE + WFD IE
5925 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
5926 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305927
Jeff Johnson295189b2012-06-20 16:38:30 -07005928 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
5929 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
5930 }
5931#endif
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005932 /* Appending HS 2.0 Indication Element in Assiciation Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305933 else if ( (0 == memcmp(&genie[0], HS20_OUI_TYPE,
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07005934 HS20_OUI_TYPE_SIZE)) )
5935 {
5936 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305937 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set HS20 IE(len %d)",
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07005938 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005939
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07005940 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
5941 {
Jeff Johnson902c9832012-12-10 14:28:09 -08005942 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
5943 "Need bigger buffer space");
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07005944 VOS_ASSERT(0);
5945 return -ENOMEM;
5946 }
5947 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
5948 pWextState->assocAddIE.length += eLen + 2;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005949
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07005950 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
5951 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
5952 }
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005953
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -07005954 if (WLAN_HDD_IBSS == pAdapter->device_mode) {
5955
5956 /* populating as ADDIE in beacon frames */
5957 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
5958 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, genie - 2, eLen + 2,
5959 NULL, eANI_BOOLEAN_FALSE)== eHAL_STATUS_SUCCESS)
5960 {
5961 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
5962 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
5963 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
5964 {
5965 hddLog(LOGE,
5966 "Coldn't pass "
5967 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
5968 }
5969 }/* ccmCfgSetStr(,WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, , )*/
5970 else
5971 hddLog(LOGE,
5972 "Could not pass on "
5973 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
5974
5975 /* IBSS mode doesn't contain params->proberesp_ies still
5976 beaconIE's need to be populated in probe response frames */
5977 if ( (NULL != (genie - 2)) && (0 != eLen + 2) )
5978 {
5979 u16 rem_probe_resp_ie_len = eLen + 2;
5980 u8 probe_rsp_ie_len[3] = {0};
5981 u8 counter = 0;
5982
5983 /* Check Probe Resp Length if it is greater then 255 then
5984 Store Probe Rsp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1
5985 & WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are
5986 not able Store More then 255 bytes into One Variable */
5987
5988 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
5989 {
5990 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
5991 {
5992 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
5993 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
5994 }
5995 else
5996 {
5997 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
5998 rem_probe_resp_ie_len = 0;
5999 }
6000 }
6001
6002 rem_probe_resp_ie_len = 0;
6003
6004 if (probe_rsp_ie_len[0] > 0)
6005 {
6006 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
6007 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
6008 (tANI_U8*)(genie - 2),
6009 probe_rsp_ie_len[0], NULL,
6010 eANI_BOOLEAN_FALSE)
6011 == eHAL_STATUS_FAILURE)
6012 {
6013 hddLog(LOGE,
6014 "Could not pass"
6015 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
6016 }
6017 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
6018 }
6019
6020 if (probe_rsp_ie_len[1] > 0)
6021 {
6022 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
6023 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
6024 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
6025 probe_rsp_ie_len[1], NULL,
6026 eANI_BOOLEAN_FALSE)
6027 == eHAL_STATUS_FAILURE)
6028 {
6029 hddLog(LOGE,
6030 "Could not pass"
6031 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
6032 }
6033 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
6034 }
6035
6036 if (probe_rsp_ie_len[2] > 0)
6037 {
6038 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
6039 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
6040 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
6041 probe_rsp_ie_len[2], NULL,
6042 eANI_BOOLEAN_FALSE)
6043 == eHAL_STATUS_FAILURE)
6044 {
6045 hddLog(LOGE,
6046 "Could not pass"
6047 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
6048 }
6049 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
6050 }
6051
6052 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
6053 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
6054 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
6055 {
6056 hddLog(LOGE,
6057 "Could not pass"
6058 "on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
6059 }
6060 }
6061 else
6062 {
6063 // Reset WNI_CFG_PROBE_RSP Flags
6064 wlan_hdd_reset_prob_rspies(pAdapter);
6065
6066 hddLog(VOS_TRACE_LEVEL_INFO,
6067 "%s: No Probe Response IE received in set beacon",
6068 __func__);
6069 }
6070 } /* end of if (WLAN_HDD_IBSS == pAdapter->device_mode) */
Jeff Johnson295189b2012-06-20 16:38:30 -07006071 break;
6072 case DOT11F_EID_RSN:
6073 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set RSN IE(len %d)",__func__, eLen + 2);
6074 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
6075 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2)/*ie_len*/);
6076 pWextState->roamProfile.pRSNReqIE = pWextState->WPARSNIE;
6077 pWextState->roamProfile.nRSNReqIELength = eLen + 2; //ie_len;
6078 break;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07006079 /* Appending Extended Capabilities with Interworking bit set in Assoc Req */
6080 case DOT11F_EID_EXTCAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306081 {
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07006082 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306083 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set Extended CAPS IE(len %d)",
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07006084 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306085
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07006086 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
6087 {
Jeff Johnson902c9832012-12-10 14:28:09 -08006088 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
6089 "Need bigger buffer space");
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07006090 VOS_ASSERT(0);
6091 return -ENOMEM;
6092 }
6093 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
6094 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306095
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07006096 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
6097 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
6098 break;
6099 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006100#ifdef FEATURE_WLAN_WAPI
6101 case WLAN_EID_WAPI:
6102 pAdapter->wapi_info.nWapiMode = 1; //Setting WAPI Mode to ON=1
Jeff Johnson0299d0a2013-10-30 12:37:43 -07006103 hddLog(VOS_TRACE_LEVEL_INFO, "WAPI MODE IS %u",
Jeff Johnson295189b2012-06-20 16:38:30 -07006104 pAdapter->wapi_info.nWapiMode);
6105 tmp = (u16 *)ie;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306106 tmp = tmp + 2; // Skip element Id and Len, Version
Jeff Johnson295189b2012-06-20 16:38:30 -07006107 akmsuiteCount = WPA_GET_LE16(tmp);
6108 tmp = tmp + 1;
6109 akmlist = (int *)(tmp);
6110 if(akmsuiteCount <= MAX_NUM_AKM_SUITES)
6111 {
6112 memcpy(akmsuite, akmlist, (4*akmsuiteCount));
6113 }
6114 else
6115 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08006116 hddLog(VOS_TRACE_LEVEL_FATAL, "Invalid akmSuite count");
Jeff Johnson295189b2012-06-20 16:38:30 -07006117 VOS_ASSERT(0);
6118 return -EINVAL;
6119 }
6120
6121 if (WAPI_PSK_AKM_SUITE == akmsuite[0])
6122 {
6123 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO PSK",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006124 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006125 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_PSK;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306126 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006127 if (WAPI_CERT_AKM_SUITE == akmsuite[0])
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306128 {
Jeff Johnson295189b2012-06-20 16:38:30 -07006129 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO CERTIFICATE",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006130 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006131 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_CERT;
6132 }
6133 break;
6134#endif
6135 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306136 hddLog (VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07006137 "%s Set UNKNOWN IE %X", __func__, elementId);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07006138 /* when Unknown IE is received we should break and continue
6139 * to the next IE in the buffer instead we were returning
6140 * so changing this to break */
6141 break;
Jeff Johnson295189b2012-06-20 16:38:30 -07006142 }
6143 genie += eLen;
6144 remLen -= eLen;
6145 }
6146 EXIT();
6147 return 0;
6148}
6149
6150/*
Gopichand Nakkala18f0c262013-05-07 23:25:08 +05306151 * FUNCTION: hdd_isWPAIEPresent
6152 * Parse the received IE to find the WPA IE
6153 *
6154 */
6155static bool hdd_isWPAIEPresent(u8 *ie, u8 ie_len)
6156{
6157 v_U8_t eLen = 0;
6158 v_U16_t remLen = ie_len;
6159 v_U8_t elementId = 0;
6160
6161 while (remLen >= 2)
6162 {
6163 elementId = *ie++;
6164 eLen = *ie++;
6165 remLen -= 2;
6166 if (eLen > remLen)
6167 {
6168 hddLog(VOS_TRACE_LEVEL_ERROR,
6169 "%s: IE length is wrong %d", __func__, eLen);
6170 return FALSE;
6171 }
6172 if ((elementId == DOT11F_EID_WPA) && (remLen > 5))
6173 {
6174 /* OUI - 0x00 0X50 0XF2
6175 WPA Information Element - 0x01
6176 WPA version - 0x01*/
6177 if (0 == memcmp(&ie[0], "\x00\x50\xf2\x01\x01", 5))
6178 return TRUE;
6179 }
6180 ie += eLen;
6181 remLen -= eLen;
6182 }
6183 return FALSE;
6184}
6185
6186/*
Jeff Johnson295189b2012-06-20 16:38:30 -07006187 * FUNCTION: wlan_hdd_cfg80211_set_privacy
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306188 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -07006189 * parameters during connect operation.
6190 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306191int wlan_hdd_cfg80211_set_privacy( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07006192 struct cfg80211_connect_params *req
6193 )
6194{
6195 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306196 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07006197 ENTER();
6198
6199 /*set wpa version*/
6200 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
6201
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306202 if (req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -07006203 {
Gopichand Nakkala781ded42013-06-28 12:10:45 +05306204 if (NL80211_WPA_VERSION_1 == req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -07006205 {
6206 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
6207 }
6208 else if (NL80211_WPA_VERSION_2 == req->crypto.wpa_versions)
6209 {
6210 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
6211 }
6212 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306213
6214 hddLog(VOS_TRACE_LEVEL_INFO, "%s: set wpa version to %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07006215 pWextState->wpaVersion);
6216
6217 /*set authentication type*/
6218 status = wlan_hdd_cfg80211_set_auth_type(pAdapter, req->auth_type);
6219
6220 if (0 > status)
6221 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306222 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07006223 "%s: failed to set authentication type ", __func__);
6224 return status;
6225 }
6226
6227 /*set key mgmt type*/
6228 if (req->crypto.n_akm_suites)
6229 {
6230 status = wlan_hdd_set_akm_suite(pAdapter, req->crypto.akm_suites[0]);
6231 if (0 > status)
6232 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306233 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set akm suite",
Jeff Johnson295189b2012-06-20 16:38:30 -07006234 __func__);
6235 return status;
6236 }
6237 }
6238
6239 /*set pairwise cipher type*/
6240 if (req->crypto.n_ciphers_pairwise)
6241 {
6242 status = wlan_hdd_cfg80211_set_cipher(pAdapter,
6243 req->crypto.ciphers_pairwise[0], true);
6244 if (0 > status)
6245 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306246 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07006247 "%s: failed to set unicast cipher type", __func__);
6248 return status;
6249 }
6250 }
6251 else
6252 {
6253 /*Reset previous cipher suite to none*/
6254 status = wlan_hdd_cfg80211_set_cipher(pAdapter, 0, true);
6255 if (0 > status)
6256 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306257 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07006258 "%s: failed to set unicast cipher type", __func__);
6259 return status;
6260 }
6261 }
6262
6263 /*set group cipher type*/
6264 status = wlan_hdd_cfg80211_set_cipher(pAdapter, req->crypto.cipher_group,
6265 false);
6266
6267 if (0 > status)
6268 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306269 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set mcast cipher type",
Jeff Johnson295189b2012-06-20 16:38:30 -07006270 __func__);
6271 return status;
6272 }
6273
Chet Lanctot186b5732013-03-18 10:26:30 -07006274#ifdef WLAN_FEATURE_11W
6275 pWextState->roamProfile.MFPEnabled = (req->mfp == NL80211_MFP_REQUIRED);
6276#endif
6277
Jeff Johnson295189b2012-06-20 16:38:30 -07006278 /*parse WPA/RSN IE, and set the correspoing fileds in Roam profile*/
6279 if (req->ie_len)
6280 {
6281 status = wlan_hdd_cfg80211_set_ie(pAdapter, req->ie, req->ie_len);
6282 if ( 0 > status)
6283 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306284 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse the WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -07006285 __func__);
6286 return status;
6287 }
6288 }
6289
6290 /*incase of WEP set default key information*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306291 if (req->key && req->key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -07006292 {
6293 if ( (WLAN_CIPHER_SUITE_WEP40 == req->crypto.ciphers_pairwise[0])
6294 || (WLAN_CIPHER_SUITE_WEP104 == req->crypto.ciphers_pairwise[0])
6295 )
6296 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306297 if ( IW_AUTH_KEY_MGMT_802_1X
Jeff Johnson295189b2012-06-20 16:38:30 -07006298 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X ))
6299 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306300 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Dynamic WEP not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -07006301 __func__);
6302 return -EOPNOTSUPP;
6303 }
6304 else
6305 {
6306 u8 key_len = req->key_len;
6307 u8 key_idx = req->key_idx;
6308
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306309 if ((eCSR_SECURITY_WEP_KEYSIZE_MAX_BYTES >= key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -07006310 && (CSR_MAX_NUM_KEY > key_idx)
6311 )
6312 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306313 hddLog(VOS_TRACE_LEVEL_INFO,
6314 "%s: setting default wep key, key_idx = %hu key_len %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07006315 __func__, key_idx, key_len);
6316 vos_mem_copy(
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306317 &pWextState->roamProfile.Keys.KeyMaterial[key_idx][0],
Jeff Johnson295189b2012-06-20 16:38:30 -07006318 req->key, key_len);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306319 pWextState->roamProfile.Keys.KeyLength[key_idx] =
Jeff Johnson295189b2012-06-20 16:38:30 -07006320 (u8)key_len;
6321 pWextState->roamProfile.Keys.defaultIndex = (u8)key_idx;
6322 }
6323 }
6324 }
6325 }
6326
6327 return status;
6328}
6329
6330/*
Vinay Krishna Eranna21042322014-01-08 19:21:39 +05306331 * FUNCTION: wlan_hdd_try_disconnect
6332 * This function is used to disconnect from previous
6333 * connection
6334 */
6335static int wlan_hdd_try_disconnect( hdd_adapter_t *pAdapter )
6336{
6337 long ret = 0;
6338 hdd_station_ctx_t *pHddStaCtx;
6339 eMib_dot11DesiredBssType connectedBssType;
6340
6341 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6342
6343 hdd_connGetConnectedBssType(pHddStaCtx,&connectedBssType );
6344
6345 if((eMib_dot11DesiredBssType_independent == connectedBssType) ||
6346 (eConnectionState_Associated == pHddStaCtx->conn_info.connState) ||
6347 (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState))
6348 {
6349 /* Issue disconnect to CSR */
6350 INIT_COMPLETION(pAdapter->disconnect_comp_var);
6351 if( eHAL_STATUS_SUCCESS ==
6352 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
6353 pAdapter->sessionId,
6354 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
6355 {
6356 ret = wait_for_completion_interruptible_timeout(
6357 &pAdapter->disconnect_comp_var,
6358 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
6359 if (0 >= ret)
6360 {
6361 hddLog(LOGE, FL("Failed to receive disconnect event"));
6362 return -EALREADY;
6363 }
6364 }
6365 }
6366 else if(eConnectionState_Disconnecting == pHddStaCtx->conn_info.connState)
6367 {
6368 ret = wait_for_completion_interruptible_timeout(
6369 &pAdapter->disconnect_comp_var,
6370 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
6371 if (0 >= ret)
6372 {
6373 hddLog(LOGE, FL("Failed to receive disconnect event"));
6374 return -EALREADY;
6375 }
6376 }
6377
6378 return 0;
6379}
6380
6381/*
Jeff Johnson295189b2012-06-20 16:38:30 -07006382 * FUNCTION: wlan_hdd_cfg80211_set_privacy
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306383 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -07006384 * parameters during connect operation.
6385 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306386static int wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07006387 struct net_device *ndev,
6388 struct cfg80211_connect_params *req
6389 )
6390{
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306391 int status;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306392 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -07006393 VOS_STATUS exitbmpsStatus = VOS_STATUS_E_INVAL;
Rajesh Chauhana0516c62014-01-30 16:11:18 -08006394 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07006395
6396 ENTER();
6397
Rajesh Chauhana0516c62014-01-30 16:11:18 -08006398 if (!pAdapter)
6399 {
6400 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6401 "%s: Adapter context is null", __func__);
6402 return VOS_STATUS_E_FAILURE;
6403 }
6404
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306405 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006406 "%s: device_mode = %d",__func__,pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07006407
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306408 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -08006409 if (!pHddCtx)
6410 {
6411 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6412 "%s: HDD context is null", __func__);
6413 return VOS_STATUS_E_FAILURE;
6414 }
6415
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306416 status = wlan_hdd_validate_context(pHddCtx);
6417
6418 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -07006419 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306420 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6421 "%s: HDD context is not valid", __func__);
6422 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -07006423 }
6424
6425#ifdef WLAN_BTAMP_FEATURE
6426 //Infra connect not supported when AMP traffic is on.
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306427 if( VOS_TRUE == WLANBAP_AmpSessionOn() )
Jeff Johnson295189b2012-06-20 16:38:30 -07006428 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306429 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07006430 "%s: No connection when AMP is on", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08006431 return -ECONNREFUSED;
Jeff Johnson295189b2012-06-20 16:38:30 -07006432 }
6433#endif
Vinay Krishna Eranna21042322014-01-08 19:21:39 +05306434
6435 //If Device Mode is Station Concurrent Sessions Exit BMps
6436 //P2P Mode will be taken care in Open/close adapter
6437 if((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
6438 (vos_concurrent_sessions_running()))
6439 {
6440 exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
6441 }
6442
6443 /*Try disconnecting if already in connected state*/
6444 status = wlan_hdd_try_disconnect(pAdapter);
6445 if ( 0 > status)
6446 {
6447 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
6448 " connection"));
6449 return -EALREADY;
6450 }
6451
Jeff Johnson295189b2012-06-20 16:38:30 -07006452 /*initialise security parameters*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306453 status = wlan_hdd_cfg80211_set_privacy(pAdapter, req);
Jeff Johnson295189b2012-06-20 16:38:30 -07006454
6455 if ( 0 > status)
6456 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306457 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security params",
Jeff Johnson295189b2012-06-20 16:38:30 -07006458 __func__);
6459 return status;
6460 }
6461
Mohit Khanna765234a2012-09-11 15:08:35 -07006462 if ( req->channel )
6463 {
6464 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
6465 req->ssid_len, req->bssid,
6466 req->channel->hw_value);
6467 }
6468 else
6469 {
6470 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306471 req->ssid_len, req->bssid, 0);
Mohit Khanna765234a2012-09-11 15:08:35 -07006472 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006473
6474 if (0 > status)
6475 {
6476 //ReEnable BMPS if disabled
6477 if((VOS_STATUS_SUCCESS == exitbmpsStatus) &&
6478 (NULL != pHddCtx))
6479 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306480 if (pHddCtx->hdd_wlan_suspended)
6481 {
6482 hdd_set_pwrparams(pHddCtx);
6483 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006484 //ReEnable Bmps and Imps back
6485 hdd_enable_bmps_imps(pHddCtx);
6486 }
6487
6488 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: connect failed", __func__);
6489 return status;
6490 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306491 pHddCtx->isAmpAllowed = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07006492 EXIT();
6493 return status;
6494}
6495
6496
6497/*
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05306498 * FUNCTION: wlan_hdd_disconnect
6499 * This function is used to issue a disconnect request to SME
6500 */
6501int wlan_hdd_disconnect( hdd_adapter_t *pAdapter, u16 reason )
6502{
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306503 int status;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05306504 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306505 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306506 long ret;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306507
6508 status = wlan_hdd_validate_context(pHddCtx);
6509
6510 if (0 != status)
6511 {
6512 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6513 "%s: HDD context is not valid", __func__);
6514 return status;
6515 }
6516
6517 pHddCtx->isAmpAllowed = VOS_TRUE;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05306518 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05306519 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306520
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05306521 /*issue disconnect*/
6522 status = sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
6523 pAdapter->sessionId, reason);
6524
6525 if ( 0 != status )
6526 {
6527 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006528 "%s csrRoamDisconnect failure, returned %d",
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05306529 __func__, (int)status );
6530 return -EINVAL;
6531 }
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306532 ret = wait_for_completion_interruptible_timeout(
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05306533 &pAdapter->disconnect_comp_var,
6534 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306535 if (ret <= 0)
6536 {
6537 hddLog(VOS_TRACE_LEVEL_ERROR,
6538 FL("wait on disconnect_comp_var failed %ld"), ret);
6539 }
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05306540 /*stop tx queues*/
6541 netif_tx_disable(pAdapter->dev);
6542 netif_carrier_off(pAdapter->dev);
6543 return status;
6544}
6545
6546
6547/*
Jeff Johnson295189b2012-06-20 16:38:30 -07006548 * FUNCTION: wlan_hdd_cfg80211_disconnect
6549 * This function is used to issue a disconnect request to SME
6550 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306551static int wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07006552 struct net_device *dev,
6553 u16 reason
6554 )
6555{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306556 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
6557 tCsrRoamProfile *pRoamProfile =
Jeff Johnson295189b2012-06-20 16:38:30 -07006558 &(WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter))->roamProfile;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306559 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07006560 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkala4327a152013-03-04 23:22:42 -08006561 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaaa353782013-05-17 20:36:22 +05306562#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08006563 tANI_U8 staIdx;
6564#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306565
Jeff Johnson295189b2012-06-20 16:38:30 -07006566 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306567
Arif Hussain6d2a3322013-11-17 19:50:10 -08006568 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07006569 __func__,pAdapter->device_mode);
6570
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306571 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Disconnect called with reason code %d",
6572 __func__, reason);
Jeff Johnson295189b2012-06-20 16:38:30 -07006573
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306574 status = wlan_hdd_validate_context(pHddCtx);
6575
6576 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -07006577 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306578 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6579 "%s: HDD context is not valid", __func__);
6580 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -07006581 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306582
Jeff Johnson295189b2012-06-20 16:38:30 -07006583 if (NULL != pRoamProfile)
6584 {
6585 /*issue disconnect request to SME, if station is in connected state*/
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +05306586 if ((pHddStaCtx->conn_info.connState == eConnectionState_Associated) ||
6587 (pHddStaCtx->conn_info.connState == eConnectionState_Connecting))
Jeff Johnson295189b2012-06-20 16:38:30 -07006588 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306589 eCsrRoamDisconnectReason reasonCode =
Jeff Johnson295189b2012-06-20 16:38:30 -07006590 eCSR_DISCONNECT_REASON_UNSPECIFIED;
Gopichand Nakkalaaa353782013-05-17 20:36:22 +05306591 hdd_scaninfo_t *pScanInfo;
Jeff Johnson295189b2012-06-20 16:38:30 -07006592 switch(reason)
6593 {
6594 case WLAN_REASON_MIC_FAILURE:
6595 reasonCode = eCSR_DISCONNECT_REASON_MIC_ERROR;
6596 break;
6597
6598 case WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY:
6599 case WLAN_REASON_DISASSOC_AP_BUSY:
6600 case WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA:
6601 reasonCode = eCSR_DISCONNECT_REASON_DISASSOC;
6602 break;
6603
6604 case WLAN_REASON_PREV_AUTH_NOT_VALID:
6605 case WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA:
6606 reasonCode = eCSR_DISCONNECT_REASON_DEAUTH;
6607 break;
6608
6609 case WLAN_REASON_DEAUTH_LEAVING:
6610 default:
6611 reasonCode = eCSR_DISCONNECT_REASON_UNSPECIFIED;
6612 break;
6613 }
Gopichand Nakkalaaa353782013-05-17 20:36:22 +05306614 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
6615 pScanInfo = &pHddCtx->scan_info;
6616 if (pScanInfo->mScanPending)
6617 {
Srinivas, Dasari138af4f2014-02-07 11:13:45 +05306618 hddLog(VOS_TRACE_LEVEL_INFO, "Disconnect is in progress, "
Gopichand Nakkalaaa353782013-05-17 20:36:22 +05306619 "Aborting Scan");
Srinivas, Dasari138af4f2014-02-07 11:13:45 +05306620 hdd_abort_mac_scan(pHddCtx, pAdapter->sessionId,
6621 eCSR_SCAN_ABORT_DEFAULT);
Gopichand Nakkalaaa353782013-05-17 20:36:22 +05306622 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006623
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08006624#ifdef FEATURE_WLAN_TDLS
6625 /* First clean up the tdls peers if any */
Gopichand Nakkala4327a152013-03-04 23:22:42 -08006626 for (staIdx = 0 ; staIdx < HDD_MAX_NUM_TDLS_STA; staIdx++)
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08006627 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -08006628 if ((pHddCtx->tdlsConnInfo[staIdx].sessionId == pAdapter->sessionId) &&
6629 (pHddCtx->tdlsConnInfo[staIdx].staId))
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08006630 {
Hoonki Lee11f7dda2013-02-14 16:55:44 -08006631 uint8 *mac;
Gopichand Nakkala4327a152013-03-04 23:22:42 -08006632 mac = pHddCtx->tdlsConnInfo[staIdx].peerMac.bytes;
Hoonki Lee11f7dda2013-02-14 16:55:44 -08006633 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07006634 "%s: call sme_DeleteTdlsPeerSta staId %d sessionId %d " MAC_ADDRESS_STR,
Gopichand Nakkala4327a152013-03-04 23:22:42 -08006635 __func__, pHddCtx->tdlsConnInfo[staIdx].staId, pAdapter->sessionId,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07006636 MAC_ADDR_ARRAY(mac));
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08006637 sme_DeleteTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala4327a152013-03-04 23:22:42 -08006638 pAdapter->sessionId,
6639 mac);
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08006640 }
6641 }
6642#endif
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05306643 status = wlan_hdd_disconnect(pAdapter, reasonCode);
6644 if ( 0 != status )
Jeff Johnson295189b2012-06-20 16:38:30 -07006645 {
6646 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006647 "%s wlan_hdd_disconnect failure, returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07006648 __func__, (int)status );
6649 return -EINVAL;
6650 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006651 }
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +05306652 else
6653 {
6654 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unexpected cfg disconnect API"
6655 "called while in %d state", __func__,
6656 pHddStaCtx->conn_info.connState);
6657 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006658 }
6659 else
6660 {
6661 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid roam profile", __func__);
6662 }
6663
6664 return status;
6665}
6666
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05306667
Jeff Johnson295189b2012-06-20 16:38:30 -07006668/*
6669 * FUNCTION: wlan_hdd_cfg80211_set_privacy_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306670 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -07006671 * settings in IBSS mode.
6672 */
6673static int wlan_hdd_cfg80211_set_privacy_ibss(
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306674 hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07006675 struct cfg80211_ibss_params *params
6676 )
6677{
6678 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306679 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07006680 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
6681 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306682
Jeff Johnson295189b2012-06-20 16:38:30 -07006683 ENTER();
6684
6685 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
Ravi Joshib58ca0d2013-10-29 09:50:23 -07006686 vos_mem_zero(&pHddStaCtx->ibss_enc_key, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -07006687
6688 if (params->ie_len && ( NULL != params->ie) )
6689 {
Shailender Karmuchi67edd312013-06-18 16:30:48 -07006690 if (wlan_hdd_cfg80211_get_ie_ptr (params->ie,
6691 params->ie_len, WLAN_EID_RSN ))
Jeff Johnson295189b2012-06-20 16:38:30 -07006692 {
6693 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
6694 encryptionType = eCSR_ENCRYPT_TYPE_AES;
6695 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -07006696 else if ( hdd_isWPAIEPresent (params->ie, params->ie_len ))
Jeff Johnson295189b2012-06-20 16:38:30 -07006697 {
Shailender Karmuchi642e9812013-05-30 14:34:49 -07006698 tDot11fIEWPA dot11WPAIE;
6699 tHalHandle halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
Shailender Karmuchi67edd312013-06-18 16:30:48 -07006700 u8 *ie;
Shailender Karmuchi642e9812013-05-30 14:34:49 -07006701
Wilson Yang00256342013-10-10 23:13:38 -07006702 memset(&dot11WPAIE, 0, sizeof(dot11WPAIE));
Shailender Karmuchi67edd312013-06-18 16:30:48 -07006703 ie = wlan_hdd_cfg80211_get_ie_ptr (params->ie,
6704 params->ie_len, DOT11F_EID_WPA);
6705 if ( NULL != ie )
6706 {
6707 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
6708 // Unpack the WPA IE
6709 //Skip past the EID byte and length byte - and four byte WiFi OUI
6710 dot11fUnpackIeWPA((tpAniSirGlobal) halHandle,
6711 &ie[2+4],
6712 ie[1] - 4,
6713 &dot11WPAIE);
6714 /*Extract the multicast cipher, the encType for unicast
6715 cipher for wpa-none is none*/
6716 encryptionType =
6717 hdd_TranslateWPAToCsrEncryptionType(dot11WPAIE.multicast_cipher);
6718 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006719 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -07006720
Jeff Johnson295189b2012-06-20 16:38:30 -07006721 status = wlan_hdd_cfg80211_set_ie(pAdapter, params->ie, params->ie_len);
6722
6723 if (0 > status)
6724 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306725 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -07006726 __func__);
6727 return status;
6728 }
6729 }
6730
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306731 pWextState->roamProfile.AuthType.authType[0] =
6732 pHddStaCtx->conn_info.authType =
Jeff Johnson295189b2012-06-20 16:38:30 -07006733 eCSR_AUTH_TYPE_OPEN_SYSTEM;
6734
6735 if (params->privacy)
6736 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306737 /* Security enabled IBSS, At this time there is no information available
6738 * about the security paramters, so initialise the encryption type to
Jeff Johnson295189b2012-06-20 16:38:30 -07006739 * eCSR_ENCRYPT_TYPE_WEP40_STATICKEY.
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306740 * The correct security parameters will be updated later in
Jeff Johnson295189b2012-06-20 16:38:30 -07006741 * wlan_hdd_cfg80211_add_key */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306742 /* Hal expects encryption type to be set inorder
Jeff Johnson295189b2012-06-20 16:38:30 -07006743 *enable privacy bit in beacons */
6744
6745 encryptionType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
6746 }
Shailender Karmuchi642e9812013-05-30 14:34:49 -07006747 VOS_TRACE (VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
6748 "encryptionType=%d", encryptionType);
Jeff Johnson295189b2012-06-20 16:38:30 -07006749 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
6750 pWextState->roamProfile.EncryptionType.numEntries = 1;
6751 pWextState->roamProfile.EncryptionType.encryptionType[0] = encryptionType;
Jeff Johnson295189b2012-06-20 16:38:30 -07006752 return status;
6753}
6754
6755/*
6756 * FUNCTION: wlan_hdd_cfg80211_join_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306757 * This function is used to create/join an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -07006758 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306759static int wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07006760 struct net_device *dev,
6761 struct cfg80211_ibss_params *params
6762 )
6763{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306764 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Jeff Johnson295189b2012-06-20 16:38:30 -07006765 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
6766 tCsrRoamProfile *pRoamProfile;
6767 int status;
krunal sonie9002db2013-11-25 14:24:17 -08006768 bool alloc_bssid = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07006769 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306770 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07006771
6772 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306773
6774 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006775 "%s: device_mode = %d",__func__,pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07006776
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306777 status = wlan_hdd_validate_context(pHddCtx);
6778
6779 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -07006780 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306781 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6782 "%s: HDD context is not valid", __func__);
6783 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -07006784 }
6785
6786 if (NULL == pWextState)
6787 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08006788 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -07006789 __func__);
6790 return -EIO;
6791 }
6792
Vinay Krishna Eranna21042322014-01-08 19:21:39 +05306793 /*Try disconnecting if already in connected state*/
6794 status = wlan_hdd_try_disconnect(pAdapter);
6795 if ( 0 > status)
6796 {
6797 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
6798 " IBSS connection"));
6799 return -EALREADY;
6800 }
6801
Jeff Johnson295189b2012-06-20 16:38:30 -07006802 pRoamProfile = &pWextState->roamProfile;
6803
6804 if ( eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType )
6805 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306806 hddLog (VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006807 "%s Interface type is not set to IBSS", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006808 return -EINVAL;
6809 }
6810
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -07006811 /* BSSID is provided by upper layers hence no need to AUTO generate */
6812 if (NULL != params->bssid) {
6813 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
6814 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) {
6815 hddLog (VOS_TRACE_LEVEL_ERROR,
6816 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
6817 return -EIO;
6818 }
6819 }
krunal sonie9002db2013-11-25 14:24:17 -08006820 else if(pHddCtx->cfg_ini->isCoalesingInIBSSAllowed == 0)
6821 {
6822 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
6823 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
6824 {
6825 hddLog (VOS_TRACE_LEVEL_ERROR,
6826 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
6827 return -EIO;
6828 }
6829 params->bssid = vos_mem_malloc(sizeof(VOS_MAC_ADDR_SIZE));
6830 if (!params->bssid)
6831 {
6832 hddLog (VOS_TRACE_LEVEL_ERROR,
6833 "%s:Failed memory allocation", __func__);
6834 return -EIO;
6835 }
6836 vos_mem_copy((v_U8_t *)params->bssid,
6837 (v_U8_t *)&pHddCtx->cfg_ini->IbssBssid.bytes[0],
6838 VOS_MAC_ADDR_SIZE);
6839 alloc_bssid = VOS_TRUE;
6840 }
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -07006841
Jeff Johnson295189b2012-06-20 16:38:30 -07006842 /* Set Channel */
Yue Maf49ba872013-08-19 12:04:25 -07006843 if (NULL !=
6844#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
6845 params->chandef.chan)
6846#else
6847 params->channel)
6848#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006849 {
6850 u8 channelNum;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07006851 v_U32_t numChans = WNI_CFG_VALID_CHANNEL_LIST_LEN;
6852 v_U8_t validChan[WNI_CFG_VALID_CHANNEL_LIST_LEN];
6853 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
6854 int indx;
Jeff Johnson295189b2012-06-20 16:38:30 -07006855
6856 /* Get channel number */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306857 channelNum =
Yue Maf49ba872013-08-19 12:04:25 -07006858 ieee80211_frequency_to_channel(
6859#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
6860 params->chandef.chan->center_freq);
6861#else
6862 params->channel->center_freq);
6863#endif
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07006864
6865 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
6866 validChan, &numChans))
Jeff Johnson295189b2012-06-20 16:38:30 -07006867 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07006868 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid channel list",
6869 __func__);
6870 return -EOPNOTSUPP;
Jeff Johnson295189b2012-06-20 16:38:30 -07006871 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07006872
6873 for (indx = 0; indx < numChans; indx++)
Jeff Johnson295189b2012-06-20 16:38:30 -07006874 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07006875 if (channelNum == validChan[indx])
6876 {
6877 break;
6878 }
6879 }
6880 if (indx >= numChans)
6881 {
6882 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Not valid Channel %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07006883 __func__, channelNum);
6884 return -EINVAL;
6885 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07006886 /* Set the Operational Channel */
6887 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: set channel %d", __func__,
6888 channelNum);
6889 pRoamProfile->ChannelInfo.numOfChannels = 1;
6890 pHddStaCtx->conn_info.operationChannel = channelNum;
6891 pRoamProfile->ChannelInfo.ChannelList =
6892 &pHddStaCtx->conn_info.operationChannel;
Jeff Johnson295189b2012-06-20 16:38:30 -07006893 }
6894
6895 /* Initialize security parameters */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306896 status = wlan_hdd_cfg80211_set_privacy_ibss(pAdapter, params);
Jeff Johnson295189b2012-06-20 16:38:30 -07006897 if (status < 0)
6898 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306899 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security parameters",
Jeff Johnson295189b2012-06-20 16:38:30 -07006900 __func__);
6901 return status;
6902 }
6903
6904 /* Issue connect start */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306905 status = wlan_hdd_cfg80211_connect_start(pAdapter, params->ssid,
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07006906 params->ssid_len, params->bssid,
6907 pHddStaCtx->conn_info.operationChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -07006908
6909 if (0 > status)
6910 {
6911 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: connect failed", __func__);
6912 return status;
6913 }
6914
krunal sonie9002db2013-11-25 14:24:17 -08006915 if (NULL != params->bssid &&
6916 pHddCtx->cfg_ini->isCoalesingInIBSSAllowed == 0 &&
6917 alloc_bssid == VOS_TRUE)
6918 {
6919 vos_mem_free(params->bssid);
6920 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006921 return 0;
6922}
6923
6924/*
6925 * FUNCTION: wlan_hdd_cfg80211_leave_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306926 * This function is used to leave an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -07006927 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306928static int wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07006929 struct net_device *dev
6930 )
6931{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306932 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Jeff Johnson295189b2012-06-20 16:38:30 -07006933 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
6934 tCsrRoamProfile *pRoamProfile;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306935 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
6936 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07006937
6938 ENTER();
6939
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306940 status = wlan_hdd_validate_context(pHddCtx);
6941
6942 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006943 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306944 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6945 "%s: HDD context is not valid", __func__);
6946 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006947 }
6948
Arif Hussain6d2a3322013-11-17 19:50:10 -08006949 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",__func__,pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07006950 if (NULL == pWextState)
6951 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08006952 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -07006953 __func__);
6954 return -EIO;
6955 }
6956
6957 pRoamProfile = &pWextState->roamProfile;
6958
6959 /* Issue disconnect only if interface type is set to IBSS */
6960 if (eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType)
6961 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306962 hddLog (VOS_TRACE_LEVEL_ERROR, "%s: BSS Type is not set to IBSS",
Jeff Johnson295189b2012-06-20 16:38:30 -07006963 __func__);
6964 return -EINVAL;
6965 }
6966
6967 /* Issue Disconnect request */
6968 INIT_COMPLETION(pAdapter->disconnect_comp_var);
6969 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
6970 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
6971
6972 return 0;
6973}
6974
6975/*
6976 * FUNCTION: wlan_hdd_cfg80211_set_wiphy_params
6977 * This function is used to set the phy parameters
6978 * (RTS Threshold/FRAG Threshold/Retry Count etc ...)
6979 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306980static int wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07006981 u32 changed)
6982{
6983 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
6984 tHalHandle hHal = pHddCtx->hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306985 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07006986
6987 ENTER();
6988
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306989 status = wlan_hdd_validate_context(pHddCtx);
6990
6991 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006992 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306993 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6994 "%s: HDD context is not valid", __func__);
6995 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006996 }
6997
Jeff Johnson295189b2012-06-20 16:38:30 -07006998 if (changed & WIPHY_PARAM_RTS_THRESHOLD)
6999 {
7000 u16 rts_threshold = (wiphy->rts_threshold == -1) ?
7001 WNI_CFG_RTS_THRESHOLD_STAMAX :
7002 wiphy->rts_threshold;
7003
7004 if ((WNI_CFG_RTS_THRESHOLD_STAMIN > rts_threshold) ||
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307005 (WNI_CFG_RTS_THRESHOLD_STAMAX < rts_threshold))
Jeff Johnson295189b2012-06-20 16:38:30 -07007006 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307007 hddLog(VOS_TRACE_LEVEL_ERROR,
7008 "%s: Invalid RTS Threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07007009 __func__, rts_threshold);
7010 return -EINVAL;
7011 }
7012
7013 if (0 != ccmCfgSetInt(hHal, WNI_CFG_RTS_THRESHOLD,
7014 rts_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307015 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -07007016 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307017 hddLog(VOS_TRACE_LEVEL_ERROR,
7018 "%s: ccmCfgSetInt failed for rts_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07007019 __func__, rts_threshold);
7020 return -EIO;
7021 }
7022
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307023 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set rts threshold %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07007024 rts_threshold);
7025 }
7026
7027 if (changed & WIPHY_PARAM_FRAG_THRESHOLD)
7028 {
7029 u16 frag_threshold = (wiphy->frag_threshold == -1) ?
7030 WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX :
7031 wiphy->frag_threshold;
7032
7033 if ((WNI_CFG_FRAGMENTATION_THRESHOLD_STAMIN > frag_threshold)||
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307034 (WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX < frag_threshold) )
Jeff Johnson295189b2012-06-20 16:38:30 -07007035 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307036 hddLog(VOS_TRACE_LEVEL_ERROR,
7037 "%s: Invalid frag_threshold value %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07007038 frag_threshold);
7039 return -EINVAL;
7040 }
7041
7042 if (0 != ccmCfgSetInt(hHal, WNI_CFG_FRAGMENTATION_THRESHOLD,
7043 frag_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307044 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -07007045 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307046 hddLog(VOS_TRACE_LEVEL_ERROR,
7047 "%s: ccmCfgSetInt failed for frag_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07007048 __func__, frag_threshold);
7049 return -EIO;
7050 }
7051
7052 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set frag threshold %hu", __func__,
7053 frag_threshold);
7054 }
7055
7056 if ((changed & WIPHY_PARAM_RETRY_SHORT)
7057 || (changed & WIPHY_PARAM_RETRY_LONG))
7058 {
7059 u8 retry_value = (changed & WIPHY_PARAM_RETRY_SHORT) ?
7060 wiphy->retry_short :
7061 wiphy->retry_long;
7062
7063 if ((WNI_CFG_LONG_RETRY_LIMIT_STAMIN > retry_value) ||
7064 (WNI_CFG_LONG_RETRY_LIMIT_STAMAX < retry_value))
7065 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307066 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07007067 __func__, retry_value);
7068 return -EINVAL;
7069 }
7070
7071 if (changed & WIPHY_PARAM_RETRY_SHORT)
7072 {
7073 if (0 != ccmCfgSetInt(hHal, WNI_CFG_LONG_RETRY_LIMIT,
7074 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307075 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -07007076 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307077 hddLog(VOS_TRACE_LEVEL_ERROR,
7078 "%s: ccmCfgSetInt failed for long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07007079 __func__, retry_value);
7080 return -EIO;
7081 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307082 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07007083 __func__, retry_value);
7084 }
7085 else if (changed & WIPHY_PARAM_RETRY_SHORT)
7086 {
7087 if (0 != ccmCfgSetInt(hHal, WNI_CFG_SHORT_RETRY_LIMIT,
7088 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307089 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -07007090 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307091 hddLog(VOS_TRACE_LEVEL_ERROR,
7092 "%s: ccmCfgSetInt failed for short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07007093 __func__, retry_value);
7094 return -EIO;
7095 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307096 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07007097 __func__, retry_value);
7098 }
7099 }
7100
7101 return 0;
7102}
7103
7104/*
7105 * FUNCTION: wlan_hdd_cfg80211_set_txpower
7106 * This function is used to set the txpower
7107 */
7108static int wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
Yue Maf49ba872013-08-19 12:04:25 -07007109#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
7110 struct wireless_dev *wdev,
7111#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007112#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307113 enum tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -07007114#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307115 enum nl80211_tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -07007116#endif
7117 int dbm)
7118{
7119 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307120 tHalHandle hHal = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07007121 tSirMacAddr bssid = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
7122 tSirMacAddr selfMac = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307123 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07007124
7125 ENTER();
7126
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307127 status = wlan_hdd_validate_context(pHddCtx);
7128
7129 if (0 != status)
7130 {
7131 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7132 "%s: HDD context is not valid", __func__);
7133 return status;
7134 }
7135
7136 hHal = pHddCtx->hHal;
7137
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307138 if (0 != ccmCfgSetInt(hHal, WNI_CFG_CURRENT_TX_POWER_LEVEL,
7139 dbm, ccmCfgSetCallback,
7140 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -07007141 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307142 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07007143 "%s: ccmCfgSetInt failed for tx power %hu", __func__, dbm);
7144 return -EIO;
7145 }
7146
7147 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set tx power level %d dbm", __func__,
7148 dbm);
7149
7150 switch(type)
7151 {
7152 case NL80211_TX_POWER_AUTOMATIC: /*automatically determine transmit power*/
7153 /* Fall through */
7154 case NL80211_TX_POWER_LIMITED: /*limit TX power by the mBm parameter*/
7155 if( sme_SetMaxTxPower(hHal, bssid, selfMac, dbm) != eHAL_STATUS_SUCCESS )
7156 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307157 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Setting maximum tx power failed",
7158 __func__);
7159 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -07007160 }
7161 break;
7162 case NL80211_TX_POWER_FIXED: /*fix TX power to the mBm parameter*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307163 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: NL80211_TX_POWER_FIXED not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -07007164 __func__);
7165 return -EOPNOTSUPP;
7166 break;
7167 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307168 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid power setting type %d",
7169 __func__, type);
Jeff Johnson295189b2012-06-20 16:38:30 -07007170 return -EIO;
7171 }
7172
7173 return 0;
7174}
7175
7176/*
7177 * FUNCTION: wlan_hdd_cfg80211_get_txpower
7178 * This function is used to read the txpower
7179 */
Yue Maf49ba872013-08-19 12:04:25 -07007180static int wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy,
7181#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
7182 struct wireless_dev *wdev,
7183#endif
7184 int *dbm)
Jeff Johnson295189b2012-06-20 16:38:30 -07007185{
7186
7187 hdd_adapter_t *pAdapter;
7188 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307189 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07007190
Jeff Johnsone7245742012-09-05 17:12:55 -07007191 ENTER();
7192
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307193 status = wlan_hdd_validate_context(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07007194
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307195 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007196 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307197 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7198 "%s: HDD context is not valid", __func__);
7199 *dbm = 0;
7200 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007201 }
7202
Jeff Johnson295189b2012-06-20 16:38:30 -07007203 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
7204 if (NULL == pAdapter)
7205 {
7206 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Not in station context " ,__func__);
7207 return -ENOENT;
7208 }
7209
7210 wlan_hdd_get_classAstats(pAdapter);
7211 *dbm = pAdapter->hdd_stats.ClassA_stat.max_pwr;
7212
Jeff Johnsone7245742012-09-05 17:12:55 -07007213 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07007214 return 0;
7215}
7216
7217static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
7218 u8* mac, struct station_info *sinfo)
7219{
7220 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
7221 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7222 int ssidlen = pHddStaCtx->conn_info.SSID.SSID.length;
7223 tANI_U8 rate_flags;
7224
7225 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
7226 hdd_config_t *pCfg = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -07007227
7228 tANI_U8 OperationalRates[CSR_DOT11_SUPPORTED_RATES_MAX];
7229 tANI_U32 ORLeng = CSR_DOT11_SUPPORTED_RATES_MAX;
7230 tANI_U8 ExtendedRates[CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX];
7231 tANI_U32 ERLeng = CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX;
7232 tANI_U8 MCSRates[SIZE_OF_BASIC_MCS_SET];
7233 tANI_U32 MCSLeng = SIZE_OF_BASIC_MCS_SET;
7234 tANI_U16 maxRate = 0;
7235 tANI_U16 myRate;
7236 tANI_U16 currentRate = 0;
7237 tANI_U8 maxSpeedMCS = 0;
7238 tANI_U8 maxMCSIdx = 0;
7239 tANI_U8 rateFlag = 1;
7240 tANI_U8 i, j, rssidx;
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07007241 tANI_U16 temp;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307242 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07007243
Leo Chang6f8870f2013-03-26 18:11:36 -07007244#ifdef WLAN_FEATURE_11AC
7245 tANI_U32 vht_mcs_map;
7246 eDataRate11ACMaxMcs vhtMaxMcs;
7247#endif /* WLAN_FEATURE_11AC */
7248
Jeff Johnsone7245742012-09-05 17:12:55 -07007249 ENTER();
7250
Jeff Johnson295189b2012-06-20 16:38:30 -07007251 if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) ||
7252 (0 == ssidlen))
7253 {
7254 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Not associated or"
7255 " Invalid ssidlen, %d", __func__, ssidlen);
7256 /*To keep GUI happy*/
7257 return 0;
7258 }
7259
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307260 status = wlan_hdd_validate_context(pHddCtx);
7261
7262 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007263 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307264 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7265 "%s: HDD context is not valid", __func__);
7266 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007267 }
7268
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -07007269 wlan_hdd_get_station_stats(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07007270 rate_flags = pAdapter->hdd_stats.ClassA_stat.tx_rate_flags;
7271
Kiet Lam3b17fc82013-09-27 05:24:08 +05307272 wlan_hdd_get_rssi(pAdapter, &sinfo->signal);
7273 sinfo->filled |= STATION_INFO_SIGNAL;
7274
Jeff Johnson295189b2012-06-20 16:38:30 -07007275 //convert to the UI units of 100kbps
7276 myRate = pAdapter->hdd_stats.ClassA_stat.tx_rate * 5;
7277
7278#ifdef LINKSPEED_DEBUG_ENABLED
Leo Chang6f8870f2013-03-26 18:11:36 -07007279 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 -07007280 sinfo->signal,
7281 pCfg->reportMaxLinkSpeed,
7282 myRate,
7283 (int) pCfg->linkSpeedRssiHigh,
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07007284 (int) pCfg->linkSpeedRssiMid,
7285 (int) pCfg->linkSpeedRssiLow,
Leo Chang6f8870f2013-03-26 18:11:36 -07007286 (int) rate_flags,
7287 (int) pAdapter->hdd_stats.ClassA_stat.mcs_index);
Jeff Johnson295189b2012-06-20 16:38:30 -07007288#endif //LINKSPEED_DEBUG_ENABLED
7289
7290 if (eHDD_LINK_SPEED_REPORT_ACTUAL != pCfg->reportMaxLinkSpeed)
7291 {
7292 // we do not want to necessarily report the current speed
7293 if (eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed)
7294 {
7295 // report the max possible speed
7296 rssidx = 0;
7297 }
7298 else if (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed)
7299 {
7300 // report the max possible speed with RSSI scaling
7301 if (sinfo->signal >= pCfg->linkSpeedRssiHigh)
7302 {
7303 // report the max possible speed
7304 rssidx = 0;
7305 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07007306 else if (sinfo->signal >= pCfg->linkSpeedRssiMid)
Jeff Johnson295189b2012-06-20 16:38:30 -07007307 {
7308 // report middle speed
7309 rssidx = 1;
7310 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07007311 else if (sinfo->signal >= pCfg->linkSpeedRssiLow)
7312 {
7313 // report middle speed
7314 rssidx = 2;
7315 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007316 else
7317 {
7318 // report actual speed
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07007319 rssidx = 3;
Jeff Johnson295189b2012-06-20 16:38:30 -07007320 }
7321 }
7322 else
7323 {
7324 // unknown, treat as eHDD_LINK_SPEED_REPORT_MAX
7325 hddLog(VOS_TRACE_LEVEL_ERROR,
7326 "%s: Invalid value for reportMaxLinkSpeed: %u",
7327 __func__, pCfg->reportMaxLinkSpeed);
7328 rssidx = 0;
7329 }
7330
7331 maxRate = 0;
7332
7333 /* Get Basic Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +05307334 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_OPERATIONAL_RATE_SET,
7335 OperationalRates, &ORLeng))
7336 {
7337 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
7338 /*To keep GUI happy*/
7339 return 0;
7340 }
7341
Jeff Johnson295189b2012-06-20 16:38:30 -07007342 for (i = 0; i < ORLeng; i++)
7343 {
Jeff Johnsone7245742012-09-05 17:12:55 -07007344 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -07007345 {
7346 /* Validate Rate Set */
7347 if (supported_data_rate[j].beacon_rate_index == (OperationalRates[i] & 0x7F))
7348 {
7349 currentRate = supported_data_rate[j].supported_rate[rssidx];
7350 break;
7351 }
7352 }
7353 /* Update MAX rate */
7354 maxRate = (currentRate > maxRate)?currentRate:maxRate;
7355 }
7356
7357 /* Get Extended Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +05307358 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET,
7359 ExtendedRates, &ERLeng))
7360 {
7361 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
7362 /*To keep GUI happy*/
7363 return 0;
7364 }
7365
Jeff Johnson295189b2012-06-20 16:38:30 -07007366 for (i = 0; i < ERLeng; i++)
7367 {
Jeff Johnsone7245742012-09-05 17:12:55 -07007368 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -07007369 {
7370 if (supported_data_rate[j].beacon_rate_index == (ExtendedRates[i] & 0x7F))
7371 {
7372 currentRate = supported_data_rate[j].supported_rate[rssidx];
7373 break;
7374 }
7375 }
7376 /* Update MAX rate */
7377 maxRate = (currentRate > maxRate)?currentRate:maxRate;
7378 }
Kiet Lamb69f8dc2013-11-15 15:34:27 +05307379 /* Get MCS Rate Set --
Kaushik, Sushantdc304d82014-01-22 10:58:37 +05307380 Only if we are always reporting max speed (or)
Kiet Lamb69f8dc2013-11-15 15:34:27 +05307381 if we have good rssi */
Kaushik, Sushantdc304d82014-01-22 10:58:37 +05307382 if ((0 == rssidx) ||
Kiet Lamb69f8dc2013-11-15 15:34:27 +05307383 (eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed))
Jeff Johnson295189b2012-06-20 16:38:30 -07007384 {
Gopichand Nakkala05ab1322013-02-15 11:28:38 +05307385 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_CURRENT_MCS_SET,
7386 MCSRates, &MCSLeng))
7387 {
7388 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
7389 /*To keep GUI happy*/
7390 return 0;
7391 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007392 rateFlag = 0;
Leo Chang6f8870f2013-03-26 18:11:36 -07007393#ifdef WLAN_FEATURE_11AC
7394 /* VHT80 rate has seperate rate table */
Gopichand Nakkala4c705372013-04-24 13:20:33 +05307395 if (rate_flags & (eHAL_TX_RATE_VHT20|eHAL_TX_RATE_VHT40|eHAL_TX_RATE_VHT80))
Jeff Johnson295189b2012-06-20 16:38:30 -07007396 {
Leo Chang6f8870f2013-03-26 18:11:36 -07007397 ccmCfgGetInt(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_VHT_TX_MCS_MAP, &vht_mcs_map);
Gopichand Nakkala4c705372013-04-24 13:20:33 +05307398 vhtMaxMcs = (eDataRate11ACMaxMcs)(vht_mcs_map & DATA_RATE_11AC_MCS_MASK );
Leo Chang6f8870f2013-03-26 18:11:36 -07007399 if (rate_flags & eHAL_TX_RATE_SGI)
Jeff Johnson295189b2012-06-20 16:38:30 -07007400 {
Leo Chang6f8870f2013-03-26 18:11:36 -07007401 rateFlag |= 1;
Jeff Johnson295189b2012-06-20 16:38:30 -07007402 }
Leo Chang6f8870f2013-03-26 18:11:36 -07007403 if (DATA_RATE_11AC_MAX_MCS_7 == vhtMaxMcs)
Jeff Johnson295189b2012-06-20 16:38:30 -07007404 {
Leo Chang6f8870f2013-03-26 18:11:36 -07007405 maxMCSIdx = 7;
7406 }
7407 else if (DATA_RATE_11AC_MAX_MCS_8 == vhtMaxMcs)
7408 {
7409 maxMCSIdx = 8;
7410 }
7411 else if (DATA_RATE_11AC_MAX_MCS_9 == vhtMaxMcs)
7412 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +05307413 //VHT20 is supporting 0~8
7414 if (rate_flags & eHAL_TX_RATE_VHT20)
7415 maxMCSIdx = 8;
7416 else
7417 maxMCSIdx = 9;
Leo Chang6f8870f2013-03-26 18:11:36 -07007418 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +05307419
7420 if (rate_flags & eHAL_TX_RATE_VHT80)
7421 {
7422 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT80_rate[rateFlag];
7423 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT80_rate[rateFlag];
7424 }
7425 else if (rate_flags & eHAL_TX_RATE_VHT40)
7426 {
7427 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT40_rate[rateFlag];
7428 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT40_rate[rateFlag];
7429 }
7430 else if (rate_flags & eHAL_TX_RATE_VHT20)
7431 {
7432 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT20_rate[rateFlag];
7433 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT20_rate[rateFlag];
7434 }
7435
Leo Chang6f8870f2013-03-26 18:11:36 -07007436 maxSpeedMCS = 1;
7437 if (currentRate > maxRate)
7438 {
7439 maxRate = currentRate;
7440 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +05307441
Leo Chang6f8870f2013-03-26 18:11:36 -07007442 }
7443 else
7444#endif /* WLAN_FEATURE_11AC */
7445 {
7446 if (rate_flags & eHAL_TX_RATE_HT40)
7447 {
7448 rateFlag |= 1;
7449 }
7450 if (rate_flags & eHAL_TX_RATE_SGI)
7451 {
7452 rateFlag |= 2;
7453 }
7454
7455 for (i = 0; i < MCSLeng; i++)
7456 {
7457 temp = sizeof(supported_mcs_rate) / sizeof(supported_mcs_rate[0]);
7458 for (j = 0; j < temp; j++)
7459 {
7460 if (supported_mcs_rate[j].beacon_rate_index == MCSRates[i])
7461 {
7462 currentRate = supported_mcs_rate[j].supported_rate[rateFlag];
7463 break;
7464 }
7465 }
7466 if ((j < temp) && (currentRate > maxRate))
7467 {
7468 maxRate = currentRate;
7469 maxSpeedMCS = 1;
7470 maxMCSIdx = supported_mcs_rate[j].beacon_rate_index;
7471 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007472 }
7473 }
7474 }
7475
Gopichand Nakkala4c705372013-04-24 13:20:33 +05307476 else if (!(rate_flags & eHAL_TX_RATE_LEGACY))
7477 {
7478 maxRate = myRate;
7479 maxSpeedMCS = 1;
7480 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
7481 }
7482
Jeff Johnson295189b2012-06-20 16:38:30 -07007483 // make sure we report a value at least as big as our current rate
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07007484 if (((maxRate < myRate) && (0 == rssidx)) ||
7485 (0 == maxRate))
Jeff Johnson295189b2012-06-20 16:38:30 -07007486 {
7487 maxRate = myRate;
7488 if (rate_flags & eHAL_TX_RATE_LEGACY)
7489 {
7490 maxSpeedMCS = 0;
7491 }
7492 else
7493 {
7494 maxSpeedMCS = 1;
7495 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
7496 }
7497 }
7498
Gopichand Nakkala4c705372013-04-24 13:20:33 +05307499 if (rate_flags & eHAL_TX_RATE_LEGACY)
Jeff Johnson295189b2012-06-20 16:38:30 -07007500 {
7501 sinfo->txrate.legacy = maxRate;
7502#ifdef LINKSPEED_DEBUG_ENABLED
7503 pr_info("Reporting legacy rate %d\n", sinfo->txrate.legacy);
7504#endif //LINKSPEED_DEBUG_ENABLED
7505 }
7506 else
7507 {
7508 sinfo->txrate.mcs = maxMCSIdx;
Leo Chang6f8870f2013-03-26 18:11:36 -07007509#ifdef WLAN_FEATURE_11AC
7510 sinfo->txrate.nss = 1;
7511 if (rate_flags & eHAL_TX_RATE_VHT80)
7512 {
7513 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
Gopichand Nakkala4c705372013-04-24 13:20:33 +05307514 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
Leo Chang6f8870f2013-03-26 18:11:36 -07007515 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +05307516 else if (rate_flags & eHAL_TX_RATE_VHT40)
Leo Chang6f8870f2013-03-26 18:11:36 -07007517 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +05307518 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
7519 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
7520 }
7521 else if (rate_flags & eHAL_TX_RATE_VHT20)
7522 {
7523 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
7524 }
7525#endif /* WLAN_FEATURE_11AC */
7526 if (rate_flags & (eHAL_TX_RATE_HT20 | eHAL_TX_RATE_HT40))
7527 {
7528 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
7529 if (rate_flags & eHAL_TX_RATE_HT40)
7530 {
7531 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
7532 }
Leo Chang6f8870f2013-03-26 18:11:36 -07007533 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007534 if (rate_flags & eHAL_TX_RATE_SGI)
7535 {
7536 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
7537 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +05307538
Jeff Johnson295189b2012-06-20 16:38:30 -07007539#ifdef LINKSPEED_DEBUG_ENABLED
7540 pr_info("Reporting MCS rate %d flags %x\n",
7541 sinfo->txrate.mcs,
7542 sinfo->txrate.flags );
7543#endif //LINKSPEED_DEBUG_ENABLED
7544 }
7545 }
7546 else
7547 {
7548 // report current rate instead of max rate
7549
7550 if (rate_flags & eHAL_TX_RATE_LEGACY)
7551 {
7552 //provide to the UI in units of 100kbps
7553 sinfo->txrate.legacy = myRate;
7554#ifdef LINKSPEED_DEBUG_ENABLED
7555 pr_info("Reporting actual legacy rate %d\n", sinfo->txrate.legacy);
7556#endif //LINKSPEED_DEBUG_ENABLED
7557 }
7558 else
7559 {
7560 //must be MCS
7561 sinfo->txrate.mcs = pAdapter->hdd_stats.ClassA_stat.mcs_index;
Leo Chang6f8870f2013-03-26 18:11:36 -07007562#ifdef WLAN_FEATURE_11AC
7563 sinfo->txrate.nss = 1;
7564 if (rate_flags & eHAL_TX_RATE_VHT80)
7565 {
7566 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
7567 }
7568 else
7569#endif /* WLAN_FEATURE_11AC */
7570 {
7571 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
7572 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007573 if (rate_flags & eHAL_TX_RATE_SGI)
7574 {
7575 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
7576 }
7577 if (rate_flags & eHAL_TX_RATE_HT40)
7578 {
7579 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
7580 }
Leo Chang6f8870f2013-03-26 18:11:36 -07007581#ifdef WLAN_FEATURE_11AC
7582 else if (rate_flags & eHAL_TX_RATE_VHT80)
7583 {
7584 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
7585 }
7586#endif /* WLAN_FEATURE_11AC */
Jeff Johnson295189b2012-06-20 16:38:30 -07007587#ifdef LINKSPEED_DEBUG_ENABLED
7588 pr_info("Reporting actual MCS rate %d flags %x\n",
7589 sinfo->txrate.mcs,
7590 sinfo->txrate.flags );
7591#endif //LINKSPEED_DEBUG_ENABLED
7592 }
7593 }
7594 sinfo->filled |= STATION_INFO_TX_BITRATE;
7595
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -07007596 sinfo->tx_packets =
7597 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[0] +
7598 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[1] +
7599 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[2] +
7600 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[3];
7601
7602 sinfo->tx_retries =
7603 pAdapter->hdd_stats.summary_stat.retry_cnt[0] +
7604 pAdapter->hdd_stats.summary_stat.retry_cnt[1] +
7605 pAdapter->hdd_stats.summary_stat.retry_cnt[2] +
7606 pAdapter->hdd_stats.summary_stat.retry_cnt[3];
7607
7608 sinfo->tx_failed =
7609 pAdapter->hdd_stats.summary_stat.fail_cnt[0] +
7610 pAdapter->hdd_stats.summary_stat.fail_cnt[1] +
7611 pAdapter->hdd_stats.summary_stat.fail_cnt[2] +
7612 pAdapter->hdd_stats.summary_stat.fail_cnt[3];
7613
7614 sinfo->filled |=
7615 STATION_INFO_TX_PACKETS |
7616 STATION_INFO_TX_RETRIES |
7617 STATION_INFO_TX_FAILED;
7618
7619 EXIT();
7620 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07007621}
7622
7623static int wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
Sameer Thalappilc9f26e92013-06-07 10:11:06 -07007624 struct net_device *dev, bool mode, int timeout)
Jeff Johnson295189b2012-06-20 16:38:30 -07007625{
7626 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +05307627 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07007628 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307629 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07007630
Jeff Johnsone7245742012-09-05 17:12:55 -07007631 ENTER();
7632
Jeff Johnson295189b2012-06-20 16:38:30 -07007633 if (NULL == pAdapter)
7634 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08007635 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007636 return -ENODEV;
7637 }
7638
Gopichand Nakkala20c4c042013-04-19 22:08:55 +05307639 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307640 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +05307641
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307642 if (0 != status)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307643 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307644 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7645 "%s: HDD context is not valid", __func__);
7646 return status;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307647 }
7648
Gopichand Nakkala20c4c042013-04-19 22:08:55 +05307649 if ((DRIVER_POWER_MODE_AUTO == !mode) &&
7650 (TRUE == pHddCtx->hdd_wlan_suspended) &&
7651 (pHddCtx->cfg_ini->fhostArpOffload) &&
7652 (eConnectionState_Associated ==
7653 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
7654 {
Amar Singhald53568e2013-09-26 11:03:45 -07007655
7656 hddLog(VOS_TRACE_LEVEL_INFO,
7657 "offload: in cfg80211_set_power_mgmt, calling arp offload");
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05307658 vos_status = hdd_conf_arp_offload(pAdapter, TRUE);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +05307659 if (!VOS_IS_STATUS_SUCCESS(vos_status))
7660 {
7661 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007662 "%s:Failed to enable ARPOFFLOAD Feature %d",
Gopichand Nakkala20c4c042013-04-19 22:08:55 +05307663 __func__, vos_status);
7664 }
7665 }
7666
Jeff Johnson295189b2012-06-20 16:38:30 -07007667 /**The get power cmd from the supplicant gets updated by the nl only
7668 *on successful execution of the function call
7669 *we are oppositely mapped w.r.t mode in the driver
7670 **/
7671 vos_status = wlan_hdd_enter_bmps(pAdapter, !mode);
7672
Jeff Johnsone7245742012-09-05 17:12:55 -07007673 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07007674 if (VOS_STATUS_E_FAILURE == vos_status)
7675 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307676 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7677 "%s: failed to enter bmps mode", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007678 return -EINVAL;
7679 }
7680 return 0;
7681}
7682
7683
7684#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
7685static int wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
7686 struct net_device *netdev,
7687 u8 key_index)
7688{
Jeff Johnsone7245742012-09-05 17:12:55 -07007689 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07007690 return 0;
7691}
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307692#endif //LINUX_VERSION_CODE
Jeff Johnson295189b2012-06-20 16:38:30 -07007693
7694#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
7695static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
7696 struct net_device *dev,
7697 struct ieee80211_txq_params *params)
7698{
Jeff Johnsone7245742012-09-05 17:12:55 -07007699 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07007700 return 0;
7701}
7702#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
7703static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
7704 struct ieee80211_txq_params *params)
7705{
Jeff Johnsone7245742012-09-05 17:12:55 -07007706 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07007707 return 0;
7708}
7709#endif //LINUX_VERSION_CODE
7710
7711static int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
7712 struct net_device *dev, u8 *mac)
7713{
7714 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307715 hdd_context_t *pHddCtx;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08007716 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307717 int status;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08007718 v_U8_t staId;
Jeff Johnson295189b2012-06-20 16:38:30 -07007719
Jeff Johnsone7245742012-09-05 17:12:55 -07007720 ENTER();
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307721 if ( NULL == pAdapter )
Jeff Johnson295189b2012-06-20 16:38:30 -07007722 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307723 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007724 return -EINVAL;
7725 }
7726
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307727 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7728 status = wlan_hdd_validate_context(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07007729
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307730 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007731 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307732 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7733 "%s: HDD context is not valid", __func__);
7734 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007735 }
7736
Jeff Johnson295189b2012-06-20 16:38:30 -07007737 if ( (WLAN_HDD_SOFTAP == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -07007738 || (WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -07007739 )
7740 {
7741 if( NULL == mac )
7742 {
7743 v_U16_t i;
7744 for(i = 0; i < WLAN_MAX_STA_COUNT; i++)
7745 {
Rajesh Chauhan18488fc2013-08-22 10:15:03 -07007746 if ((pAdapter->aStaInfo[i].isUsed) &&
7747 (!pAdapter->aStaInfo[i].isDeauthInProgress))
Jeff Johnson295189b2012-06-20 16:38:30 -07007748 {
7749 u8 *macAddr = pAdapter->aStaInfo[i].macAddrSTA.bytes;
7750 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -08007751 "%s: Delete STA with MAC::"
7752 MAC_ADDRESS_STR,
7753 __func__, MAC_ADDR_ARRAY(macAddr));
Rajesh Chauhan18488fc2013-08-22 10:15:03 -07007754 vos_status = hdd_softap_sta_deauth(pAdapter, macAddr);
7755 if (VOS_IS_STATUS_SUCCESS(vos_status))
7756 pAdapter->aStaInfo[i].isDeauthInProgress = TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -07007757 }
7758 }
7759 }
7760 else
7761 {
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08007762
7763 vos_status = hdd_softap_GetStaId(pAdapter,(v_MACADDR_t *)mac, &staId);
7764 if (!VOS_IS_STATUS_SUCCESS(vos_status))
7765 {
7766 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -08007767 "%s: Skip this DEL STA as this is not used::"
7768 MAC_ADDRESS_STR,
7769 __func__, MAC_ADDR_ARRAY(mac));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08007770 return -ENOENT;
7771 }
7772
7773 if( pAdapter->aStaInfo[staId].isDeauthInProgress == TRUE)
7774 {
7775 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -08007776 "%s: Skip this DEL STA as deauth is in progress::"
7777 MAC_ADDRESS_STR,
7778 __func__, MAC_ADDR_ARRAY(mac));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08007779 return -ENOENT;
7780 }
7781
7782 pAdapter->aStaInfo[staId].isDeauthInProgress = TRUE;
7783
Jeff Johnson295189b2012-06-20 16:38:30 -07007784 hddLog(VOS_TRACE_LEVEL_INFO,
7785 "%s: Delete STA with MAC::"
Arif Hussain24bafea2013-11-15 15:10:03 -08007786 MAC_ADDRESS_STR,
Jeff Johnson295189b2012-06-20 16:38:30 -07007787 __func__,
Arif Hussain24bafea2013-11-15 15:10:03 -08007788 MAC_ADDR_ARRAY(mac));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08007789
7790 vos_status = hdd_softap_sta_deauth(pAdapter, mac);
7791 if (!VOS_IS_STATUS_SUCCESS(vos_status))
7792 {
7793 pAdapter->aStaInfo[staId].isDeauthInProgress = FALSE;
7794 hddLog(VOS_TRACE_LEVEL_INFO,
7795 "%s: STA removal failed for ::"
Arif Hussain24bafea2013-11-15 15:10:03 -08007796 MAC_ADDRESS_STR,
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08007797 __func__,
Arif Hussain24bafea2013-11-15 15:10:03 -08007798 MAC_ADDR_ARRAY(mac));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08007799 return -ENOENT;
7800 }
7801
Jeff Johnson295189b2012-06-20 16:38:30 -07007802 }
7803 }
7804
7805 EXIT();
7806
7807 return 0;
7808}
7809
Hoonki Lee11f7dda2013-02-14 16:55:44 -08007810static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
7811 struct net_device *dev, u8 *mac, struct station_parameters *params)
7812{
Gopichand Nakkalab977a972013-02-18 19:15:09 -08007813 int status = -EPERM;
Hoonki Lee11f7dda2013-02-14 16:55:44 -08007814#ifdef FEATURE_WLAN_TDLS
7815 u32 mask, set;
Hoonki Lee11f7dda2013-02-14 16:55:44 -08007816 ENTER();
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007817 mask = params->sta_flags_mask;
7818
7819 set = params->sta_flags_set;
7820
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007821#ifdef WLAN_FEATURE_TDLS_DEBUG
7822 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7823 "%s: mask 0x%x set 0x%x " MAC_ADDRESS_STR,
7824 __func__, mask, set, MAC_ADDR_ARRAY(mac));
7825#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007826
7827 if (mask & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
7828 if (set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007829 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 0, NULL);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007830 }
7831 }
7832#endif
Gopichand Nakkalab977a972013-02-18 19:15:09 -08007833 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -07007834}
7835
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007836
7837#ifdef FEATURE_WLAN_LFR
Wilson Yang6507c4e2013-10-01 20:11:19 -07007838#define MAX_PMKSAIDS_IN_CACHE 8
7839
7840static tPmkidCacheInfo PMKIDCache[MAX_PMKSAIDS_IN_CACHE]; // HDD local cache
7841static tANI_U32 PMKIDCacheIndex; // HDD local Cache index
7842
7843
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007844static int wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
Jeff Johnsond13512a2012-07-17 11:42:19 -07007845 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007846{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307847 tANI_U32 j=0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007848 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
7849 tHalHandle halHandle;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307850 eHalStatus result;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307851 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007852 tANI_U8 BSSIDMatched = 0;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307853 hdd_context_t *pHddCtx;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307854
Jeff Johnson0299d0a2013-10-30 12:37:43 -07007855 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: set PMKSA for " MAC_ADDRESS_STR,
7856 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
Jeff Johnsone7245742012-09-05 17:12:55 -07007857
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307858 // Validate pAdapter
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307859 if ( NULL == pAdapter )
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007860 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307861 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007862 return -EINVAL;
7863 }
7864
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307865 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7866 status = wlan_hdd_validate_context(pHddCtx);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007867
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307868 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007869 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307870 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7871 "%s: HDD context is not valid", __func__);
7872 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007873 }
7874
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307875 // Retrieve halHandle
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007876 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
7877
Wilson Yang6507c4e2013-10-01 20:11:19 -07007878 for (j = 0; j < PMKIDCacheIndex; j++)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007879 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307880 if(vos_mem_compare(PMKIDCache[j].BSSID,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007881 pmksa->bssid, WNI_CFG_BSSID_LEN))
7882 {
7883 /* BSSID matched previous entry. Overwrite it. */
7884 BSSIDMatched = 1;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307885 vos_mem_copy(PMKIDCache[j].BSSID,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007886 pmksa->bssid, WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307887 vos_mem_copy(PMKIDCache[j].PMKID,
7888 pmksa->pmkid,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007889 CSR_RSN_PMKID_SIZE);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307890 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Reusing cache entry %d.",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007891 __func__, j );
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007892 dump_bssid(pmksa->bssid);
7893 dump_pmkid(halHandle, pmksa->pmkid);
7894 break;
7895 }
7896 }
7897
Madan Mohan Koyyalamudic4b317d2012-10-18 19:43:08 -07007898 /* Check we compared all entries,if then take the first slot now */
Wilson Yang6507c4e2013-10-01 20:11:19 -07007899 if(j == MAX_PMKSAIDS_IN_CACHE) PMKIDCacheIndex=0;
Madan Mohan Koyyalamudic4b317d2012-10-18 19:43:08 -07007900
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007901 if (!BSSIDMatched)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307902 {
7903 // Now, we DON'T have a BSSID match, so take a new entry in the cache.
Wilson Yang6507c4e2013-10-01 20:11:19 -07007904 vos_mem_copy(PMKIDCache[PMKIDCacheIndex].BSSID,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307905 pmksa->bssid, ETHER_ADDR_LEN);
Wilson Yang6507c4e2013-10-01 20:11:19 -07007906 vos_mem_copy(PMKIDCache[PMKIDCacheIndex].PMKID,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307907 pmksa->pmkid,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007908 CSR_RSN_PMKID_SIZE);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307909 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Adding a new cache entry %d.",
Wilson Yang6507c4e2013-10-01 20:11:19 -07007910 __func__, PMKIDCacheIndex );
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007911 dump_bssid(pmksa->bssid);
7912 dump_pmkid(halHandle, pmksa->pmkid);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307913 // Increment the HDD Local Cache index
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007914 // The "i=0" doesn't work for the call to sme_RoamSetPMKIDCache() - LFR FIXME
Wilson Yang6507c4e2013-10-01 20:11:19 -07007915 if (PMKIDCacheIndex <= (MAX_PMKSAIDS_IN_CACHE-1)) PMKIDCacheIndex++; else PMKIDCacheIndex = 0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007916 }
7917
7918
7919 // Calling csrRoamSetPMKIDCache to configure the PMKIDs into the cache
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307920 //hddLog(LOG1, FL("%s: Calling csrRoamSetPMKIDCache with %d cache entries."),
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007921 // __func__, i );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307922 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Calling csrRoamSetPMKIDCache with %d cache entries.",
Wilson Yang6507c4e2013-10-01 20:11:19 -07007923 __func__, PMKIDCacheIndex );
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007924 // Finally set the PMKSA ID Cache in CSR
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307925 result = sme_RoamSetPMKIDCache(halHandle,pAdapter->sessionId,
7926 PMKIDCache,
Wilson Yang6507c4e2013-10-01 20:11:19 -07007927 PMKIDCacheIndex);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007928 return 0;
7929}
7930
7931
Wilson Yang6507c4e2013-10-01 20:11:19 -07007932
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007933static int wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
Wilson Yang6507c4e2013-10-01 20:11:19 -07007934 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007935{
Wilson Yang6507c4e2013-10-01 20:11:19 -07007936 tANI_U32 j=0;
7937 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
7938 tHalHandle halHandle;
Wilson Yang6507c4e2013-10-01 20:11:19 -07007939 tANI_U8 BSSIDMatched = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -07007940 hdd_context_t *pHddCtx;
Wilson Yangef657d32014-01-15 19:19:23 -08007941 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -07007942
Jeff Johnson0299d0a2013-10-30 12:37:43 -07007943 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: deleting PMKSA for " MAC_ADDRESS_STR,
7944 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
Wilson Yang6507c4e2013-10-01 20:11:19 -07007945
7946 /* Validate pAdapter */
7947 if (NULL == pAdapter)
7948 {
7949 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
7950 return -EINVAL;
7951 }
7952
7953 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7954 status = wlan_hdd_validate_context(pHddCtx);
7955
7956 if (0 != status)
7957 {
7958 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7959 "%s: HDD context is not valid", __func__);
7960 return status;
7961 }
7962
7963 /*Retrieve halHandle*/
7964 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
7965
7966 /*in case index is 0,no entry to delete*/
7967 if (0 == PMKIDCacheIndex)
7968 {
7969 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid entry to delete" ,
7970 __func__);
7971 return -EINVAL;
7972 }
7973
7974 /*find the matching PMKSA entry from j=0 to (index-1),
7975 * and delete the matched one
7976 */
7977 for (j = 0; j<PMKIDCacheIndex; j++)
7978 {
7979 if (vos_mem_compare(PMKIDCache[j].BSSID,
7980 pmksa->bssid,
7981 WNI_CFG_BSSID_LEN))
7982 {
7983 /* BSSID matched entry */
7984 BSSIDMatched = 1;
7985
7986 if (j<PMKIDCacheIndex-1)
7987 {
7988 /*replace the matching entry with the last entry in HDD local cache*/
7989 vos_mem_copy(PMKIDCache[j].BSSID,
7990 PMKIDCache[PMKIDCacheIndex-1].BSSID,
7991 WNI_CFG_BSSID_LEN);
7992 vos_mem_copy(PMKIDCache[j].PMKID,
7993 PMKIDCache[PMKIDCacheIndex-1].PMKID,
7994 CSR_RSN_PMKID_SIZE);
7995 }
7996
7997 /*clear the last entry in HDD cache ---[index-1]*/
Wilson Yang6507c4e2013-10-01 20:11:19 -07007998 vos_mem_zero(PMKIDCache[PMKIDCacheIndex-1].BSSID, WNI_CFG_BSSID_LEN);
7999 vos_mem_zero(PMKIDCache[PMKIDCacheIndex-1].PMKID, CSR_RSN_PMKID_SIZE);
8000
8001 /*reduce the PMKID array index*/
8002 PMKIDCacheIndex--;
8003
8004 /*delete the last PMKID cache in CSR*/
Wilson Yangef657d32014-01-15 19:19:23 -08008005 if (eHAL_STATUS_SUCCESS !=
8006 sme_RoamDelPMKIDfromCache(halHandle, pAdapter->sessionId, pmksa->bssid))
Wilson Yang6507c4e2013-10-01 20:11:19 -07008007 {
8008 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: cannot delete PMKSA %d CONTENT.",
8009 __func__,PMKIDCacheIndex);
Wilson Yangef657d32014-01-15 19:19:23 -08008010 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -07008011 }
8012
8013 dump_bssid(pmksa->bssid);
8014 dump_pmkid(halHandle,pmksa->pmkid);
8015
8016 break;
8017 }
8018 }
8019
8020 /* we compare all entries,but cannot find matching entry */
8021 if (j == MAX_PMKSAIDS_IN_CACHE && !BSSIDMatched)
8022 {
Jeff Johnson0299d0a2013-10-30 12:37:43 -07008023 hddLog(VOS_TRACE_LEVEL_FATAL,
8024 "%s: No such PMKSA entry existed " MAC_ADDRESS_STR,
8025 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
Wilson Yang6507c4e2013-10-01 20:11:19 -07008026 dump_bssid(pmksa->bssid);
8027 dump_pmkid(halHandle, pmksa->pmkid);
8028 return -EINVAL;
8029 }
Wilson Yangef657d32014-01-15 19:19:23 -08008030 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008031}
8032
Wilson Yang6507c4e2013-10-01 20:11:19 -07008033
8034
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008035static int wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
8036{
Wilson Yang6507c4e2013-10-01 20:11:19 -07008037 tANI_U32 j=0;
8038 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
8039 tHalHandle halHandle;
8040 hdd_context_t *pHddCtx;
8041 tANI_U8 *pBSSId;
Wilson Yangef657d32014-01-15 19:19:23 -08008042 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -07008043
8044 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: flushing PMKSA ",__func__);
8045
8046 /* Validate pAdapter */
8047 if (NULL == pAdapter)
8048 {
8049 hddLog(VOS_TRACE_LEVEL_ERROR,
8050 "%s: Invalid Adapter" ,__func__);
8051 return -EINVAL;
8052 }
8053
8054 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8055 status = wlan_hdd_validate_context(pHddCtx);
8056
8057 if (0 != status)
8058 {
8059 hddLog(VOS_TRACE_LEVEL_ERROR,
8060 "%s: HDD context is not valid", __func__);
8061 return status;
8062 }
8063
8064 /*Retrieve halHandle*/
8065 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
8066
8067 /*in case index is 0,no entry to delete*/
8068 if (0 == PMKIDCacheIndex)
8069 {
8070 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid entry to delete" ,
8071 __func__);
8072 return -EINVAL;
8073 }
8074
8075 /*delete all the PMKSA one by one */
8076 for (j = 0; j<PMKIDCacheIndex; j++)
8077 {
Wilson Yang6507c4e2013-10-01 20:11:19 -07008078 pBSSId =(tANI_U8 *)(PMKIDCache[j].BSSID);
Wilson Yang6507c4e2013-10-01 20:11:19 -07008079
8080 /*delete the PMKID in CSR*/
Wilson Yangef657d32014-01-15 19:19:23 -08008081 if (eHAL_STATUS_SUCCESS !=
8082 sme_RoamDelPMKIDfromCache(halHandle, pAdapter->sessionId, pBSSId))
Wilson Yang6507c4e2013-10-01 20:11:19 -07008083 {
8084 hddLog(VOS_TRACE_LEVEL_ERROR ,"%s cannot flush PMKIDCache %d.",
8085 __func__,j);
Wilson Yangef657d32014-01-15 19:19:23 -08008086 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -07008087 }
Kiet Lam8d21d5b2013-10-31 17:18:29 +05308088 /*clear the entry in HDD cache 0--index-1 */
8089 vos_mem_zero(PMKIDCache[j].BSSID, WNI_CFG_BSSID_LEN);
8090 vos_mem_zero(PMKIDCache[j].PMKID, CSR_RSN_PMKID_SIZE);
Wilson Yang6507c4e2013-10-01 20:11:19 -07008091 }
8092
8093 PMKIDCacheIndex = 0;
Wilson Yangef657d32014-01-15 19:19:23 -08008094 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008095}
8096#endif
8097
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07008098#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308099static int wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07008100 struct net_device *dev, struct cfg80211_update_ft_ies_params *ftie)
8101{
8102 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
8103 hdd_station_ctx_t *pHddStaCtx;
8104
8105 if (NULL == pAdapter)
8106 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08008107 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07008108 return -ENODEV;
8109 }
8110
8111 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
8112
8113 // Added for debug on reception of Re-assoc Req.
8114 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
8115 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08008116 hddLog(LOGE, FL("Called with Ie of length = %zu when not associated"),
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07008117 ftie->ie_len);
Arif Hussain6d2a3322013-11-17 19:50:10 -08008118 hddLog(LOGE, FL("Should be Re-assoc Req IEs"));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07008119 }
8120
8121#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG
Arif Hussain6d2a3322013-11-17 19:50:10 -08008122 hddLog(LOGE, FL("%s called with Ie of length = %zu"), __func__,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07008123 ftie->ie_len);
8124#endif
8125
8126 // Pass the received FT IEs to SME
Gopichand Nakkala356fb102013-03-06 12:34:04 +05308127 sme_SetFTIEs( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
8128 (const u8 *)ftie->ie,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07008129 ftie->ie_len);
8130 return 0;
8131}
8132#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008133
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308134#ifdef FEATURE_WLAN_SCAN_PNO
8135
8136void hdd_cfg80211_sched_scan_done_callback(void *callbackContext,
8137 tSirPrefNetworkFoundInd *pPrefNetworkFoundInd)
8138{
8139 int ret;
8140 hdd_adapter_t* pAdapter = (hdd_adapter_t*)callbackContext;
8141 hdd_context_t *pHddCtx;
8142
Nirav Shah80830bf2013-12-31 16:35:12 +05308143 ENTER();
8144
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308145 if (NULL == pAdapter)
8146 {
Agarwal Ashish971c2882013-10-30 20:11:12 +05308147 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308148 "%s: HDD adapter is Null", __func__);
8149 return ;
8150 }
8151
8152 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8153 if (NULL == pHddCtx)
8154 {
8155 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8156 "%s: HDD context is Null!!!", __func__);
8157 return ;
8158 }
8159
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05308160 spin_lock(&pHddCtx->schedScan_lock);
8161 if (TRUE == pHddCtx->isWiphySuspended)
8162 {
8163 pHddCtx->isSchedScanUpdatePending = TRUE;
8164 spin_unlock(&pHddCtx->schedScan_lock);
8165 hddLog(VOS_TRACE_LEVEL_INFO,
8166 "%s: Update cfg80211 scan database after it resume", __func__);
8167 return ;
8168 }
8169 spin_unlock(&pHddCtx->schedScan_lock);
8170
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308171 ret = wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter);
8172
8173 if (0 > ret)
8174 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
8175
8176 cfg80211_sched_scan_results(pHddCtx->wiphy);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05308177 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8178 "%s: cfg80211 scan result database updated", __func__);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308179}
8180
8181/*
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +05308182 * FUNCTION: wlan_hdd_is_pno_allowed
8183 * To check is there any P2P GO/SAP or P2P Client/STA
8184 * session is active
8185 */
8186static eHalStatus wlan_hdd_is_pno_allowed(hdd_adapter_t *pAdapter)
8187{
8188 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
8189 hdd_adapter_t *pTempAdapter = NULL;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +05308190 hdd_station_ctx_t *pStaCtx;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +05308191 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8192 int status = 0;
8193 status = hdd_get_front_adapter(pHddCtx, &pAdapterNode);
8194
8195 while ((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status))
8196 {
8197 pTempAdapter = pAdapterNode->pAdapter;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +05308198 pStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pTempAdapter);
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +05308199
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +05308200 if (((WLAN_HDD_INFRA_STATION == pTempAdapter->device_mode)
8201 && (eConnectionState_NotConnected != pStaCtx->conn_info.connState))
8202 || (WLAN_HDD_P2P_CLIENT == pTempAdapter->device_mode)
8203 || (WLAN_HDD_P2P_GO == pTempAdapter->device_mode)
8204 || (WLAN_HDD_SOFTAP == pTempAdapter->device_mode)
8205 )
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +05308206 {
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +05308207 return eHAL_STATUS_FAILURE;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +05308208 }
8209 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
8210 pAdapterNode = pNext;
8211 }
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +05308212 return eHAL_STATUS_SUCCESS;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +05308213}
8214
8215/*
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308216 * FUNCTION: wlan_hdd_cfg80211_sched_scan_start
8217 * NL interface to enable PNO
8218 */
8219static int wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
8220 struct net_device *dev, struct cfg80211_sched_scan_request *request)
8221{
8222 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
8223 tpSirPNOScanReq pPnoRequest = NULL;
8224 hdd_context_t *pHddCtx;
8225 tHalHandle hHal;
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +05308226 v_U32_t i, indx, num_ch, tempInterval;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308227 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN];
8228 u8 channels_allowed[WNI_CFG_VALID_CHANNEL_LIST_LEN];
8229 v_U32_t num_channels_allowed = WNI_CFG_VALID_CHANNEL_LIST_LEN;
8230 eHalStatus status = eHAL_STATUS_FAILURE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308231 int ret = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308232
8233 if (NULL == pAdapter)
8234 {
8235 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
8236 "%s: HDD adapter is Null", __func__);
8237 return -ENODEV;
8238 }
8239
8240 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05308241 ret = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308242
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05308243 if (0 != ret)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308244 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05308245 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8246 "%s: HDD context is not valid", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308247 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308248 }
8249
8250 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
8251 if (NULL == hHal)
8252 {
8253 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8254 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05308255 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308256 }
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +05308257
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +05308258 /* The current firmware design for PNO does not consider concurrent
8259 * active sessions.Hence , determine the concurrent active sessions
8260 * and return a failure to the framework on a request for schedule
8261 * scan.
8262 */
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +05308263 if (eHAL_STATUS_SUCCESS != wlan_hdd_is_pno_allowed(pAdapter))
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +05308264 {
8265 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +05308266 FL("Cannot handle sched_scan"));
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +05308267 return -EBUSY;
8268 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308269
8270 pPnoRequest = (tpSirPNOScanReq) vos_mem_malloc(sizeof (tSirPNOScanReq));
8271 if (NULL == pPnoRequest)
8272 {
8273 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
8274 "%s: vos_mem_malloc failed", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308275 return -ENOMEM;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308276 }
8277
Madan Mohan Koyyalamudic3f04352013-09-26 19:21:48 +05308278 memset(pPnoRequest, 0, sizeof (tSirPNOScanReq));
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308279 pPnoRequest->enable = 1; /*Enable PNO */
8280 pPnoRequest->ucNetworksCount = request->n_match_sets;
8281
8282 if (( !pPnoRequest->ucNetworksCount ) ||
8283 ( pPnoRequest->ucNetworksCount > SIR_PNO_MAX_SUPP_NETWORKS ))
8284 {
8285 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +05308286 "%s: Network input is not correct %d",
8287 __func__, pPnoRequest->ucNetworksCount);
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308288 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308289 goto error;
8290 }
8291
8292 if ( SIR_PNO_MAX_NETW_CHANNELS_EX < request->n_channels )
8293 {
8294 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +05308295 "%s: Incorrect number of channels %d",
8296 __func__, request->n_channels);
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308297 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308298 goto error;
8299 }
8300
8301 /* Framework provides one set of channels(all)
8302 * common for all saved profile */
8303 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
8304 channels_allowed, &num_channels_allowed))
8305 {
8306 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8307 "%s: failed to get valid channel list", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308308 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308309 goto error;
8310 }
8311 /* Checking each channel against allowed channel list */
8312 num_ch = 0;
Nirav Shah80830bf2013-12-31 16:35:12 +05308313 if (request->n_channels)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308314 {
Nirav Shah80830bf2013-12-31 16:35:12 +05308315 char chList [(request->n_channels*5)+1];
8316 int len;
8317 for (i = 0, len = 0; i < request->n_channels; i++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308318 {
Nirav Shah80830bf2013-12-31 16:35:12 +05308319 for (indx = 0; indx < num_channels_allowed; indx++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308320 {
Nirav Shah80830bf2013-12-31 16:35:12 +05308321 if (request->channels[i]->hw_value == channels_allowed[indx])
8322 {
8323 valid_ch[num_ch++] = request->channels[i]->hw_value;
8324 len += snprintf(chList+len, 5, "%d ",
8325 request->channels[i]->hw_value);
8326 break ;
8327 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308328 }
8329 }
Nirav Shah80830bf2013-12-31 16:35:12 +05308330 hddLog(VOS_TRACE_LEVEL_INFO,"Channel-List: %s ", chList);
8331 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308332
8333 /* Filling per profile params */
8334 for (i = 0; i < pPnoRequest->ucNetworksCount; i++)
8335 {
8336 pPnoRequest->aNetworks[i].ssId.length =
8337 request->match_sets[i].ssid.ssid_len;
8338
8339 if (( 0 == pPnoRequest->aNetworks[i].ssId.length ) ||
8340 ( pPnoRequest->aNetworks[i].ssId.length > 32 ) )
8341 {
8342 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +05308343 "%s: SSID Len %d is not correct for network %d",
8344 __func__, pPnoRequest->aNetworks[i].ssId.length, i);
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308345 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308346 goto error;
8347 }
8348
8349 memcpy(pPnoRequest->aNetworks[i].ssId.ssId,
8350 request->match_sets[i].ssid.ssid,
8351 request->match_sets[i].ssid.ssid_len);
8352 pPnoRequest->aNetworks[i].authentication = 0; /*eAUTH_TYPE_ANY*/
8353 pPnoRequest->aNetworks[i].encryption = 0; /*eED_ANY*/
8354 pPnoRequest->aNetworks[i].bcastNetwType = 0; /*eBCAST_UNKNOWN*/
8355
8356 /*Copying list of valid channel into request */
8357 memcpy(pPnoRequest->aNetworks[i].aChannels, valid_ch, num_ch);
8358 pPnoRequest->aNetworks[i].ucChannelCount = num_ch;
8359
8360 pPnoRequest->aNetworks[i].rssiThreshold = 0; //Default value
8361 }
8362
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +05308363 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnson59a121e2013-11-30 09:46:08 -08008364 "request->ie_len = %zu", request->ie_len);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +05308365 if ((0 < request->ie_len) && (NULL != request->ie))
8366 {
8367 pPnoRequest->us24GProbeTemplateLen = request->ie_len;
8368 memcpy(&pPnoRequest->p24GProbeTemplate, request->ie,
8369 pPnoRequest->us24GProbeTemplateLen);
8370
8371 pPnoRequest->us5GProbeTemplateLen = request->ie_len;
8372 memcpy(&pPnoRequest->p5GProbeTemplate, request->ie,
8373 pPnoRequest->us5GProbeTemplateLen);
8374 }
8375
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +05308376 /* Driver gets only one time interval which is hardcoded in
8377 * supplicant for 10000ms. Taking power consumption into account 6 timers
8378 * will be used, Timervalue is increased exponentially i.e 10,20,40,
8379 * 80,160,320 secs. And number of scan cycle for each timer
8380 * is configurable through INI param gPNOScanTimerRepeatValue.
8381 * If it is set to 0 only one timer will be used and PNO scan cycle
8382 * will be repeated after each interval specified by supplicant
8383 * till PNO is disabled.
8384 */
8385 if (0 == pHddCtx->cfg_ini->configPNOScanTimerRepeatValue)
8386 pPnoRequest->scanTimers.ucScanTimersCount = HDD_PNO_SCAN_TIMERS_SET_ONE;
8387 else
8388 pPnoRequest->scanTimers.ucScanTimersCount =
8389 HDD_PNO_SCAN_TIMERS_SET_MULTIPLE;
8390
8391 tempInterval = (request->interval)/1000;
8392 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8393 "Base scan interval = %d PNOScanTimerRepeatValue = %d",
8394 tempInterval, pHddCtx->cfg_ini->configPNOScanTimerRepeatValue);
8395 for ( i = 0; i < pPnoRequest->scanTimers.ucScanTimersCount; i++)
8396 {
8397 pPnoRequest->scanTimers.aTimerValues[i].uTimerRepeat =
8398 pHddCtx->cfg_ini->configPNOScanTimerRepeatValue;
8399 pPnoRequest->scanTimers.aTimerValues[i].uTimerValue = tempInterval;
8400 tempInterval *= 2;
8401 }
8402 //Repeat last timer until pno disabled.
8403 pPnoRequest->scanTimers.aTimerValues[i-1].uTimerRepeat = 0;
8404
Madan Mohan Koyyalamudid206c7b2013-09-26 22:54:51 +05308405 pPnoRequest->modePNO = SIR_PNO_MODE_IMMEDIATE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308406
Nirav Shah80830bf2013-12-31 16:35:12 +05308407 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8408 "SessionId %d, enable %d, modePNO %d, ucScanTimersCount %d",
8409 pAdapter->sessionId, pPnoRequest->enable, pPnoRequest->modePNO,
8410 pPnoRequest->scanTimers.ucScanTimersCount);
8411
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308412 status = sme_SetPreferredNetworkList(WLAN_HDD_GET_HAL_CTX(pAdapter),
8413 pPnoRequest, pAdapter->sessionId,
8414 hdd_cfg80211_sched_scan_done_callback, pAdapter);
8415 if (eHAL_STATUS_SUCCESS != status)
8416 {
8417 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +05308418 "%s: Failed to enable PNO", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308419 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308420 goto error;
8421 }
8422
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05308423 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8424 "PNO scanRequest offloaded");
8425
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308426error:
8427 vos_mem_free(pPnoRequest);
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308428 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308429}
8430
8431/*
8432 * FUNCTION: wlan_hdd_cfg80211_sched_scan_stop
8433 * NL interface to disable PNO
8434 */
8435static int wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
8436 struct net_device *dev)
8437{
8438 eHalStatus status = eHAL_STATUS_FAILURE;
8439 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
8440 hdd_context_t *pHddCtx;
8441 tHalHandle hHal;
8442 tpSirPNOScanReq pPnoRequest = NULL;
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308443 int ret = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308444
8445 ENTER();
8446
8447 if (NULL == pAdapter)
8448 {
8449 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
8450 "%s: HDD adapter is Null", __func__);
8451 return -ENODEV;
8452 }
8453
8454 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308455
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308456 if (NULL == pHddCtx)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308457 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05308458 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308459 "%s: HDD context is Null", __func__);
8460 return -ENODEV;
8461 }
8462
8463 /* The return 0 is intentional when isLogpInProgress and
8464 * isLoadUnloadInProgress. We did observe a crash due to a return of
8465 * failure in sched_scan_stop , especially for a case where the unload
8466 * of the happens at the same time. The function __cfg80211_stop_sched_scan
8467 * was clearing rdev->sched_scan_req only when the sched_scan_stop returns
8468 * success. If it returns a failure , then its next invocation due to the
8469 * clean up of the second interface will have the dev pointer corresponding
8470 * to the first one leading to a crash.
8471 */
8472 if (pHddCtx->isLogpInProgress)
8473 {
8474 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8475 "%s: LOGP in Progress. Ignore!!!", __func__);
8476 return ret;
8477 }
8478
8479 if (pHddCtx->isLoadUnloadInProgress)
8480 {
8481 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8482 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
8483 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308484 }
8485
8486 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
8487 if (NULL == hHal)
8488 {
8489 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8490 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05308491 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308492 }
8493
8494 pPnoRequest = (tpSirPNOScanReq) vos_mem_malloc(sizeof (tSirPNOScanReq));
8495 if (NULL == pPnoRequest)
8496 {
8497 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
8498 "%s: vos_mem_malloc failed", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308499 return -ENOMEM;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308500 }
8501
8502 memset(pPnoRequest, 0, sizeof (tSirPNOScanReq));
8503 pPnoRequest->enable = 0; /* Disable PNO */
8504 pPnoRequest->ucNetworksCount = 0;
8505
8506 status = sme_SetPreferredNetworkList(hHal, pPnoRequest,
8507 pAdapter->sessionId,
8508 NULL, pAdapter);
8509 if (eHAL_STATUS_SUCCESS != status)
8510 {
8511 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8512 "Failed to disabled PNO");
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308513 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308514 }
8515
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05308516 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8517 "%s: PNO scan disabled", __func__);
8518
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308519 vos_mem_free(pPnoRequest);
8520
8521 EXIT();
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308522 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308523}
8524
8525#endif /*FEATURE_WLAN_SCAN_PNO*/
8526
8527
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008528#ifdef FEATURE_WLAN_TDLS
8529static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
8530 u8 *peer, u8 action_code, u8 dialog_token,
8531 u16 status_code, const u8 *buf, size_t len)
8532{
8533
8534 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
8535 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008536 u8 peerMac[6];
8537 VOS_STATUS status;
Gopichand Nakkala05922802013-03-14 12:23:19 -07008538 int max_sta_failed = 0;
Hoonki Leea34dd892013-02-05 22:56:02 -08008539 int responder;
Hoonki Leed37cbb32013-04-20 00:31:14 -07008540 long rc;
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008541
Hoonki Lee11f7dda2013-02-14 16:55:44 -08008542 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008543 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308544 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008545 "Invalid arguments");
8546 return -EINVAL;
8547 }
8548
Sameer Thalappil75ea31a2013-02-21 19:38:16 -08008549 if (pHddCtx->isLogpInProgress)
8550 {
8551 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8552 "%s:LOGP in Progress. Ignore!!!", __func__);
Gopichand Nakkala05922802013-03-14 12:23:19 -07008553 wlan_hdd_tdls_set_link_status(pAdapter, peer, eTDLS_LINK_IDLE);
Sameer Thalappil75ea31a2013-02-21 19:38:16 -08008554 return -EBUSY;
8555 }
8556
Hoonki Lee27511902013-03-14 18:19:06 -07008557 if (eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode)
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008558 {
Hoonki Lee27511902013-03-14 18:19:06 -07008559 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
8560 "%s: TDLS mode is disabled OR not enabled in FW."
8561 MAC_ADDRESS_STR " action %d declined.",
8562 __func__, MAC_ADDR_ARRAY(peer), action_code);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008563 return -ENOTSUPP;
8564 }
Lee Hoonkic1262f22013-01-24 21:59:00 -08008565
Hoonki Lee27511902013-03-14 18:19:06 -07008566 /* other than teardown frame, other mgmt frames are not sent if disabled */
8567 if (SIR_MAC_TDLS_TEARDOWN != action_code)
8568 {
8569 /* if tdls_mode is disabled to respond to peer's request */
8570 if (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode)
8571 {
8572 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
8573 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07008574 " TDLS mode is disabled. action %d declined.",
8575 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee27511902013-03-14 18:19:06 -07008576
8577 return -ENOTSUPP;
8578 }
8579 }
8580
Gopichand Nakkalab977a972013-02-18 19:15:09 -08008581 if (WLAN_IS_TDLS_SETUP_ACTION(action_code))
8582 {
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308583 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, peer, TRUE))
Gopichand Nakkalab977a972013-02-18 19:15:09 -08008584 {
8585 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07008586 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07008587 " TDLS setup is ongoing. action %d declined.",
8588 __func__, MAC_ADDR_ARRAY(peer), action_code);
8589 return -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -08008590 }
8591 }
8592
Hoonki Lee11f7dda2013-02-14 16:55:44 -08008593 if (SIR_MAC_TDLS_SETUP_REQ == action_code ||
8594 SIR_MAC_TDLS_SETUP_RSP == action_code )
Lee Hoonkic1262f22013-01-24 21:59:00 -08008595 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -08008596 if (HDD_MAX_NUM_TDLS_STA <= wlan_hdd_tdlsConnectedPeers(pAdapter))
Lee Hoonkic1262f22013-01-24 21:59:00 -08008597 {
8598 /* supplicant still sends tdls_mgmt(SETUP_REQ) even after
8599 we return error code at 'add_station()'. Hence we have this
8600 check again in addtion to add_station().
8601 Anyway, there is no hard to double-check. */
Hoonki Lee11f7dda2013-02-14 16:55:44 -08008602 if (SIR_MAC_TDLS_SETUP_REQ == action_code)
Lee Hoonkic1262f22013-01-24 21:59:00 -08008603 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07008604 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8605 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07008606 " TDLS Max peer already connected. action %d declined.",
8607 __func__, MAC_ADDR_ARRAY(peer), action_code);
Sunil Dutt388ac8f2013-11-28 18:06:52 +05308608 return -EINVAL;
Lee Hoonkic1262f22013-01-24 21:59:00 -08008609 }
8610 else
8611 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -08008612 /* maximum reached. tweak to send error code to peer and return
8613 error code to supplicant */
Lee Hoonkic1262f22013-01-24 21:59:00 -08008614 status_code = eSIR_MAC_UNSPEC_FAILURE_STATUS;
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07008615 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8616 "%s: " MAC_ADDRESS_STR
8617 " TDLS Max peer already connected send response status %d",
8618 __func__, MAC_ADDR_ARRAY(peer), status_code);
Gopichand Nakkala05922802013-03-14 12:23:19 -07008619 max_sta_failed = -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -08008620 /* fall through to send setup resp with failure status
8621 code */
Lee Hoonkic1262f22013-01-24 21:59:00 -08008622 }
8623 }
Hoonki Lee11f7dda2013-02-14 16:55:44 -08008624 else
8625 {
8626 hddTdlsPeer_t *pTdlsPeer;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308627 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008628 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Hoonki Lee11f7dda2013-02-14 16:55:44 -08008629 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07008630 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07008631 "%s:" MAC_ADDRESS_STR " already connected. action %d declined.",
8632 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee11f7dda2013-02-14 16:55:44 -08008633 return -EPERM;
8634 }
8635 }
Lee Hoonkic1262f22013-01-24 21:59:00 -08008636 }
Hoonki Lee11f7dda2013-02-14 16:55:44 -08008637 vos_mem_copy(peerMac, peer, 6);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008638
Hoonki Lee1090c6a2013-01-16 17:40:54 -08008639#ifdef WLAN_FEATURE_TDLS_DEBUG
8640 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07008641 "%s: " MAC_ADDRESS_STR " action %d, dialog_token %d status %d, len = %d",
8642 "tdls_mgmt", MAC_ADDR_ARRAY(peer),
8643 action_code, dialog_token, status_code, len);
Hoonki Lee1090c6a2013-01-16 17:40:54 -08008644#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008645
Hoonki Leea34dd892013-02-05 22:56:02 -08008646 /*Except teardown responder will not be used so just make 0*/
8647 responder = 0;
Hoonki Lee11f7dda2013-02-14 16:55:44 -08008648 if (SIR_MAC_TDLS_TEARDOWN == action_code)
Hoonki Leea34dd892013-02-05 22:56:02 -08008649 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -07008650
8651 hddTdlsPeer_t *pTdlsPeer;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308652 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peerMac, TRUE);
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -07008653
8654 if(pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
8655 responder = pTdlsPeer->is_responder;
8656 else
Hoonki Leea34dd892013-02-05 22:56:02 -08008657 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -07008658 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8659 "%s: " MAC_ADDRESS_STR " peer doesn't exist or not connected %d dialog_token %d status %d, len = %d",
8660 __func__, MAC_ADDR_ARRAY(peer), (NULL == pTdlsPeer) ? -1 : pTdlsPeer->link_status,
8661 dialog_token, status_code, len);
8662 return -EPERM;
Hoonki Leea34dd892013-02-05 22:56:02 -08008663 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008664 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008665
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +05308666 /* For explicit trigger of DIS_REQ come out of BMPS for
8667 successfully receiving DIS_RSP from peer. */
Hoonki Lee14621352013-04-16 17:51:19 -07008668 if ((SIR_MAC_TDLS_SETUP_RSP == action_code) ||
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +05308669 (SIR_MAC_TDLS_DIS_RSP == action_code) ||
8670 (SIR_MAC_TDLS_DIS_REQ == action_code))
Hoonki Lee14621352013-04-16 17:51:19 -07008671 {
8672 if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter)))
8673 {
8674 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +05308675 "%s: Sending frame action_code %u.Disable BMPS", __func__, action_code);
Hoonki Lee14621352013-04-16 17:51:19 -07008676 hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
8677 }
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +05308678 if (SIR_MAC_TDLS_DIS_REQ != action_code)
8679 wlan_hdd_tdls_set_cap(pAdapter, peerMac, eTDLS_CAP_SUPPORTED);
Hoonki Lee14621352013-04-16 17:51:19 -07008680 }
8681
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008682 /* make sure doesn't call send_mgmt() while it is pending */
8683 if (TDLS_CTX_MAGIC == pAdapter->mgmtTxCompletionStatus)
8684 {
8685 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008686 "%s: " MAC_ADDRESS_STR " action %d couldn't sent, as one is pending. return EBUSY",
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008687 __func__, MAC_ADDR_ARRAY(peer), action_code);
8688 return -EBUSY;
8689 }
8690
8691 pAdapter->mgmtTxCompletionStatus = TDLS_CTX_MAGIC;
Gopichand Nakkalab977a972013-02-18 19:15:09 -08008692 INIT_COMPLETION(pAdapter->tdls_mgmt_comp);
8693
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008694 status = sme_SendTdlsMgmtFrame(WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
Hoonki Leea34dd892013-02-05 22:56:02 -08008695 peerMac, action_code, dialog_token, status_code, (tANI_U8 *)buf, len, responder);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008696
Gopichand Nakkalab977a972013-02-18 19:15:09 -08008697 if (VOS_STATUS_SUCCESS != status)
8698 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008699 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8700 "%s: sme_SendTdlsMgmtFrame failed!", __func__);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008701 pAdapter->mgmtTxCompletionStatus = FALSE;
Hoonki Lee14621352013-04-16 17:51:19 -07008702 wlan_hdd_tdls_check_bmps(pAdapter);
Sunil Dutt388ac8f2013-11-28 18:06:52 +05308703 return -EINVAL;
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008704 }
8705
Hoonki Leed37cbb32013-04-20 00:31:14 -07008706 rc = wait_for_completion_interruptible_timeout(&pAdapter->tdls_mgmt_comp,
8707 msecs_to_jiffies(WAIT_TIME_TDLS_MGMT));
8708
8709 if ((rc <= 0) || (TRUE != pAdapter->mgmtTxCompletionStatus))
Gopichand Nakkalab977a972013-02-18 19:15:09 -08008710 {
Hoonki Leed37cbb32013-04-20 00:31:14 -07008711 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07008712 "%s: Mgmt Tx Completion failed status %ld TxCompletion %u",
Hoonki Leed37cbb32013-04-20 00:31:14 -07008713 __func__, rc, pAdapter->mgmtTxCompletionStatus);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008714 pAdapter->mgmtTxCompletionStatus = FALSE;
Yue Ma4f55ef32014-01-23 16:45:33 -08008715
8716 if (pHddCtx->isLogpInProgress)
8717 {
8718 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8719 "%s: LOGP in Progress. Ignore!!!", __func__);
8720 return -EAGAIN;
8721 }
8722
Hoonki Leed37cbb32013-04-20 00:31:14 -07008723 wlan_hdd_tdls_check_bmps(pAdapter);
Sunil Dutt388ac8f2013-11-28 18:06:52 +05308724 return -EINVAL;
Gopichand Nakkalab977a972013-02-18 19:15:09 -08008725 }
8726
Gopichand Nakkala05922802013-03-14 12:23:19 -07008727 if (max_sta_failed)
Hoonki Lee14621352013-04-16 17:51:19 -07008728 {
8729 wlan_hdd_tdls_check_bmps(pAdapter);
Gopichand Nakkala05922802013-03-14 12:23:19 -07008730 return max_sta_failed;
Hoonki Lee14621352013-04-16 17:51:19 -07008731 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -08008732
Hoonki Leea34dd892013-02-05 22:56:02 -08008733 if (SIR_MAC_TDLS_SETUP_RSP == action_code)
8734 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -08008735 wlan_hdd_tdls_set_responder(pAdapter, peerMac, TRUE);
Hoonki Leea34dd892013-02-05 22:56:02 -08008736 }
8737 else if (SIR_MAC_TDLS_SETUP_CNF == action_code)
8738 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -08008739 wlan_hdd_tdls_set_responder(pAdapter, peerMac, FALSE);
Hoonki Leea34dd892013-02-05 22:56:02 -08008740 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008741
8742 return 0;
8743}
8744
8745static int wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
8746 u8 *peer, enum nl80211_tdls_operation oper)
8747{
8748 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
8749 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308750 int status;
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008751 hddTdlsPeer_t *pTdlsPeer;
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008752
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308753 if ( NULL == peer )
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008754 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -08008755 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chilam Ngc4244af2013-04-01 15:37:32 -07008756 "%s: Invalid arguments", __func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008757 return -EINVAL;
8758 }
Hoonki Lee1090c6a2013-01-16 17:40:54 -08008759
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308760 status = wlan_hdd_validate_context(pHddCtx);
8761
8762 if (0 != status)
Sameer Thalappil75ea31a2013-02-21 19:38:16 -08008763 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308764 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8765 "%s: HDD context is not valid", __func__);
8766 return status;
Sameer Thalappil75ea31a2013-02-21 19:38:16 -08008767 }
8768
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008769
8770 if( FALSE == pHddCtx->cfg_ini->fEnableTDLSSupport ||
Hoonki Lee1090c6a2013-01-16 17:40:54 -08008771 FALSE == sme_IsFeatureSupportedByFW(TDLS))
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008772 {
Hoonki Lee1090c6a2013-01-16 17:40:54 -08008773 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chilam Ngc4244af2013-04-01 15:37:32 -07008774 "TDLS Disabled in INI OR not enabled in FW. "
8775 "Cannot process TDLS commands");
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008776 return -ENOTSUPP;
8777 }
8778
8779 switch (oper) {
8780 case NL80211_TDLS_ENABLE_LINK:
8781 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008782 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308783 long ret;
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05308784 tCsrTdlsLinkEstablishParams tdlsLinkEstablishParams;
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008785
Sunil Dutt41de4e22013-11-14 18:09:02 +05308786 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
8787
8788 if ( NULL == pTdlsPeer ) {
8789 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
8790 " (oper %d) not exsting. ignored",
8791 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
8792 return -EINVAL;
8793 }
8794
8795 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8796 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
8797 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
8798 "NL80211_TDLS_ENABLE_LINK");
8799
Gopichand Nakkala2f4a2822013-04-17 11:22:01 -07008800 if (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
8801 {
8802 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Staion Index %u "
8803 MAC_ADDRESS_STR " failed",
8804 __func__, pTdlsPeer->staId, MAC_ADDR_ARRAY(peer));
8805 return -EINVAL;
8806 }
8807
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008808 if (eTDLS_LINK_CONNECTED != pTdlsPeer->link_status)
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07008809 {
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +05308810 if (IS_ADVANCE_TDLS_ENABLE) {
Gopichand Nakkala24be5312013-07-02 16:47:12 +05308811
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +05308812 if (0 != wlan_hdd_tdls_get_link_establish_params(
8813 pAdapter, peer,&tdlsLinkEstablishParams)) {
8814 return -EINVAL;
8815 }
8816 INIT_COMPLETION(pAdapter->tdls_link_establish_req_comp);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05308817
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +05308818 sme_SendTdlsLinkEstablishParams(WLAN_HDD_GET_HAL_CTX(pAdapter),
8819 pAdapter->sessionId, peer, &tdlsLinkEstablishParams);
8820 /* Send TDLS peer UAPSD capabilities to the firmware and
8821 * register with the TL on after the response for this operation
8822 * is received .
8823 */
8824 ret = wait_for_completion_interruptible_timeout(
8825 &pAdapter->tdls_link_establish_req_comp,
8826 msecs_to_jiffies(WAIT_TIME_TDLS_LINK_ESTABLISH_REQ));
8827 if (ret <= 0)
8828 {
8829 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8830 "%s: Link Establish Request Faled Status %ld",
8831 __func__, ret);
8832 return -EINVAL;
8833 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05308834 }
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -07008835 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer, eTDLS_LINK_CONNECTED);
Gopichand Nakkala471708b2013-06-04 20:03:01 +05308836 /* Mark TDLS client Authenticated .*/
8837 status = WLANTL_ChangeSTAState( pHddCtx->pvosContext,
8838 pTdlsPeer->staId,
8839 WLANTL_STA_AUTHENTICATED);
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -07008840 if (VOS_STATUS_SUCCESS == status)
8841 {
Hoonki Lee14621352013-04-16 17:51:19 -07008842 if (pTdlsPeer->is_responder == 0)
8843 {
8844 v_U8_t staId = (v_U8_t)pTdlsPeer->staId;
8845
8846 wlan_hdd_tdls_timer_restart(pAdapter,
8847 &pTdlsPeer->initiatorWaitTimeoutTimer,
8848 WAIT_TIME_TDLS_INITIATOR);
8849 /* suspend initiator TX until it receives direct packet from the
8850 reponder or WAIT_TIME_TDLS_INITIATOR timer expires */
8851 WLANTL_SuspendDataTx( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
8852 &staId, NULL);
8853 }
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -07008854 wlan_hdd_tdls_increment_peer_count(pAdapter);
8855 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07008856 wlan_hdd_tdls_check_bmps(pAdapter);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05308857
8858 /* Update TL about the UAPSD masks , to route the packets to firmware */
Gopichand Nakkala574f6d12013-06-27 19:38:43 +05308859 if ((TRUE == pHddCtx->cfg_ini->fEnableTDLSBufferSta)
8860 || pHddCtx->cfg_ini->fTDLSUapsdMask )
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05308861 {
Gopichand Nakkala574f6d12013-06-27 19:38:43 +05308862 int ac;
8863 uint8 ucAc[4] = { WLANTL_AC_VO,
8864 WLANTL_AC_VI,
8865 WLANTL_AC_BK,
8866 WLANTL_AC_BE };
8867 uint8 tlTid[4] = { 7, 5, 2, 3 } ;
8868 for(ac=0; ac < 4; ac++)
8869 {
8870 status = WLANTL_EnableUAPSDForAC( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
8871 pTdlsPeer->staId, ucAc[ac],
8872 tlTid[ac], tlTid[ac], 0, 0,
8873 WLANTL_BI_DIR );
8874 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05308875 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07008876 }
8877
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008878 }
8879 break;
8880 case NL80211_TDLS_DISABLE_LINK:
Lee Hoonkic1262f22013-01-24 21:59:00 -08008881 {
Sunil Dutt41de4e22013-11-14 18:09:02 +05308882 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
8883
8884 if ( NULL == pTdlsPeer ) {
8885 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
8886 " (oper %d) not exsting. ignored",
8887 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
8888 return -EINVAL;
8889 }
8890
8891 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8892 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
8893 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
8894 "NL80211_TDLS_DISABLE_LINK");
8895
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008896 if(TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
Lee Hoonkic1262f22013-01-24 21:59:00 -08008897 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008898 long status;
8899
8900 INIT_COMPLETION(pAdapter->tdls_del_station_comp);
8901
Lee Hoonkic1262f22013-01-24 21:59:00 -08008902 sme_DeleteTdlsPeerSta( WLAN_HDD_GET_HAL_CTX(pAdapter),
8903 pAdapter->sessionId, peer );
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008904
8905 status = wait_for_completion_interruptible_timeout(&pAdapter->tdls_del_station_comp,
8906 msecs_to_jiffies(WAIT_TIME_TDLS_DEL_STA));
8907 if (status <= 0)
8908 {
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008909 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer, eTDLS_LINK_IDLE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008910 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8911 "%s: Del station failed status %ld",
8912 __func__, status);
8913 return -EPERM;
8914 }
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008915 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer, eTDLS_LINK_IDLE);
Lee Hoonkic1262f22013-01-24 21:59:00 -08008916 }
8917 else
8918 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07008919 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8920 "%s: TDLS Peer Station doesn't exist.", __func__);
Lee Hoonkic1262f22013-01-24 21:59:00 -08008921 }
Lee Hoonkic1262f22013-01-24 21:59:00 -08008922 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07008923 break;
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008924 case NL80211_TDLS_TEARDOWN:
Sunil Dutt41de4e22013-11-14 18:09:02 +05308925 {
8926 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8927 " %s : NL80211_TDLS_TEARDOWN for " MAC_ADDRESS_STR,
8928 __func__, MAC_ADDR_ARRAY(peer));
8929
8930 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
8931 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
8932
8933 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8934 " %s TDLS External control and Implicit Trigger not enabled ",
8935 __func__);
8936 return -ENOTSUPP;
8937 }
8938
Sunil Dutt41de4e22013-11-14 18:09:02 +05308939
8940 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
8941
8942 if ( NULL == pTdlsPeer ) {
8943 hddLog(VOS_TRACE_LEVEL_INFO, "%s: " MAC_ADDRESS_STR
8944 " peer not exsting",
8945 __func__, MAC_ADDR_ARRAY(peer));
Naresh Jayaram937abdf2013-11-26 19:50:25 +05308946 return -EINVAL;
Sunil Dutt41de4e22013-11-14 18:09:02 +05308947 }
8948 else {
8949 wlan_hdd_tdls_indicate_teardown(pAdapter, pTdlsPeer,
8950 eSIR_MAC_TDLS_TEARDOWN_UNSPEC_REASON);
8951 }
Naresh Jayaram937abdf2013-11-26 19:50:25 +05308952
8953 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, FALSE) )
8954 return -EINVAL;
Sunil Dutt41de4e22013-11-14 18:09:02 +05308955 break;
8956 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008957 case NL80211_TDLS_SETUP:
Sunil Dutt41de4e22013-11-14 18:09:02 +05308958 {
Naresh Jayaramdb4514b2013-11-25 18:08:10 +05308959 hddTdlsPeer_t *pTdlsPeer;
Sunil Dutt41de4e22013-11-14 18:09:02 +05308960 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8961 " %s : NL80211_TDLS_SETUP for " MAC_ADDRESS_STR,
8962 __func__, MAC_ADDR_ARRAY(peer));
8963
8964 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
8965 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
8966
8967 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8968 " %s TDLS External control and Implicit Trigger not enabled ",
8969 __func__);
8970 return -ENOTSUPP;
8971 }
8972
Naresh Jayaramdb4514b2013-11-25 18:08:10 +05308973 /* To cater the requirement of establishing the TDLS link
8974 * irrespective of the data traffic , get an entry of TDLS peer.
8975 */
8976 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, peer);
8977 if (pTdlsPeer == NULL) {
8978 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8979 "%s: peer " MAC_ADDRESS_STR " not existing",
8980 __func__, MAC_ADDR_ARRAY(peer));
8981 return -EINVAL;
8982 }
Naresh Jayaram937abdf2013-11-26 19:50:25 +05308983
8984 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, TRUE) ) {
8985
8986 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8987 " %s TDLS Add Force Peer Failed",
8988 __func__);
8989 return -EINVAL;
8990 }
Naresh Jayaramdb4514b2013-11-25 18:08:10 +05308991 break;
Sunil Dutt41de4e22013-11-14 18:09:02 +05308992 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008993 case NL80211_TDLS_DISCOVERY_REQ:
8994 /* We don't support in-driver setup/teardown/discovery */
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308995 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
8996 "%s: We don't support in-driver setup/teardown/discovery "
8997 ,__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008998 return -ENOTSUPP;
8999 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309000 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9001 "%s: unsupported event",__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009002 return -ENOTSUPP;
9003 }
9004 return 0;
9005}
Chilam NG571c65a2013-01-19 12:27:36 +05309006
9007int wlan_hdd_cfg80211_send_tdls_discover_req(struct wiphy *wiphy,
9008 struct net_device *dev, u8 *peer)
9009{
Arif Hussaina7c8e412013-11-20 11:06:42 -08009010 hddLog(VOS_TRACE_LEVEL_INFO,
9011 "tdls send discover req: "MAC_ADDRESS_STR,
9012 MAC_ADDR_ARRAY(peer));
Chilam NG571c65a2013-01-19 12:27:36 +05309013
9014 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
9015 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, NULL, 0);
9016}
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009017#endif
9018
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309019#ifdef WLAN_FEATURE_GTK_OFFLOAD
9020/*
9021 * FUNCTION: wlan_hdd_cfg80211_update_replayCounterCallback
9022 * Callback rountine called upon receiving response for
9023 * get offload info
9024 */
9025void wlan_hdd_cfg80211_update_replayCounterCallback(void *callbackContext,
9026 tpSirGtkOffloadGetInfoRspParams pGtkOffloadGetInfoRsp)
9027{
9028
9029 hdd_adapter_t *pAdapter = (hdd_adapter_t *)callbackContext;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05309030 tANI_U8 tempReplayCounter[8];
9031 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309032
9033 ENTER();
9034
9035 if (NULL == pAdapter)
9036 {
Agarwal Ashish971c2882013-10-30 20:11:12 +05309037 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309038 "%s: HDD adapter is Null", __func__);
9039 return ;
9040 }
9041
9042 if (NULL == pGtkOffloadGetInfoRsp)
9043 {
9044 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9045 "%s: pGtkOffloadGetInfoRsp is Null", __func__);
9046 return ;
9047 }
9048
9049 if (VOS_STATUS_SUCCESS != pGtkOffloadGetInfoRsp->ulStatus)
9050 {
9051 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9052 "%s: wlan Failed to get replay counter value",
9053 __func__);
9054 return ;
9055 }
9056
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05309057 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9058 /* Update replay counter */
9059 pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter =
9060 pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
9061
9062 {
9063 /* changing from little to big endian since supplicant
9064 * works on big endian format
9065 */
9066 int i;
9067 tANI_U8 *p = (tANI_U8 *)&pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
9068
9069 for (i = 0; i < 8; i++)
9070 {
9071 tempReplayCounter[7-i] = (tANI_U8)p[i];
9072 }
9073 }
9074
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309075 /* Update replay counter to NL */
9076 cfg80211_gtk_rekey_notify(pAdapter->dev, pGtkOffloadGetInfoRsp->bssId,
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05309077 tempReplayCounter, GFP_KERNEL);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309078}
9079
9080/*
9081 * FUNCTION: wlan_hdd_cfg80211_set_rekey_data
9082 * This function is used to offload GTK rekeying job to the firmware.
9083 */
9084int wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
9085 struct cfg80211_gtk_rekey_data *data)
9086{
9087 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
9088 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
9089 hdd_station_ctx_t *pHddStaCtx;
9090 tHalHandle hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309091 int result;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05309092 tSirGtkOffloadParams hddGtkOffloadReqParams;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309093 eHalStatus status = eHAL_STATUS_FAILURE;
9094
9095 ENTER();
9096
9097 if (NULL == pAdapter)
9098 {
9099 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
9100 "%s: HDD adapter is Null", __func__);
9101 return -ENODEV;
9102 }
9103
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309104 result = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309105
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309106 if (0 != result)
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309107 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309108 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9109 "%s: HDD context is not valid", __func__);
9110 return result;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309111 }
9112
9113 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9114 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
9115 if (NULL == hHal)
9116 {
9117 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9118 "%s: HAL context is Null!!!", __func__);
9119 return -EAGAIN;
9120 }
9121
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05309122 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_ENABLE;
9123 memcpy(pHddStaCtx->gtkOffloadReqParams.aKCK, data->kck, NL80211_KCK_LEN);
9124 memcpy(pHddStaCtx->gtkOffloadReqParams.aKEK, data->kek, NL80211_KEK_LEN);
9125 memcpy(pHddStaCtx->gtkOffloadReqParams.bssId, &pHddStaCtx->conn_info.bssId,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309126 WNI_CFG_BSSID_LEN);
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05309127 {
9128 /* changing from big to little endian since driver
9129 * works on little endian format
9130 */
9131 tANI_U8 *p =
9132 (tANI_U8 *)&pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter;
9133 int i;
9134
9135 for (i = 0; i < 8; i++)
9136 {
9137 p[7-i] = data->replay_ctr[i];
9138 }
9139 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309140
9141 if (TRUE == pHddCtx->hdd_wlan_suspended)
9142 {
9143 /* if wlan is suspended, enable GTK offload directly from here */
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05309144 memcpy(&hddGtkOffloadReqParams, &pHddStaCtx->gtkOffloadReqParams,
9145 sizeof (tSirGtkOffloadParams));
9146 status = sme_SetGTKOffload(hHal, &hddGtkOffloadReqParams,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309147 pAdapter->sessionId);
9148
9149 if (eHAL_STATUS_SUCCESS != status)
9150 {
9151 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9152 "%s: sme_SetGTKOffload failed, returned %d",
9153 __func__, status);
9154 return status;
9155 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309156 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9157 "%s: sme_SetGTKOffload successfull", __func__);
9158 }
9159 else
9160 {
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309161 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9162 "%s: wlan not suspended GTKOffload request is stored",
9163 __func__);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309164 }
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05309165
9166 return eHAL_STATUS_SUCCESS;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309167}
9168#endif /*WLAN_FEATURE_GTK_OFFLOAD*/
9169
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05309170/*
9171 * FUNCTION: wlan_hdd_cfg80211_set_mac_acl
9172 * This function is used to set access control policy
9173 */
9174static int wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy,
9175 struct net_device *dev, const struct cfg80211_acl_data *params)
9176{
9177 int i;
9178 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
9179 hdd_hostapd_state_t *pHostapdState;
9180 tsap_Config_t *pConfig;
9181 v_CONTEXT_t pVosContext = NULL;
9182 hdd_context_t *pHddCtx;
9183 int status;
9184
9185 ENTER();
9186
9187 if (NULL == pAdapter)
9188 {
9189 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
9190 "%s: HDD adapter is Null", __func__);
9191 return -ENODEV;
9192 }
9193
9194 if (NULL == params)
9195 {
9196 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
9197 "%s: params is Null", __func__);
9198 return -EINVAL;
9199 }
9200
9201 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9202 status = wlan_hdd_validate_context(pHddCtx);
9203
9204 if (0 != status)
9205 {
9206 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9207 "%s: HDD context is not valid", __func__);
9208 return status;
9209 }
9210
9211 pVosContext = pHddCtx->pvosContext;
9212 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
9213
9214 if (NULL == pHostapdState)
9215 {
9216 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
9217 "%s: pHostapdState is Null", __func__);
9218 return -EINVAL;
9219 }
9220
9221 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"acl policy: = %d"
9222 "no acl entries = %d", params->acl_policy, params->n_acl_entries);
9223
9224 if (WLAN_HDD_SOFTAP == pAdapter->device_mode)
9225 {
9226 pConfig = &pAdapter->sessionCtx.ap.sapConfig;
9227
9228 /* default value */
9229 pConfig->num_accept_mac = 0;
9230 pConfig->num_deny_mac = 0;
9231
9232 /**
9233 * access control policy
9234 * @NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED: Deny stations which are
9235 * listed in hostapd.deny file.
9236 * @NL80211_ACL_POLICY_DENY_UNLESS_LISTED: Allow stations which are
9237 * listed in hostapd.accept file.
9238 */
9239 if (NL80211_ACL_POLICY_DENY_UNLESS_LISTED == params->acl_policy)
9240 {
9241 pConfig->SapMacaddr_acl = eSAP_DENY_UNLESS_ACCEPTED;
9242 }
9243 else if (NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED == params->acl_policy)
9244 {
9245 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
9246 }
9247 else
9248 {
9249 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9250 "%s:Acl Policy : %d is not supported",
9251 __func__, params->acl_policy);
9252 return -ENOTSUPP;
9253 }
9254
9255 if (eSAP_DENY_UNLESS_ACCEPTED == pConfig->SapMacaddr_acl)
9256 {
9257 pConfig->num_accept_mac = params->n_acl_entries;
9258 for (i = 0; i < params->n_acl_entries; i++)
9259 {
9260 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9261 "** Add ACL MAC entry %i in WhiletList :"
9262 MAC_ADDRESS_STR, i,
9263 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
9264
9265 vos_mem_copy(&pConfig->accept_mac[i], params->mac_addrs[i].addr,
9266 sizeof(qcmacaddr));
9267 }
9268 }
9269 else if (eSAP_ACCEPT_UNLESS_DENIED == pConfig->SapMacaddr_acl)
9270 {
9271 pConfig->num_deny_mac = params->n_acl_entries;
9272 for (i = 0; i < params->n_acl_entries; i++)
9273 {
9274 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9275 "** Add ACL MAC entry %i in BlackList :"
9276 MAC_ADDRESS_STR, i,
9277 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
9278
9279 vos_mem_copy(&pConfig->deny_mac[i], params->mac_addrs[i].addr,
9280 sizeof(qcmacaddr));
9281 }
9282 }
9283
9284 if (VOS_STATUS_SUCCESS != WLANSAP_SetMacACL(pVosContext, pConfig))
9285 {
9286 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9287 "%s: SAP Set Mac Acl fail", __func__);
9288 return -EINVAL;
9289 }
9290 }
9291 else
9292 {
9293 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9294 "%s: Invalid device_mode = %d",
9295 __func__, pAdapter->device_mode);
9296 return -EINVAL;
9297 }
9298
9299 return 0;
9300}
9301
Leo Chang9056f462013-08-01 19:21:11 -07009302#ifdef WLAN_NL80211_TESTMODE
9303#ifdef FEATURE_WLAN_LPHB
Leo Changd9df8aa2013-09-26 13:32:26 -07009304void wlan_hdd_cfg80211_lphb_ind_handler
Leo Chang9056f462013-08-01 19:21:11 -07009305(
9306 void *pAdapter,
9307 void *indCont
9308)
9309{
Leo Changd9df8aa2013-09-26 13:32:26 -07009310 tSirLPHBInd *lphbInd;
9311 struct sk_buff *skb;
Leo Chang9056f462013-08-01 19:21:11 -07009312
9313 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -07009314 "LPHB indication arrived");
Leo Chang9056f462013-08-01 19:21:11 -07009315
9316 if (NULL == indCont)
9317 {
9318 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -07009319 "LPHB IND, invalid argument");
Leo Chang9056f462013-08-01 19:21:11 -07009320 return;
9321 }
9322
Leo Changd9df8aa2013-09-26 13:32:26 -07009323 lphbInd = (tSirLPHBInd *)indCont;
Leo Chang9056f462013-08-01 19:21:11 -07009324 skb = cfg80211_testmode_alloc_event_skb(
9325 ((hdd_adapter_t *)pAdapter)->wdev.wiphy,
Leo Changd9df8aa2013-09-26 13:32:26 -07009326 sizeof(tSirLPHBInd),
Leo Chang9056f462013-08-01 19:21:11 -07009327 GFP_ATOMIC);
9328 if (!skb)
9329 {
9330 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9331 "LPHB timeout, NL buffer alloc fail");
9332 return;
9333 }
9334
Leo Changac3ba772013-10-07 09:47:04 -07009335 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_CMD, WLAN_HDD_TM_CMD_WLAN_HB))
Leo Changd9df8aa2013-09-26 13:32:26 -07009336 {
9337 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9338 "WLAN_HDD_TM_ATTR_CMD put fail");
9339 goto nla_put_failure;
9340 }
Leo Changac3ba772013-10-07 09:47:04 -07009341 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_TYPE, lphbInd->protocolType))
Leo Changd9df8aa2013-09-26 13:32:26 -07009342 {
9343 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9344 "WLAN_HDD_TM_ATTR_TYPE put fail");
9345 goto nla_put_failure;
9346 }
Leo Changac3ba772013-10-07 09:47:04 -07009347 if(nla_put(skb, WLAN_HDD_TM_ATTR_DATA,
Leo Changd9df8aa2013-09-26 13:32:26 -07009348 sizeof(tSirLPHBInd), lphbInd))
9349 {
9350 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9351 "WLAN_HDD_TM_ATTR_DATA put fail");
9352 goto nla_put_failure;
9353 }
Leo Chang9056f462013-08-01 19:21:11 -07009354 cfg80211_testmode_event(skb, GFP_ATOMIC);
9355 return;
9356
9357nla_put_failure:
9358 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9359 "NLA Put fail");
9360 kfree_skb(skb);
9361
9362 return;
9363}
9364#endif /* FEATURE_WLAN_LPHB */
9365
9366static int wlan_hdd_cfg80211_testmode(struct wiphy *wiphy, void *data, int len)
9367{
9368 struct nlattr *tb[WLAN_HDD_TM_ATTR_MAX + 1];
9369 int err = 0;
9370#ifdef FEATURE_WLAN_LPHB
9371 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Leo Changd9df8aa2013-09-26 13:32:26 -07009372 eHalStatus smeStatus;
Leo Chang9056f462013-08-01 19:21:11 -07009373#endif /* FEATURE_WLAN_LPHB */
9374
9375 err = nla_parse(tb, WLAN_HDD_TM_ATTR_MAX, data, len, wlan_hdd_tm_policy);
9376 if (err)
9377 {
9378 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9379 "%s Testmode INV ATTR", __func__);
9380 return err;
9381 }
9382
9383 if (!tb[WLAN_HDD_TM_ATTR_CMD])
9384 {
9385 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9386 "%s Testmode INV CMD", __func__);
9387 return -EINVAL;
9388 }
9389
9390 switch (nla_get_u32(tb[WLAN_HDD_TM_ATTR_CMD]))
9391 {
9392#ifdef FEATURE_WLAN_LPHB
9393 /* Low Power Heartbeat configuration request */
9394 case WLAN_HDD_TM_CMD_WLAN_HB:
9395 {
9396 int buf_len;
9397 void *buf;
9398 tSirLPHBReq *hb_params = NULL;
Amar Singhal05852702014-02-04 14:40:00 -08009399 tSirLPHBReq *hb_params_temp = NULL;
Leo Chang9056f462013-08-01 19:21:11 -07009400
9401 if (!tb[WLAN_HDD_TM_ATTR_DATA])
9402 {
9403 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9404 "%s Testmode INV DATA", __func__);
9405 return -EINVAL;
9406 }
9407
9408 buf = nla_data(tb[WLAN_HDD_TM_ATTR_DATA]);
9409 buf_len = nla_len(tb[WLAN_HDD_TM_ATTR_DATA]);
Amar Singhal05852702014-02-04 14:40:00 -08009410
9411 hb_params_temp =(tSirLPHBReq *)buf;
9412 if ((hb_params_temp->cmd == LPHB_SET_TCP_PARAMS_INDID) &&
9413 (hb_params_temp->params.lphbTcpParamReq.timePeriodSec == 0))
9414 return -EINVAL;
9415
Leo Chang9056f462013-08-01 19:21:11 -07009416 hb_params = (tSirLPHBReq *)vos_mem_malloc(sizeof(tSirLPHBReq));
9417 if (NULL == hb_params)
9418 {
9419 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9420 "%s Request Buffer Alloc Fail", __func__);
9421 return -EINVAL;
9422 }
9423
9424 vos_mem_copy(hb_params, buf, buf_len);
Leo Changd9df8aa2013-09-26 13:32:26 -07009425 smeStatus = sme_LPHBConfigReq((tHalHandle)(pHddCtx->hHal),
9426 hb_params,
9427 wlan_hdd_cfg80211_lphb_ind_handler);
9428 if (eHAL_STATUS_SUCCESS != smeStatus)
Leo Chang9056f462013-08-01 19:21:11 -07009429 {
Leo Changd9df8aa2013-09-26 13:32:26 -07009430 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9431 "LPHB Config Fail, disable");
Leo Chang9056f462013-08-01 19:21:11 -07009432 vos_mem_free(hb_params);
9433 }
Leo Chang9056f462013-08-01 19:21:11 -07009434 return 0;
9435 }
9436#endif /* FEATURE_WLAN_LPHB */
9437 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309438 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9439 "%s: unsupported event",__func__);
Leo Chang9056f462013-08-01 19:21:11 -07009440 return -EOPNOTSUPP;
9441 }
9442
9443 return err;
9444}
9445#endif /* CONFIG_NL80211_TESTMODE */
9446
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +05309447static int wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
9448 struct net_device *dev,
9449 int idx, struct survey_info *survey)
9450{
9451 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
9452 hdd_context_t *pHddCtx;
Mihir Sheted9072e02013-08-21 17:02:29 +05309453 hdd_station_ctx_t *pHddStaCtx;
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +05309454 tHalHandle halHandle;
Mihir Sheted9072e02013-08-21 17:02:29 +05309455 v_U32_t channel = 0, freq = 0; /* Initialization Required */
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +05309456 v_S7_t snr,rssi;
9457 int status, i, j, filled = 0;
9458
9459 ENTER();
9460
9461
9462 if (NULL == pAdapter)
9463 {
9464 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
9465 "%s: HDD adapter is Null", __func__);
9466 return -ENODEV;
9467 }
9468
9469 if (NULL == wiphy)
9470 {
9471 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
9472 "%s: wiphy is Null", __func__);
9473 return -ENODEV;
9474 }
9475
9476 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9477 status = wlan_hdd_validate_context(pHddCtx);
9478
9479 if (0 != status)
9480 {
9481 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9482 "%s: HDD context is not valid", __func__);
9483 return status;
9484 }
9485
Mihir Sheted9072e02013-08-21 17:02:29 +05309486 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9487
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +05309488 if (0 == pHddCtx->cfg_ini->fEnableSNRMonitoring ||
Mihir Sheted9072e02013-08-21 17:02:29 +05309489 0 != pAdapter->survey_idx ||
9490 eConnectionState_Associated != pHddStaCtx->conn_info.connState)
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +05309491 {
9492 /* The survey dump ops when implemented completely is expected to
9493 * return a survey of all channels and the ops is called by the
9494 * kernel with incremental values of the argument 'idx' till it
9495 * returns -ENONET. But we can only support the survey for the
9496 * operating channel for now. survey_idx is used to track
9497 * that the ops is called only once and then return -ENONET for
9498 * the next iteration
9499 */
9500 pAdapter->survey_idx = 0;
9501 return -ENONET;
9502 }
9503
9504 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
9505
9506 wlan_hdd_get_snr(pAdapter, &snr);
9507 wlan_hdd_get_rssi(pAdapter, &rssi);
9508
9509 sme_GetOperationChannel(halHandle, &channel, pAdapter->sessionId);
9510 hdd_wlan_get_freq(channel, &freq);
9511
9512
9513 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
9514 {
9515 if (NULL == wiphy->bands[i])
9516 {
9517 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
9518 "%s: wiphy->bands[i] is NULL, i = %d", __func__, i);
9519 continue;
9520 }
9521
9522 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
9523 {
9524 struct ieee80211_supported_band *band = wiphy->bands[i];
9525
9526 if (band->channels[j].center_freq == (v_U16_t)freq)
9527 {
9528 survey->channel = &band->channels[j];
9529 /* The Rx BDs contain SNR values in dB for the received frames
9530 * while the supplicant expects noise. So we calculate and
9531 * return the value of noise (dBm)
9532 * SNR (dB) = RSSI (dBm) - NOISE (dBm)
9533 */
9534 survey->noise = rssi - snr;
9535 survey->filled = SURVEY_INFO_NOISE_DBM;
9536 filled = 1;
9537 }
9538 }
9539 }
9540
9541 if (filled)
9542 pAdapter->survey_idx = 1;
9543 else
9544 {
9545 pAdapter->survey_idx = 0;
9546 return -ENONET;
9547 }
9548
9549 return 0;
9550}
9551
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05309552/*
9553 * FUNCTION: wlan_hdd_cfg80211_resume_wlan
9554 * this is called when cfg80211 driver resume
9555 * driver updates latest sched_scan scan result(if any) to cfg80211 database
9556 */
9557int wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
9558{
9559 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
9560 hdd_adapter_t *pAdapter;
9561 hdd_adapter_list_node_t *pAdapterNode, *pNext;
9562 VOS_STATUS status = VOS_STATUS_SUCCESS;
9563
9564 ENTER();
9565
9566 if ( NULL == pHddCtx )
9567 {
9568 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
9569 "%s: HddCtx validation failed", __func__);
9570 return 0;
9571 }
9572
9573 if (pHddCtx->isLogpInProgress)
9574 {
9575 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9576 "%s: LOGP in Progress. Ignore!!!", __func__);
9577 return 0;
9578 }
9579
9580 if (pHddCtx->isLoadUnloadInProgress)
9581 {
9582 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9583 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
9584 return 0;
9585 }
9586
9587 spin_lock(&pHddCtx->schedScan_lock);
9588 pHddCtx->isWiphySuspended = FALSE;
9589 if (TRUE != pHddCtx->isSchedScanUpdatePending)
9590 {
9591 spin_unlock(&pHddCtx->schedScan_lock);
9592 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9593 "%s: Return resume is not due to PNO indication", __func__);
9594 return 0;
9595 }
9596 // Reset flag to avoid updatating cfg80211 data old results again
9597 pHddCtx->isSchedScanUpdatePending = FALSE;
9598 spin_unlock(&pHddCtx->schedScan_lock);
9599
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +05309600
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05309601 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
9602
9603 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
9604 {
9605 pAdapter = pAdapterNode->pAdapter;
9606 if ( (NULL != pAdapter) &&
9607 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) )
9608 {
9609 if (0 != wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter))
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +05309610 {
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05309611 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
9612 "%s: NO SCAN result", __func__);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +05309613 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05309614 else
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +05309615 {
9616 /* Acquire wakelock to handle the case where APP's tries to
9617 * suspend immediately after updating the scan results. Whis
9618 * results in app's is in suspended state and not able to
9619 * process the connect request to AP
9620 */
9621 hdd_prevent_suspend_timeout(2000);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05309622 cfg80211_sched_scan_results(pHddCtx->wiphy);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +05309623 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05309624
9625 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9626 "%s : cfg80211 scan result database updated", __func__);
9627
9628 return 0;
9629
9630 }
9631 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
9632 pAdapterNode = pNext;
9633 }
9634
9635 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9636 "%s: Failed to find Adapter", __func__);
9637 return 0;
9638}
9639
9640/*
9641 * FUNCTION: wlan_hdd_cfg80211_suspend_wlan
9642 * this is called when cfg80211 driver suspends
9643 */
9644int wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
9645 struct cfg80211_wowlan *wow)
9646{
9647 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
9648
9649 ENTER();
9650 if (NULL == pHddCtx)
9651 {
9652 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
9653 "%s: HddCtx validation failed", __func__);
9654 return 0;
9655 }
9656
9657 pHddCtx->isWiphySuspended = TRUE;
9658
9659 EXIT();
9660
9661 return 0;
9662}
9663
Jeff Johnson295189b2012-06-20 16:38:30 -07009664/* cfg80211_ops */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309665static struct cfg80211_ops wlan_hdd_cfg80211_ops =
Jeff Johnson295189b2012-06-20 16:38:30 -07009666{
9667 .add_virtual_intf = wlan_hdd_add_virtual_intf,
9668 .del_virtual_intf = wlan_hdd_del_virtual_intf,
9669 .change_virtual_intf = wlan_hdd_cfg80211_change_iface,
9670 .change_station = wlan_hdd_change_station,
9671#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
9672 .add_beacon = wlan_hdd_cfg80211_add_beacon,
9673 .del_beacon = wlan_hdd_cfg80211_del_beacon,
9674 .set_beacon = wlan_hdd_cfg80211_set_beacon,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009675#else
9676 .start_ap = wlan_hdd_cfg80211_start_ap,
9677 .change_beacon = wlan_hdd_cfg80211_change_beacon,
9678 .stop_ap = wlan_hdd_cfg80211_stop_ap,
Jeff Johnson295189b2012-06-20 16:38:30 -07009679#endif
9680 .change_bss = wlan_hdd_cfg80211_change_bss,
9681 .add_key = wlan_hdd_cfg80211_add_key,
9682 .get_key = wlan_hdd_cfg80211_get_key,
9683 .del_key = wlan_hdd_cfg80211_del_key,
9684 .set_default_key = wlan_hdd_cfg80211_set_default_key,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -08009685#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07009686 .set_channel = wlan_hdd_cfg80211_set_channel,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -08009687#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009688 .scan = wlan_hdd_cfg80211_scan,
9689 .connect = wlan_hdd_cfg80211_connect,
9690 .disconnect = wlan_hdd_cfg80211_disconnect,
9691 .join_ibss = wlan_hdd_cfg80211_join_ibss,
9692 .leave_ibss = wlan_hdd_cfg80211_leave_ibss,
9693 .set_wiphy_params = wlan_hdd_cfg80211_set_wiphy_params,
9694 .set_tx_power = wlan_hdd_cfg80211_set_txpower,
9695 .get_tx_power = wlan_hdd_cfg80211_get_txpower,
Jeff Johnson295189b2012-06-20 16:38:30 -07009696 .remain_on_channel = wlan_hdd_cfg80211_remain_on_channel,
9697 .cancel_remain_on_channel = wlan_hdd_cfg80211_cancel_remain_on_channel,
9698 .mgmt_tx = wlan_hdd_action,
9699#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
9700 .mgmt_tx_cancel_wait = wlan_hdd_cfg80211_mgmt_tx_cancel_wait,
9701 .set_default_mgmt_key = wlan_hdd_set_default_mgmt_key,
9702 .set_txq_params = wlan_hdd_set_txq_params,
9703#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009704 .get_station = wlan_hdd_cfg80211_get_station,
9705 .set_power_mgmt = wlan_hdd_cfg80211_set_power_mgmt,
9706 .del_station = wlan_hdd_cfg80211_del_station,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009707 .add_station = wlan_hdd_cfg80211_add_station,
9708#ifdef FEATURE_WLAN_LFR
9709 .set_pmksa = wlan_hdd_cfg80211_set_pmksa,
9710 .del_pmksa = wlan_hdd_cfg80211_del_pmksa,
9711 .flush_pmksa = wlan_hdd_cfg80211_flush_pmksa,
9712#endif
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07009713#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
9714 .update_ft_ies = wlan_hdd_cfg80211_update_ft_ies,
9715#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009716#ifdef FEATURE_WLAN_TDLS
9717 .tdls_mgmt = wlan_hdd_cfg80211_tdls_mgmt,
9718 .tdls_oper = wlan_hdd_cfg80211_tdls_oper,
9719#endif
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309720#ifdef WLAN_FEATURE_GTK_OFFLOAD
9721 .set_rekey_data = wlan_hdd_cfg80211_set_rekey_data,
9722#endif /* WLAN_FEATURE_GTK_OFFLOAD */
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05309723#ifdef FEATURE_WLAN_SCAN_PNO
9724 .sched_scan_start = wlan_hdd_cfg80211_sched_scan_start,
9725 .sched_scan_stop = wlan_hdd_cfg80211_sched_scan_stop,
9726#endif /*FEATURE_WLAN_SCAN_PNO */
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05309727 .resume = wlan_hdd_cfg80211_resume_wlan,
9728 .suspend = wlan_hdd_cfg80211_suspend_wlan,
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05309729 .set_mac_acl = wlan_hdd_cfg80211_set_mac_acl,
Leo Chang9056f462013-08-01 19:21:11 -07009730#ifdef WLAN_NL80211_TESTMODE
9731 .testmode_cmd = wlan_hdd_cfg80211_testmode,
9732#endif
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +05309733 .dump_survey = wlan_hdd_cfg80211_dump_survey,
Jeff Johnson295189b2012-06-20 16:38:30 -07009734};
9735