blob: 181fa2580057081af5e1a2ae623cacd60ab6e57e [file] [log] [blame]
Jeff Johnson295189b2012-06-20 16:38:30 -07001/*
Kiet Lam842dad02014-02-18 18:44:02 -08002 * Copyright (c) 2012-2014 The Linux Foundation. All rights reserved.
3 *
4 * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
5 *
6 *
7 * Permission to use, copy, modify, and/or distribute this software for
8 * any purpose with or without fee is hereby granted, provided that the
9 * above copyright notice and this permission notice appear in all
10 * copies.
11 *
12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
13 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
14 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
15 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
16 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
17 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
18 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
19 * PERFORMANCE OF THIS SOFTWARE.
20 */
21
22/*
Kiet Lamaa8e15a2014-02-11 23:30:06 -080023 * Copyright (c) 2012-2014 Qualcomm Atheros, Inc.
24 * All Rights Reserved.
25 * Qualcomm Atheros Confidential and Proprietary.
Kiet Lam842dad02014-02-18 18:44:02 -080026 *
Kiet Lamaa8e15a2014-02-11 23:30:06 -080027 */
Kiet Lam842dad02014-02-18 18:44:02 -080028
29
Jeff Johnson295189b2012-06-20 16:38:30 -070030/**========================================================================
31
32 \file wlan_hdd_cfg80211.c
33
34 \brief WLAN Host Device Driver implementation
35
Jeff Johnson295189b2012-06-20 16:38:30 -070036 ========================================================================*/
37
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070038/**=========================================================================
Jeff Johnson295189b2012-06-20 16:38:30 -070039
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070040 EDIT HISTORY FOR FILE
Jeff Johnson295189b2012-06-20 16:38:30 -070041
42
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070043 This section contains comments describing changes made to the module.
44 Notice that changes are listed in reverse chronological order.
Jeff Johnson295189b2012-06-20 16:38:30 -070045
46
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070047 $Header:$ $DateTime: $ $Author: $
Jeff Johnson295189b2012-06-20 16:38:30 -070048
49
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070050 when who what, where, why
Jeff Johnson295189b2012-06-20 16:38:30 -070051 -------- --- --------------------------------------------------------
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070052 21/12/09 Ashwani Created module.
Jeff Johnson295189b2012-06-20 16:38:30 -070053
54 07/06/10 Kumar Deepak Implemented cfg80211 callbacks for ANDROID
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070055 Ganesh K
Jeff Johnson295189b2012-06-20 16:38:30 -070056 ==========================================================================*/
57
Jeff Johnson295189b2012-06-20 16:38:30 -070058
59#include <linux/version.h>
60#include <linux/module.h>
61#include <linux/kernel.h>
62#include <linux/init.h>
63#include <linux/wireless.h>
64#include <wlan_hdd_includes.h>
65#include <net/arp.h>
66#include <net/cfg80211.h>
67#include <linux/wireless.h>
68#include <wlan_hdd_wowl.h>
69#include <aniGlobal.h>
70#include "ccmApi.h"
71#include "sirParams.h"
72#include "dot11f.h"
73#include "wlan_hdd_assoc.h"
74#include "wlan_hdd_wext.h"
75#include "sme_Api.h"
76#include "wlan_hdd_p2p.h"
77#include "wlan_hdd_cfg80211.h"
78#include "wlan_hdd_hostapd.h"
79#include "sapInternal.h"
80#include "wlan_hdd_softap_tx_rx.h"
81#include "wlan_hdd_main.h"
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053082#include "wlan_hdd_assoc.h"
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053083#include "wlan_hdd_power.h"
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053084#include "wlan_hdd_trace.h"
85#include "vos_types.h"
86#include "vos_trace.h"
Jeff Johnson295189b2012-06-20 16:38:30 -070087#ifdef WLAN_BTAMP_FEATURE
88#include "bap_hdd_misc.h"
89#endif
90#include <qc_sap_ioctl.h>
Mohit Khanna698ba2a2012-12-04 15:08:18 -080091#ifdef FEATURE_WLAN_TDLS
92#include "wlan_hdd_tdls.h"
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053093#include "wlan_hdd_wmm.h"
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053094#include "wlan_qct_wda.h"
Mohit Khanna698ba2a2012-12-04 15:08:18 -080095#endif
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +053096#include "wlan_nv.h"
Leo Chang6fe1f922013-06-07 19:21:24 -070097#include "wlan_hdd_dev_pwr.h"
Jeff Johnson295189b2012-06-20 16:38:30 -070098
99#define g_mode_rates_size (12)
100#define a_mode_rates_size (8)
101#define FREQ_BASE_80211G (2407)
102#define FREQ_BAND_DIFF_80211G (5)
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700103#define MAX_SCAN_SSID 9
Kiet Lamac06e2c2013-10-23 16:25:07 +0530104#define MAX_PENDING_LOG 5
Jeff Johnson295189b2012-06-20 16:38:30 -0700105#define GET_IE_LEN_IN_BSS_DESC(lenInBss) ( lenInBss + sizeof(lenInBss) - \
krunal soni2a6a9062014-02-11 14:14:23 -0800106 ((uintptr_t)OFFSET_OF( tSirBssDescription, ieFields)))
Jeff Johnson295189b2012-06-20 16:38:30 -0700107
108#define HDD2GHZCHAN(freq, chan, flag) { \
109 .band = IEEE80211_BAND_2GHZ, \
110 .center_freq = (freq), \
111 .hw_value = (chan),\
112 .flags = (flag), \
113 .max_antenna_gain = 0 ,\
114 .max_power = 30, \
115}
116
117#define HDD5GHZCHAN(freq, chan, flag) { \
118 .band = IEEE80211_BAND_5GHZ, \
119 .center_freq = (freq), \
120 .hw_value = (chan),\
121 .flags = (flag), \
122 .max_antenna_gain = 0 ,\
123 .max_power = 30, \
124}
125
126#define HDD_G_MODE_RATETAB(rate, rate_id, flag)\
127{\
128 .bitrate = rate, \
129 .hw_value = rate_id, \
130 .flags = flag, \
131}
132
Lee Hoonkic1262f22013-01-24 21:59:00 -0800133#ifndef WLAN_FEATURE_TDLS_DEBUG
134#define TDLS_LOG_LEVEL VOS_TRACE_LEVEL_INFO
135#else
136#define TDLS_LOG_LEVEL VOS_TRACE_LEVEL_ERROR
137#endif
138
Gopichand Nakkala356fb102013-03-06 12:34:04 +0530139#ifdef WLAN_FEATURE_VOWIFI_11R
140#define WLAN_AKM_SUITE_FT_8021X 0x000FAC03
141#define WLAN_AKM_SUITE_FT_PSK 0x000FAC04
142#endif
143
Naresh Jayaram3180aa42014-02-12 21:47:26 +0530144#define HDD_CHANNEL_14 14
145
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530146static const u32 hdd_cipher_suites[] =
Jeff Johnson295189b2012-06-20 16:38:30 -0700147{
148 WLAN_CIPHER_SUITE_WEP40,
149 WLAN_CIPHER_SUITE_WEP104,
150 WLAN_CIPHER_SUITE_TKIP,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800151#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -0700152#define WLAN_CIPHER_SUITE_KRK 0x004096ff /* use for KRK */
153 WLAN_CIPHER_SUITE_KRK,
154 WLAN_CIPHER_SUITE_CCMP,
155#else
156 WLAN_CIPHER_SUITE_CCMP,
157#endif
158#ifdef FEATURE_WLAN_WAPI
159 WLAN_CIPHER_SUITE_SMS4,
160#endif
Chet Lanctot186b5732013-03-18 10:26:30 -0700161#ifdef WLAN_FEATURE_11W
162 WLAN_CIPHER_SUITE_AES_CMAC,
163#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700164};
165
166static inline int is_broadcast_ether_addr(const u8 *addr)
167{
168 return ((addr[0] == 0xff) && (addr[1] == 0xff) && (addr[2] == 0xff) &&
169 (addr[3] == 0xff) && (addr[4] == 0xff) && (addr[5] == 0xff));
170}
171
172static struct ieee80211_channel hdd_channels_2_4_GHZ[] =
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530173{
Jeff Johnson295189b2012-06-20 16:38:30 -0700174 HDD2GHZCHAN(2412, 1, 0) ,
175 HDD2GHZCHAN(2417, 2, 0) ,
176 HDD2GHZCHAN(2422, 3, 0) ,
177 HDD2GHZCHAN(2427, 4, 0) ,
178 HDD2GHZCHAN(2432, 5, 0) ,
179 HDD2GHZCHAN(2437, 6, 0) ,
180 HDD2GHZCHAN(2442, 7, 0) ,
181 HDD2GHZCHAN(2447, 8, 0) ,
182 HDD2GHZCHAN(2452, 9, 0) ,
183 HDD2GHZCHAN(2457, 10, 0) ,
184 HDD2GHZCHAN(2462, 11, 0) ,
185 HDD2GHZCHAN(2467, 12, 0) ,
186 HDD2GHZCHAN(2472, 13, 0) ,
187 HDD2GHZCHAN(2484, 14, 0) ,
188};
189
Jeff Johnson295189b2012-06-20 16:38:30 -0700190static struct ieee80211_channel hdd_social_channels_2_4_GHZ[] =
191{
192 HDD2GHZCHAN(2412, 1, 0) ,
193 HDD2GHZCHAN(2437, 6, 0) ,
194 HDD2GHZCHAN(2462, 11, 0) ,
195};
Jeff Johnson295189b2012-06-20 16:38:30 -0700196
197static struct ieee80211_channel hdd_channels_5_GHZ[] =
198{
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -0700199 HDD5GHZCHAN(4920, 240, 0) ,
200 HDD5GHZCHAN(4940, 244, 0) ,
201 HDD5GHZCHAN(4960, 248, 0) ,
202 HDD5GHZCHAN(4980, 252, 0) ,
203 HDD5GHZCHAN(5040, 208, 0) ,
204 HDD5GHZCHAN(5060, 212, 0) ,
205 HDD5GHZCHAN(5080, 216, 0) ,
Jeff Johnson295189b2012-06-20 16:38:30 -0700206 HDD5GHZCHAN(5180, 36, 0) ,
207 HDD5GHZCHAN(5200, 40, 0) ,
208 HDD5GHZCHAN(5220, 44, 0) ,
209 HDD5GHZCHAN(5240, 48, 0) ,
210 HDD5GHZCHAN(5260, 52, 0) ,
211 HDD5GHZCHAN(5280, 56, 0) ,
212 HDD5GHZCHAN(5300, 60, 0) ,
213 HDD5GHZCHAN(5320, 64, 0) ,
214 HDD5GHZCHAN(5500,100, 0) ,
215 HDD5GHZCHAN(5520,104, 0) ,
216 HDD5GHZCHAN(5540,108, 0) ,
217 HDD5GHZCHAN(5560,112, 0) ,
218 HDD5GHZCHAN(5580,116, 0) ,
219 HDD5GHZCHAN(5600,120, 0) ,
220 HDD5GHZCHAN(5620,124, 0) ,
221 HDD5GHZCHAN(5640,128, 0) ,
222 HDD5GHZCHAN(5660,132, 0) ,
223 HDD5GHZCHAN(5680,136, 0) ,
224 HDD5GHZCHAN(5700,140, 0) ,
Leo Chang80de3c22013-11-26 10:52:12 -0800225#ifdef FEATURE_WLAN_CH144
226 HDD5GHZCHAN(5720,144, 0) ,
227#endif /* FEATURE_WLAN_CH144 */
Jeff Johnson295189b2012-06-20 16:38:30 -0700228 HDD5GHZCHAN(5745,149, 0) ,
229 HDD5GHZCHAN(5765,153, 0) ,
230 HDD5GHZCHAN(5785,157, 0) ,
231 HDD5GHZCHAN(5805,161, 0) ,
232 HDD5GHZCHAN(5825,165, 0) ,
233};
234
235static struct ieee80211_rate g_mode_rates[] =
236{
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530237 HDD_G_MODE_RATETAB(10, 0x1, 0),
238 HDD_G_MODE_RATETAB(20, 0x2, 0),
239 HDD_G_MODE_RATETAB(55, 0x4, 0),
240 HDD_G_MODE_RATETAB(110, 0x8, 0),
241 HDD_G_MODE_RATETAB(60, 0x10, 0),
242 HDD_G_MODE_RATETAB(90, 0x20, 0),
243 HDD_G_MODE_RATETAB(120, 0x40, 0),
244 HDD_G_MODE_RATETAB(180, 0x80, 0),
245 HDD_G_MODE_RATETAB(240, 0x100, 0),
246 HDD_G_MODE_RATETAB(360, 0x200, 0),
247 HDD_G_MODE_RATETAB(480, 0x400, 0),
Jeff Johnson295189b2012-06-20 16:38:30 -0700248 HDD_G_MODE_RATETAB(540, 0x800, 0),
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530249};
Jeff Johnson295189b2012-06-20 16:38:30 -0700250
251static struct ieee80211_rate a_mode_rates[] =
252{
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530253 HDD_G_MODE_RATETAB(60, 0x10, 0),
254 HDD_G_MODE_RATETAB(90, 0x20, 0),
255 HDD_G_MODE_RATETAB(120, 0x40, 0),
256 HDD_G_MODE_RATETAB(180, 0x80, 0),
257 HDD_G_MODE_RATETAB(240, 0x100, 0),
258 HDD_G_MODE_RATETAB(360, 0x200, 0),
259 HDD_G_MODE_RATETAB(480, 0x400, 0),
Jeff Johnson295189b2012-06-20 16:38:30 -0700260 HDD_G_MODE_RATETAB(540, 0x800, 0),
261};
262
263static struct ieee80211_supported_band wlan_hdd_band_2_4_GHZ =
264{
265 .channels = hdd_channels_2_4_GHZ,
266 .n_channels = ARRAY_SIZE(hdd_channels_2_4_GHZ),
267 .band = IEEE80211_BAND_2GHZ,
268 .bitrates = g_mode_rates,
269 .n_bitrates = g_mode_rates_size,
270 .ht_cap.ht_supported = 1,
271 .ht_cap.cap = IEEE80211_HT_CAP_SGI_20
272 | IEEE80211_HT_CAP_GRN_FLD
273 | IEEE80211_HT_CAP_DSSSCCK40
274 | IEEE80211_HT_CAP_LSIG_TXOP_PROT,
275 .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
276 .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
277 .ht_cap.mcs.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
278 .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ),
279 .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
280};
281
Jeff Johnson295189b2012-06-20 16:38:30 -0700282static struct ieee80211_supported_band wlan_hdd_band_p2p_2_4_GHZ =
283{
284 .channels = hdd_social_channels_2_4_GHZ,
285 .n_channels = ARRAY_SIZE(hdd_social_channels_2_4_GHZ),
286 .band = IEEE80211_BAND_2GHZ,
287 .bitrates = g_mode_rates,
288 .n_bitrates = g_mode_rates_size,
289 .ht_cap.ht_supported = 1,
290 .ht_cap.cap = IEEE80211_HT_CAP_SGI_20
291 | IEEE80211_HT_CAP_GRN_FLD
292 | IEEE80211_HT_CAP_DSSSCCK40
293 | IEEE80211_HT_CAP_LSIG_TXOP_PROT,
294 .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
295 .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
296 .ht_cap.mcs.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
297 .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ),
298 .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
299};
Jeff Johnson295189b2012-06-20 16:38:30 -0700300
301static struct ieee80211_supported_band wlan_hdd_band_5_GHZ =
302{
303 .channels = hdd_channels_5_GHZ,
304 .n_channels = ARRAY_SIZE(hdd_channels_5_GHZ),
305 .band = IEEE80211_BAND_5GHZ,
306 .bitrates = a_mode_rates,
307 .n_bitrates = a_mode_rates_size,
308 .ht_cap.ht_supported = 1,
309 .ht_cap.cap = IEEE80211_HT_CAP_SGI_20
310 | IEEE80211_HT_CAP_GRN_FLD
311 | IEEE80211_HT_CAP_DSSSCCK40
312 | IEEE80211_HT_CAP_LSIG_TXOP_PROT
313 | IEEE80211_HT_CAP_SGI_40
314 | IEEE80211_HT_CAP_SUP_WIDTH_20_40,
315 .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
316 .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
317 .ht_cap.mcs.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
318 .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ),
319 .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
320};
321
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530322/* This structure contain information what kind of frame are expected in
Jeff Johnson295189b2012-06-20 16:38:30 -0700323 TX/RX direction for each kind of interface */
324static const struct ieee80211_txrx_stypes
325wlan_hdd_txrx_stypes[NUM_NL80211_IFTYPES] = {
326 [NL80211_IFTYPE_STATION] = {
327 .tx = 0xffff,
328 .rx = BIT(SIR_MAC_MGMT_ACTION) |
329 BIT(SIR_MAC_MGMT_PROBE_REQ),
330 },
331 [NL80211_IFTYPE_AP] = {
332 .tx = 0xffff,
333 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
334 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
335 BIT(SIR_MAC_MGMT_PROBE_REQ) |
336 BIT(SIR_MAC_MGMT_DISASSOC) |
337 BIT(SIR_MAC_MGMT_AUTH) |
338 BIT(SIR_MAC_MGMT_DEAUTH) |
339 BIT(SIR_MAC_MGMT_ACTION),
340 },
Jeff Johnsonbc006202013-04-29 14:05:30 -0700341 [NL80211_IFTYPE_ADHOC] = {
342 .tx = 0xffff,
343 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
344 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
345 BIT(SIR_MAC_MGMT_PROBE_REQ) |
346 BIT(SIR_MAC_MGMT_DISASSOC) |
347 BIT(SIR_MAC_MGMT_AUTH) |
348 BIT(SIR_MAC_MGMT_DEAUTH) |
349 BIT(SIR_MAC_MGMT_ACTION),
350 },
Jeff Johnson295189b2012-06-20 16:38:30 -0700351 [NL80211_IFTYPE_P2P_CLIENT] = {
352 .tx = 0xffff,
353 .rx = BIT(SIR_MAC_MGMT_ACTION) |
354 BIT(SIR_MAC_MGMT_PROBE_REQ),
355 },
356 [NL80211_IFTYPE_P2P_GO] = {
357 /* This is also same as for SoftAP */
358 .tx = 0xffff,
359 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
360 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
361 BIT(SIR_MAC_MGMT_PROBE_REQ) |
362 BIT(SIR_MAC_MGMT_DISASSOC) |
363 BIT(SIR_MAC_MGMT_AUTH) |
364 BIT(SIR_MAC_MGMT_DEAUTH) |
365 BIT(SIR_MAC_MGMT_ACTION),
366 },
Jeff Johnson295189b2012-06-20 16:38:30 -0700367};
368
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800369#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800370static const struct ieee80211_iface_limit
371wlan_hdd_iface_limit[] = {
372 {
Sunil Ravia72c3992013-01-31 06:12:22 -0800373 /* max = 3 ; Our driver create two interfaces during driver init
374 * wlan0 and p2p0 interfaces. p2p0 is considered as station
375 * interface until a group is formed. In JB architecture, once the
376 * group is formed, interface type of p2p0 is changed to P2P GO or
377 * Client.
378 * When supplicant remove the group, it first issue a set interface
379 * cmd to change the mode back to Station. In JB this works fine as
380 * we advertize two station type interface during driver init.
381 * Some vendors create separate interface for P2P GO/Client,
382 * after group formation(Third one). But while group remove
383 * supplicant first tries to change the mode(3rd interface) to STATION
384 * But as we advertized only two sta type interfaces nl80211 was
385 * returning error for the third one which was leading to failure in
386 * delete interface. Ideally while removing the group, supplicant
387 * should not try to change the 3rd interface mode to Station type.
388 * Till we get a fix in wpa_supplicant, we advertize max STA
389 * interface type to 3
390 */
391 .max = 3,
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800392 .types = BIT(NL80211_IFTYPE_STATION),
393 },
394 {
395 .max = 1,
Jeff Johnsonbc006202013-04-29 14:05:30 -0700396 .types = BIT(NL80211_IFTYPE_ADHOC) | BIT(NL80211_IFTYPE_AP),
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800397 },
398 {
399 .max = 1,
400 .types = BIT(NL80211_IFTYPE_P2P_GO) |
401 BIT(NL80211_IFTYPE_P2P_CLIENT),
402 },
403};
404
405/* By default, only single channel concurrency is allowed */
406static struct ieee80211_iface_combination
407wlan_hdd_iface_combination = {
408 .limits = wlan_hdd_iface_limit,
409 .num_different_channels = 1,
Sunil Ravia72c3992013-01-31 06:12:22 -0800410 /*
411 * max = WLAN_MAX_INTERFACES ; JellyBean architecture creates wlan0
412 * and p2p0 interfaces during driver init
413 * Some vendors create separate interface for P2P operations.
414 * wlan0: STA interface
415 * p2p0: P2P Device interface, action frames goes
416 * through this interface.
417 * p2p-xx: P2P interface, After GO negotiation this interface is
418 * created for p2p operations(GO/CLIENT interface).
419 */
420 .max_interfaces = WLAN_MAX_INTERFACES,
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800421 .n_limits = ARRAY_SIZE(wlan_hdd_iface_limit),
422 .beacon_int_infra_match = false,
423};
424#endif
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800425
Jeff Johnson295189b2012-06-20 16:38:30 -0700426static struct cfg80211_ops wlan_hdd_cfg80211_ops;
427
428/* Data rate 100KBPS based on IE Index */
429struct index_data_rate_type
430{
431 v_U8_t beacon_rate_index;
432 v_U16_t supported_rate[4];
433};
434
435/* 11B, 11G Rate table include Basic rate and Extended rate
436 The IDX field is the rate index
437 The HI field is the rate when RSSI is strong or being ignored
438 (in this case we report actual rate)
439 The MID field is the rate when RSSI is moderate
440 (in this case we cap 11b rates at 5.5 and 11g rates at 24)
441 The LO field is the rate when RSSI is low
442 (in this case we don't report rates, actual current rate used)
443 */
444static const struct
445{
446 v_U8_t beacon_rate_index;
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -0700447 v_U16_t supported_rate[4];
Jeff Johnson295189b2012-06-20 16:38:30 -0700448} supported_data_rate[] =
449{
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -0700450/* IDX HI HM LM LO (RSSI-based index */
451 {2, { 10, 10, 10, 0}},
452 {4, { 20, 20, 10, 0}},
453 {11, { 55, 20, 10, 0}},
454 {12, { 60, 55, 20, 0}},
455 {18, { 90, 55, 20, 0}},
456 {22, {110, 55, 20, 0}},
457 {24, {120, 90, 60, 0}},
458 {36, {180, 120, 60, 0}},
459 {44, {220, 180, 60, 0}},
460 {48, {240, 180, 90, 0}},
461 {66, {330, 180, 90, 0}},
462 {72, {360, 240, 90, 0}},
463 {96, {480, 240, 120, 0}},
464 {108, {540, 240, 120, 0}}
Jeff Johnson295189b2012-06-20 16:38:30 -0700465};
466
467/* MCS Based rate table */
468static struct index_data_rate_type supported_mcs_rate[] =
469{
470/* MCS L20 L40 S20 S40 */
471 {0, {65, 135, 72, 150}},
472 {1, {130, 270, 144, 300}},
473 {2, {195, 405, 217, 450}},
474 {3, {260, 540, 289, 600}},
475 {4, {390, 810, 433, 900}},
476 {5, {520, 1080, 578, 1200}},
477 {6, {585, 1215, 650, 1350}},
478 {7, {650, 1350, 722, 1500}}
479};
480
Leo Chang6f8870f2013-03-26 18:11:36 -0700481#ifdef WLAN_FEATURE_11AC
482
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530483#define DATA_RATE_11AC_MCS_MASK 0x03
Leo Chang6f8870f2013-03-26 18:11:36 -0700484
485struct index_vht_data_rate_type
486{
487 v_U8_t beacon_rate_index;
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530488 v_U16_t supported_VHT80_rate[2];
489 v_U16_t supported_VHT40_rate[2];
490 v_U16_t supported_VHT20_rate[2];
Leo Chang6f8870f2013-03-26 18:11:36 -0700491};
492
493typedef enum
494{
495 DATA_RATE_11AC_MAX_MCS_7,
496 DATA_RATE_11AC_MAX_MCS_8,
497 DATA_RATE_11AC_MAX_MCS_9,
498 DATA_RATE_11AC_MAX_MCS_NA
499} eDataRate11ACMaxMcs;
500
501/* MCS Based VHT rate table */
502static struct index_vht_data_rate_type supported_vht_mcs_rate[] =
503{
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530504/* MCS L80 S80 L40 S40 L20 S40*/
505 {0, {293, 325}, {135, 150}, {65, 72}},
506 {1, {585, 650}, {270, 300}, {130, 144}},
507 {2, {878, 975}, {405, 450}, {195, 217}},
508 {3, {1170, 1300}, {540, 600}, {260, 289}},
509 {4, {1755, 1950}, {810, 900}, {390, 433}},
510 {5, {2340, 2600}, {1080, 1200}, {520, 578}},
511 {6, {2633, 2925}, {1215, 1350}, {585, 650}},
512 {7, {2925, 3250}, {1350, 1500}, {650, 722}},
513 {8, {3510, 3900}, {1620, 1800}, {780, 867}},
514 {9, {3900, 4333}, {1800, 2000}, {780, 867}}
Leo Chang6f8870f2013-03-26 18:11:36 -0700515};
516#endif /* WLAN_FEATURE_11AC */
517
Jeff Johnson295189b2012-06-20 16:38:30 -0700518extern struct net_device_ops net_ops_struct;
519
Leo Chang9056f462013-08-01 19:21:11 -0700520#ifdef WLAN_NL80211_TESTMODE
521enum wlan_hdd_tm_attr
522{
523 WLAN_HDD_TM_ATTR_INVALID = 0,
524 WLAN_HDD_TM_ATTR_CMD = 1,
525 WLAN_HDD_TM_ATTR_DATA = 2,
526 WLAN_HDD_TM_ATTR_TYPE = 3,
527 /* keep last */
528 WLAN_HDD_TM_ATTR_AFTER_LAST,
529 WLAN_HDD_TM_ATTR_MAX = WLAN_HDD_TM_ATTR_AFTER_LAST - 1,
530};
531
532enum wlan_hdd_tm_cmd
533{
534 WLAN_HDD_TM_CMD_WLAN_HB = 1,
535};
536
537#define WLAN_HDD_TM_DATA_MAX_LEN 5000
538
539static const struct nla_policy wlan_hdd_tm_policy[WLAN_HDD_TM_ATTR_MAX + 1] =
540{
541 [WLAN_HDD_TM_ATTR_CMD] = { .type = NLA_U32 },
542 [WLAN_HDD_TM_ATTR_DATA] = { .type = NLA_BINARY,
543 .len = WLAN_HDD_TM_DATA_MAX_LEN },
544};
545#endif /* WLAN_NL80211_TESTMODE */
546
Rajesh Chauhan98a31f82014-01-06 20:15:25 -0800547#ifdef FEATURE_WLAN_CH_AVOID
548/*
549 * FUNCTION: wlan_hdd_send_avoid_freq_event
550 * This is called when wlan driver needs to send vendor specific
551 * avoid frequency range event to userspace
552 */
553int wlan_hdd_send_avoid_freq_event(hdd_context_t *pHddCtx,
554 tHddAvoidFreqList *pAvoidFreqList)
555{
556 struct sk_buff *vendor_event;
557
558 ENTER();
559
560 if (!pHddCtx)
561 {
562 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
563 "%s: HDD context is null", __func__);
564 return -1;
565 }
566
567 if (!pAvoidFreqList)
568 {
569 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
570 "%s: pAvoidFreqList is null", __func__);
571 return -1;
572 }
573
574 vendor_event = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
575 sizeof(tHddAvoidFreqList),
576 QCOM_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY_INDEX,
577 GFP_KERNEL);
578 if (!vendor_event)
579 {
580 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
581 "%s: cfg80211_vendor_event_alloc failed", __func__);
582 return -1;
583 }
584
585 memcpy(skb_put(vendor_event, sizeof(tHddAvoidFreqList)),
586 (void *)pAvoidFreqList, sizeof(tHddAvoidFreqList));
587
588 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
589
590 EXIT();
591 return 0;
592}
593#endif /* FEATURE_WLAN_CH_AVOID */
594
595/* vendor specific events */
596static const struct nl80211_vendor_cmd_info wlan_hdd_cfg80211_vendor_events[] =
597{
598#ifdef FEATURE_WLAN_CH_AVOID
599 {
600 .vendor_id = QCOM_NL80211_VENDOR_ID,
601 .subcmd = QCOM_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY
602 },
603#endif /* FEATURE_WLAN_CH_AVOID */
604};
605
Jeff Johnson295189b2012-06-20 16:38:30 -0700606/*
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +0530607 * FUNCTION: wlan_hdd_cfg80211_wiphy_alloc
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530608 * This function is called by hdd_wlan_startup()
609 * during initialization.
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +0530610 * This function is used to allocate wiphy structure.
Jeff Johnson295189b2012-06-20 16:38:30 -0700611 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +0530612struct wiphy *wlan_hdd_cfg80211_wiphy_alloc(int priv_size)
Jeff Johnson295189b2012-06-20 16:38:30 -0700613{
614 struct wiphy *wiphy;
615 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530616 /*
617 * Create wiphy device
Jeff Johnson295189b2012-06-20 16:38:30 -0700618 */
619 wiphy = wiphy_new(&wlan_hdd_cfg80211_ops, priv_size);
620
621 if (!wiphy)
622 {
623 /* Print error and jump into err label and free the memory */
624 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wiphy init failed", __func__);
625 return NULL;
626 }
627
628 return wiphy;
629}
630
631/*
632 * FUNCTION: wlan_hdd_cfg80211_update_band
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530633 * This function is called from the supplicant through a
Jeff Johnson295189b2012-06-20 16:38:30 -0700634 * private ioctl to change the band value
635 */
636int wlan_hdd_cfg80211_update_band(struct wiphy *wiphy, eCsrBand eBand)
637{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +0530638 int i, j;
639 eNVChannelEnabledType channelEnabledState;
640
Jeff Johnsone7245742012-09-05 17:12:55 -0700641 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +0530642
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +0530643 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
Jeff Johnson295189b2012-06-20 16:38:30 -0700644 {
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +0530645
646 if (NULL == wiphy->bands[i])
647 {
648 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[i] is NULL, i = %d",
649 __func__, i);
650 continue;
651 }
652
653 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
654 {
655 struct ieee80211_supported_band *band = wiphy->bands[i];
656
657 channelEnabledState = vos_nv_getChannelEnabledState(
658 band->channels[j].hw_value);
659
660 if (IEEE80211_BAND_2GHZ == i && eCSR_BAND_5G == eBand) // 5G only
661 {
662 // Enable Social channels for P2P
663 if (WLAN_HDD_IS_SOCIAL_CHANNEL(band->channels[j].center_freq) &&
664 NV_CHANNEL_ENABLE == channelEnabledState)
665 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
666 else
667 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
668 continue;
669 }
670 else if (IEEE80211_BAND_5GHZ == i && eCSR_BAND_24 == eBand) // 2G only
671 {
672 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
673 continue;
674 }
675
676 if (NV_CHANNEL_DISABLE == channelEnabledState ||
677 NV_CHANNEL_INVALID == channelEnabledState)
678 {
679 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
680 }
681 else if (NV_CHANNEL_DFS == channelEnabledState)
682 {
683 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
684 band->channels[j].flags |= IEEE80211_CHAN_RADAR;
685 }
686 else
687 {
688 band->channels[j].flags &= ~(IEEE80211_CHAN_DISABLED
689 |IEEE80211_CHAN_RADAR);
690 }
691 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700692 }
693 return 0;
694}
695/*
696 * FUNCTION: wlan_hdd_cfg80211_init
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530697 * This function is called by hdd_wlan_startup()
698 * during initialization.
Jeff Johnson295189b2012-06-20 16:38:30 -0700699 * This function is used to initialize and register wiphy structure.
700 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +0530701int wlan_hdd_cfg80211_init(struct device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -0700702 struct wiphy *wiphy,
703 hdd_config_t *pCfg
704 )
705{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +0530706 int i, j;
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +0530707 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
708
Jeff Johnsone7245742012-09-05 17:12:55 -0700709 ENTER();
710
Jeff Johnson295189b2012-06-20 16:38:30 -0700711 /* Now bind the underlying wlan device with wiphy */
712 set_wiphy_dev(wiphy, dev);
713
714 wiphy->mgmt_stypes = wlan_hdd_txrx_stypes;
Amar Singhalfddc28c2013-09-05 13:03:40 -0700715
Kiet Lam6c583332013-10-14 05:37:09 +0530716#ifndef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -0700717 /* the flag for the other case would be initialzed in
718 vos_init_wiphy_from_nv_bin */
Amar Singhal0a402232013-10-11 20:57:16 -0700719 wiphy->flags |= WIPHY_FLAG_STRICT_REGULATORY;
Kiet Lam6c583332013-10-14 05:37:09 +0530720#endif
Amar Singhala49cbc52013-10-08 18:37:44 -0700721
Amar Singhalfddc28c2013-09-05 13:03:40 -0700722 /* This will disable updating of NL channels from passive to
723 * active if a beacon is received on passive channel. */
724 wiphy->flags |= WIPHY_FLAG_DISABLE_BEACON_HINTS;
Amar Singhalf0073192013-09-20 12:34:56 -0700725
Amar Singhalfddc28c2013-09-05 13:03:40 -0700726
Amar Singhala49cbc52013-10-08 18:37:44 -0700727
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700728#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -0700729 wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME
730 | WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD
731 | WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL
Jeff Johnsone7245742012-09-05 17:12:55 -0700732 | WIPHY_FLAG_OFFCHAN_TX;
Kiet Lam6c583332013-10-14 05:37:09 +0530733 wiphy->country_ie_pref = NL80211_COUNTRY_IE_IGNORE_CORE;
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700734#endif
Amar Singhala49cbc52013-10-08 18:37:44 -0700735
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800736#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowda640728a2013-03-28 12:21:54 -0700737 if (pCfg->isFastTransitionEnabled
James Zmuda77fb5ae2013-01-29 08:00:17 -0800738#ifdef FEATURE_WLAN_LFR
Srinivas Girigowda640728a2013-03-28 12:21:54 -0700739 || pCfg->isFastRoamIniFeatureEnabled
740#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800741#ifdef FEATURE_WLAN_ESE
742 || pCfg->isEseIniFeatureEnabled
Srinivas Girigowda640728a2013-03-28 12:21:54 -0700743#endif
744 )
745 {
746 wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM;
747 }
James Zmuda77fb5ae2013-01-29 08:00:17 -0800748#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -0800749#ifdef FEATURE_WLAN_TDLS
750 wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS
751 | WIPHY_FLAG_TDLS_EXTERNAL_SETUP;
752#endif
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +0530753#ifdef FEATURE_WLAN_SCAN_PNO
Hardik Kantilal Patel3dfd8792013-11-13 20:34:57 +0530754 if (pCfg->configPNOScanSupport)
755 {
756 wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN;
757 wiphy->max_sched_scan_ssids = SIR_PNO_MAX_SUPP_NETWORKS;
758 wiphy->max_match_sets = SIR_PNO_MAX_SUPP_NETWORKS;
759 wiphy->max_sched_scan_ie_len = SIR_MAC_MAX_IE_LENGTH;
760 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +0530761#endif/*FEATURE_WLAN_SCAN_PNO*/
Mohit Khanna698ba2a2012-12-04 15:08:18 -0800762
Amar Singhalfddc28c2013-09-05 13:03:40 -0700763#ifdef CONFIG_ENABLE_LINUX_REG
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -0700764 /* even with WIPHY_FLAG_CUSTOM_REGULATORY,
765 driver can still register regulatory callback and
Amar Singhalfddc28c2013-09-05 13:03:40 -0700766 it will get regulatory settings in wiphy->band[], but
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -0700767 driver need to determine what to do with both
768 regulatory settings */
Amar Singhalfddc28c2013-09-05 13:03:40 -0700769
770 wiphy->reg_notifier = wlan_hdd_linux_reg_notifier;
Amar Singhala49cbc52013-10-08 18:37:44 -0700771#else
772 wiphy->reg_notifier = wlan_hdd_crda_reg_notifier;
Amar Singhalfddc28c2013-09-05 13:03:40 -0700773#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700774
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530775 wiphy->max_scan_ssids = MAX_SCAN_SSID;
776
Madan Mohan Koyyalamudi6815b162013-07-19 17:17:46 +0530777 wiphy->max_scan_ie_len = SIR_MAC_MAX_IE_LENGTH;
Jeff Johnson295189b2012-06-20 16:38:30 -0700778
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +0530779 wiphy->max_acl_mac_addrs = MAX_ACL_MAC_ADDRESS;
780
Jeff Johnson295189b2012-06-20 16:38:30 -0700781 /* Supports STATION & AD-HOC modes right now */
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530782 wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -0700783 | BIT(NL80211_IFTYPE_ADHOC)
Jeff Johnson295189b2012-06-20 16:38:30 -0700784 | BIT(NL80211_IFTYPE_P2P_CLIENT)
785 | BIT(NL80211_IFTYPE_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -0700786 | BIT(NL80211_IFTYPE_AP);
787
Rashmi Ramannabd3feb72014-02-25 16:14:48 +0530788 if( pCfg->advertiseConcurrentOperation )
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800789 {
Rashmi Ramannabd3feb72014-02-25 16:14:48 +0530790#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
791 if( pCfg->enableMCC )
792 {
793 /* Currently, supports up to two channels */
794 wlan_hdd_iface_combination.num_different_channels = 2;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800795
Rashmi Ramannabd3feb72014-02-25 16:14:48 +0530796 if( !pCfg->allowMCCGODiffBI )
797 wlan_hdd_iface_combination.beacon_int_infra_match = true;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800798
Rashmi Ramannabd3feb72014-02-25 16:14:48 +0530799 }
800 wiphy->iface_combinations = &wlan_hdd_iface_combination;
801 wiphy->n_iface_combinations = 1;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800802#endif
Rashmi Ramannabd3feb72014-02-25 16:14:48 +0530803 }
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800804
Jeff Johnson295189b2012-06-20 16:38:30 -0700805 /* Before registering we need to update the ht capabilitied based
806 * on ini values*/
807 if( !pCfg->ShortGI20MhzEnable )
808 {
809 wlan_hdd_band_2_4_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
810 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
811 wlan_hdd_band_p2p_2_4_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
812 }
813
814 if( !pCfg->ShortGI40MhzEnable )
815 {
816 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_40;
817 }
818
819 if( !pCfg->nChannelBondingMode5GHz )
820 {
821 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
822 }
823
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +0530824 wiphy->bands[IEEE80211_BAND_2GHZ] = &wlan_hdd_band_2_4_GHZ;
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +0530825 if (true == hdd_is_5g_supported(pHddCtx))
826 {
827 wiphy->bands[IEEE80211_BAND_5GHZ] = &wlan_hdd_band_5_GHZ;
828 }
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +0530829
830 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
831 {
832
833 if (NULL == wiphy->bands[i])
834 {
835 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[i] is NULL, i = %d",
836 __func__, i);
837 continue;
838 }
839
840 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
841 {
842 struct ieee80211_supported_band *band = wiphy->bands[i];
843
844 if (IEEE80211_BAND_2GHZ == i && eCSR_BAND_5G == pCfg->nBandCapability) // 5G only
845 {
846 // Enable social channels for P2P
847 if (WLAN_HDD_IS_SOCIAL_CHANNEL(band->channels[j].center_freq))
848 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
849 else
850 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
851 continue;
852 }
853 else if (IEEE80211_BAND_5GHZ == i && eCSR_BAND_24 == pCfg->nBandCapability) // 2G only
854 {
855 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
856 continue;
857 }
858 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700859 }
860 /*Initialise the supported cipher suite details*/
861 wiphy->cipher_suites = hdd_cipher_suites;
862 wiphy->n_cipher_suites = ARRAY_SIZE(hdd_cipher_suites);
863
864 /*signal strength in mBm (100*dBm) */
865 wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
866
867#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Jeff Johnson295189b2012-06-20 16:38:30 -0700868 wiphy->max_remain_on_channel_duration = 1000;
869#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700870
Rajesh Chauhan98a31f82014-01-06 20:15:25 -0800871 wiphy->n_vendor_commands = 0;
872 wiphy->vendor_events = wlan_hdd_cfg80211_vendor_events;
873 wiphy->n_vendor_events = ARRAY_SIZE(wlan_hdd_cfg80211_vendor_events);
874
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +0530875 EXIT();
876 return 0;
877}
878
879/* In this function we are registering wiphy. */
880int wlan_hdd_cfg80211_register(struct wiphy *wiphy)
881{
882 ENTER();
883 /* Register our wiphy dev with cfg80211 */
Jeff Johnson295189b2012-06-20 16:38:30 -0700884 if (0 > wiphy_register(wiphy))
885 {
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +0530886 /* print error */
Jeff Johnson295189b2012-06-20 16:38:30 -0700887 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
888 return -EIO;
889 }
890
891 EXIT();
892 return 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530893}
Jeff Johnson295189b2012-06-20 16:38:30 -0700894
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +0530895/* In this function we are updating channel list when,
896 regulatory domain is FCC and country code is US.
897 Here In FCC standard 5GHz UNII-1 Bands are indoor only.
898 As per FCC smart phone is not a indoor device.
899 GO should not opeate on indoor channels */
900void wlan_hdd_cfg80211_update_reg_info(struct wiphy *wiphy)
901{
902 int j;
903 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
904 tANI_U8 defaultCountryCode[3] = SME_INVALID_COUNTRY_CODE;
905 //Default counrtycode from NV at the time of wiphy initialization.
906 if (eHAL_STATUS_SUCCESS != sme_GetDefaultCountryCodeFrmNv(pHddCtx->hHal,
907 &defaultCountryCode[0]))
908 {
Jeff Johnson0299d0a2013-10-30 12:37:43 -0700909 hddLog(LOGE, FL("Failed to get default country code from NV"));
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +0530910 }
911 if ((defaultCountryCode[0]== 'U') && (defaultCountryCode[1]=='S'))
912 {
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +0530913 if (NULL == wiphy->bands[IEEE80211_BAND_5GHZ])
914 {
915 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[IEEE80211_BAND_5GHZ] is NULL",__func__ );
916 return;
917 }
918 for (j = 0; j < wiphy->bands[IEEE80211_BAND_5GHZ]->n_channels; j++)
919 {
920 struct ieee80211_supported_band *band = wiphy->bands[IEEE80211_BAND_5GHZ];
921 // Mark UNII -1 band channel as passive
922 if (WLAN_HDD_CHANNEL_IN_UNII_1_BAND(band->channels[j].center_freq))
923 band->channels[j].flags |= IEEE80211_CHAN_PASSIVE_SCAN;
924 }
925 }
926}
927
Jeff Johnson295189b2012-06-20 16:38:30 -0700928/* In this function we will do all post VOS start initialization.
929 In this function we will register for all frame in which supplicant
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530930 is interested.
Jeff Johnson295189b2012-06-20 16:38:30 -0700931*/
932void wlan_hdd_cfg80211_post_voss_start(hdd_adapter_t* pAdapter)
933{
Jeff Johnson295189b2012-06-20 16:38:30 -0700934 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
935 /* Register for all P2P action, public action etc frames */
936 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
937
Jeff Johnsone7245742012-09-05 17:12:55 -0700938 ENTER();
939
Jeff Johnson295189b2012-06-20 16:38:30 -0700940 /* Right now we are registering these frame when driver is getting
941 initialized. Once we will move to 2.6.37 kernel, in which we have
942 frame register ops, we will move this code as a part of that */
943 /* GAS Initial Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530944 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Jeff Johnson295189b2012-06-20 16:38:30 -0700945 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
946
947 /* GAS Initial Response */
948 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
949 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530950
Jeff Johnson295189b2012-06-20 16:38:30 -0700951 /* GAS Comeback Request */
952 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
953 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
954
955 /* GAS Comeback Response */
956 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
957 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
958
959 /* P2P Public Action */
960 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530961 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -0700962 P2P_PUBLIC_ACTION_FRAME_SIZE );
963
964 /* P2P Action */
965 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
966 (v_U8_t*)P2P_ACTION_FRAME,
967 P2P_ACTION_FRAME_SIZE );
Chet Lanctot186b5732013-03-18 10:26:30 -0700968
Gopichand Nakkalae3d56e72013-04-21 23:33:32 +0530969 /* WNM BSS Transition Request frame */
970 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
971 (v_U8_t*)WNM_BSS_ACTION_FRAME,
972 WNM_BSS_ACTION_FRAME_SIZE );
Leela Venkata Kiran Kumar Reddy Chiralae8e62c82013-10-29 18:23:26 -0700973
974 /* WNM-Notification */
975 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
976 (v_U8_t*)WNM_NOTIFICATION_FRAME,
977 WNM_NOTIFICATION_FRAME_SIZE );
978
Leela Venkata Kiran Kumar Reddy Chiralae8e62c82013-10-29 18:23:26 -0700979#ifdef WLAN_FEATURE_11W
980 /* SA Query Response Action Frame */
981 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
982 (v_U8_t*)SA_QUERY_FRAME_RSP,
983 SA_QUERY_FRAME_RSP_SIZE );
984#endif /* WLAN_FEATURE_11W */
Jeff Johnson295189b2012-06-20 16:38:30 -0700985}
986
987void wlan_hdd_cfg80211_pre_voss_stop(hdd_adapter_t* pAdapter)
988{
Jeff Johnson295189b2012-06-20 16:38:30 -0700989 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
990 /* Register for all P2P action, public action etc frames */
991 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
992
Jeff Johnsone7245742012-09-05 17:12:55 -0700993 ENTER();
994
Jeff Johnson295189b2012-06-20 16:38:30 -0700995 /* Right now we are registering these frame when driver is getting
996 initialized. Once we will move to 2.6.37 kernel, in which we have
997 frame register ops, we will move this code as a part of that */
998 /* GAS Initial Request */
999
1000 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
1001 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
1002
1003 /* GAS Initial Response */
1004 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
1005 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301006
Jeff Johnson295189b2012-06-20 16:38:30 -07001007 /* GAS Comeback Request */
1008 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
1009 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
1010
1011 /* GAS Comeback Response */
1012 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
1013 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
1014
1015 /* P2P Public Action */
1016 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301017 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -07001018 P2P_PUBLIC_ACTION_FRAME_SIZE );
1019
1020 /* P2P Action */
1021 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
1022 (v_U8_t*)P2P_ACTION_FRAME,
1023 P2P_ACTION_FRAME_SIZE );
Leela Venkata Kiran Kumar Reddy Chiralae8e62c82013-10-29 18:23:26 -07001024 /* WNM-Notification */
1025 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
1026 (v_U8_t*)WNM_NOTIFICATION_FRAME,
1027 WNM_NOTIFICATION_FRAME_SIZE );
1028
Chet Lanctot186b5732013-03-18 10:26:30 -07001029#ifdef WLAN_FEATURE_11W
1030 /* SA Query Response Action Frame */
1031 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
1032 (v_U8_t*)SA_QUERY_FRAME_RSP,
1033 SA_QUERY_FRAME_RSP_SIZE );
1034#endif /* WLAN_FEATURE_11W */
Jeff Johnson295189b2012-06-20 16:38:30 -07001035}
1036
1037#ifdef FEATURE_WLAN_WAPI
1038void wlan_hdd_cfg80211_set_key_wapi(hdd_adapter_t* pAdapter, u8 key_index,
1039 const u8 *mac_addr, u8 *key , int key_Len)
1040{
1041 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
1042 tCsrRoamSetKey setKey;
1043 v_BOOL_t isConnected = TRUE;
1044 int status = 0;
1045 v_U32_t roamId= 0xFF;
1046 tANI_U8 *pKeyPtr = NULL;
1047 int n = 0;
1048
Arif Hussain6d2a3322013-11-17 19:50:10 -08001049 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07001050 __func__,pAdapter->device_mode);
1051
Gopichand Nakkalae7480202013-02-11 15:24:22 +05301052 vos_mem_zero(&setKey, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -07001053 setKey.keyId = key_index; // Store Key ID
1054 setKey.encType = eCSR_ENCRYPT_TYPE_WPI; // SET WAPI Encryption
1055 setKey.keyDirection = eSIR_TX_RX; // Key Directionn both TX and RX
1056 setKey.paeRole = 0 ; // the PAE role
1057 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
1058 {
1059 vos_set_macaddr_broadcast( (v_MACADDR_t *)setKey.peerMac );
1060 }
1061 else
1062 {
1063 isConnected = hdd_connIsConnected(pHddStaCtx);
1064 vos_mem_copy(setKey.peerMac,&pHddStaCtx->conn_info.bssId,WNI_CFG_BSSID_LEN);
1065 }
1066 setKey.keyLength = key_Len;
1067 pKeyPtr = setKey.Key;
1068 memcpy( pKeyPtr, key, key_Len);
1069
Arif Hussain6d2a3322013-11-17 19:50:10 -08001070 hddLog(VOS_TRACE_LEVEL_INFO,"%s: WAPI KEY LENGTH:0x%04x",
Jeff Johnson295189b2012-06-20 16:38:30 -07001071 __func__, key_Len);
1072 for (n = 0 ; n < key_Len; n++)
1073 hddLog(VOS_TRACE_LEVEL_INFO, "%s WAPI KEY Data[%d]:%02x ",
1074 __func__,n,setKey.Key[n]);
1075
1076 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
1077 if ( isConnected )
1078 {
1079 status= sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
1080 pAdapter->sessionId, &setKey, &roamId );
1081 }
1082 if ( status != 0 )
1083 {
1084 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1085 "[%4d] sme_RoamSetKey returned ERROR status= %d",
1086 __LINE__, status );
1087 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
1088 }
1089}
1090#endif /* FEATURE_WLAN_WAPI*/
1091
1092#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301093int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07001094 beacon_data_t **ppBeacon,
1095 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001096#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301097int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001098 beacon_data_t **ppBeacon,
1099 struct cfg80211_beacon_data *params,
1100 int dtim_period)
1101#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301102{
Jeff Johnson295189b2012-06-20 16:38:30 -07001103 int size;
1104 beacon_data_t *beacon = NULL;
1105 beacon_data_t *old = NULL;
1106 int head_len,tail_len;
1107
Jeff Johnsone7245742012-09-05 17:12:55 -07001108 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07001109 if (params->head && !params->head_len)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05301110 {
1111 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1112 FL("head_len is NULL"));
Jeff Johnson295189b2012-06-20 16:38:30 -07001113 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05301114 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001115
1116 old = pAdapter->sessionCtx.ap.beacon;
1117
1118 if (!params->head && !old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05301119 {
1120 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1121 FL("session(%d) old and new heads points to NULL"),
1122 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07001123 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05301124 }
1125
1126 if (params->tail && !params->tail_len)
1127 {
1128 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1129 FL("tail_len is zero but tail is not NULL"));
1130 return -EINVAL;
1131 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001132
Jeff Johnson295189b2012-06-20 16:38:30 -07001133#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,38))
1134 /* Kernel 3.0 is not updating dtim_period for set beacon */
1135 if (!params->dtim_period)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05301136 {
1137 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1138 FL("dtim period is 0"));
Jeff Johnson295189b2012-06-20 16:38:30 -07001139 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05301140 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001141#endif
1142
1143 if(params->head)
1144 head_len = params->head_len;
1145 else
1146 head_len = old->head_len;
1147
1148 if(params->tail || !old)
1149 tail_len = params->tail_len;
1150 else
1151 tail_len = old->tail_len;
1152
1153 size = sizeof(beacon_data_t) + head_len + tail_len;
1154
1155 beacon = kzalloc(size, GFP_KERNEL);
1156
1157 if( beacon == NULL )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05301158 {
1159 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1160 FL("Mem allocation for beacon failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -07001161 return -ENOMEM;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05301162 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001163
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001164#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07001165 if(params->dtim_period || !old )
1166 beacon->dtim_period = params->dtim_period;
1167 else
1168 beacon->dtim_period = old->dtim_period;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001169#else
1170 if(dtim_period || !old )
1171 beacon->dtim_period = dtim_period;
1172 else
1173 beacon->dtim_period = old->dtim_period;
1174#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301175
Jeff Johnson295189b2012-06-20 16:38:30 -07001176 beacon->head = ((u8 *) beacon) + sizeof(beacon_data_t);
1177 beacon->tail = beacon->head + head_len;
1178 beacon->head_len = head_len;
1179 beacon->tail_len = tail_len;
1180
1181 if(params->head) {
1182 memcpy (beacon->head,params->head,beacon->head_len);
1183 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301184 else {
Jeff Johnson295189b2012-06-20 16:38:30 -07001185 if(old)
1186 memcpy (beacon->head,old->head,beacon->head_len);
1187 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301188
Jeff Johnson295189b2012-06-20 16:38:30 -07001189 if(params->tail) {
1190 memcpy (beacon->tail,params->tail,beacon->tail_len);
1191 }
1192 else {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301193 if(old)
Jeff Johnson295189b2012-06-20 16:38:30 -07001194 memcpy (beacon->tail,old->tail,beacon->tail_len);
1195 }
1196
1197 *ppBeacon = beacon;
1198
1199 kfree(old);
1200
1201 return 0;
1202
1203}
Jeff Johnson295189b2012-06-20 16:38:30 -07001204
1205v_U8_t* wlan_hdd_cfg80211_get_ie_ptr(v_U8_t *pIes, int length, v_U8_t eid)
1206{
1207 int left = length;
1208 v_U8_t *ptr = pIes;
1209 v_U8_t elem_id,elem_len;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301210
Jeff Johnson295189b2012-06-20 16:38:30 -07001211 while(left >= 2)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301212 {
Jeff Johnson295189b2012-06-20 16:38:30 -07001213 elem_id = ptr[0];
1214 elem_len = ptr[1];
1215 left -= 2;
1216 if(elem_len > left)
1217 {
1218 hddLog(VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07001219 FL("****Invalid IEs eid = %d elem_len=%d left=%d*****"),
Jeff Johnson295189b2012-06-20 16:38:30 -07001220 eid,elem_len,left);
1221 return NULL;
1222 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301223 if (elem_id == eid)
Jeff Johnson295189b2012-06-20 16:38:30 -07001224 {
1225 return ptr;
1226 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301227
Jeff Johnson295189b2012-06-20 16:38:30 -07001228 left -= elem_len;
1229 ptr += (elem_len + 2);
1230 }
1231 return NULL;
1232}
1233
Jeff Johnson295189b2012-06-20 16:38:30 -07001234/* Check if rate is 11g rate or not */
1235static int wlan_hdd_rate_is_11g(u8 rate)
1236{
Sanjay Devnani28322e22013-06-21 16:13:40 -07001237 static const u8 gRateArray[8] = {12, 18, 24, 36, 48, 72, 96, 108}; /* actual rate * 2 */
Jeff Johnson295189b2012-06-20 16:38:30 -07001238 u8 i;
1239 for (i = 0; i < 8; i++)
1240 {
1241 if(rate == gRateArray[i])
1242 return TRUE;
1243 }
1244 return FALSE;
1245}
1246
1247/* Check for 11g rate and set proper 11g only mode */
1248static void wlan_hdd_check_11gmode(u8 *pIe, u8* require_ht,
1249 u8* pCheckRatesfor11g, eSapPhyMode* pSapHw_mode)
1250{
1251 u8 i, num_rates = pIe[0];
1252
1253 pIe += 1;
1254 for ( i = 0; i < num_rates; i++)
1255 {
1256 if( *pCheckRatesfor11g && (TRUE == wlan_hdd_rate_is_11g(pIe[i] & RATE_MASK)))
1257 {
1258 /* If rate set have 11g rate than change the mode to 11G */
1259 *pSapHw_mode = eSAP_DOT11_MODE_11g;
1260 if (pIe[i] & BASIC_RATE_MASK)
1261 {
1262 /* If we have 11g rate as basic rate, it means mode
1263 is 11g only mode.
1264 */
1265 *pSapHw_mode = eSAP_DOT11_MODE_11g_ONLY;
1266 *pCheckRatesfor11g = FALSE;
1267 }
1268 }
1269 else if((BASIC_RATE_MASK | WLAN_BSS_MEMBERSHIP_SELECTOR_HT_PHY) == pIe[i])
1270 {
1271 *require_ht = TRUE;
1272 }
1273 }
1274 return;
1275}
1276
1277static void wlan_hdd_set_sapHwmode(hdd_adapter_t *pHostapdAdapter)
1278{
1279 tsap_Config_t *pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
1280 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
1281 struct ieee80211_mgmt *pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
1282 u8 checkRatesfor11g = TRUE;
1283 u8 require_ht = FALSE;
1284 u8 *pIe=NULL;
1285
1286 pConfig->SapHw_mode= eSAP_DOT11_MODE_11b;
1287
1288 pIe = wlan_hdd_cfg80211_get_ie_ptr(&pMgmt_frame->u.beacon.variable[0],
1289 pBeacon->head_len, WLAN_EID_SUPP_RATES);
1290 if (pIe != NULL)
1291 {
1292 pIe += 1;
1293 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
1294 &pConfig->SapHw_mode);
1295 }
1296
1297 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
1298 WLAN_EID_EXT_SUPP_RATES);
1299 if (pIe != NULL)
1300 {
1301
1302 pIe += 1;
1303 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
1304 &pConfig->SapHw_mode);
1305 }
1306
1307 if( pConfig->channel > 14 )
1308 {
1309 pConfig->SapHw_mode= eSAP_DOT11_MODE_11a;
1310 }
1311
1312 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
1313 WLAN_EID_HT_CAPABILITY);
1314
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301315 if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07001316 {
1317 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n;
1318 if(require_ht)
1319 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n_ONLY;
1320 }
1321}
1322
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05301323static int wlan_hdd_add_ie(hdd_adapter_t* pHostapdAdapter, v_U8_t *genie,
1324 v_U8_t *total_ielen, v_U8_t *oui, v_U8_t oui_size)
1325{
Arif Hussaine7f3ea52013-09-12 21:56:36 -07001326 v_U16_t ielen = 0;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05301327 v_U8_t *pIe = NULL;
1328 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
1329
1330 pIe = wlan_hdd_get_vendor_oui_ie_ptr(oui, oui_size,
1331 pBeacon->tail, pBeacon->tail_len);
1332
1333 if (pIe)
1334 {
1335 ielen = pIe[1] + 2;
1336 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
1337 {
1338 vos_mem_copy(&genie[*total_ielen], pIe, ielen);
1339 }
1340 else
1341 {
1342 hddLog( VOS_TRACE_LEVEL_ERROR, "**Ie Length is too big***");
1343 return -EINVAL;
1344 }
1345 *total_ielen += ielen;
1346 }
1347 return 0;
1348}
1349
Arif Hussaine7f3ea52013-09-12 21:56:36 -07001350static void wlan_hdd_add_hostapd_conf_vsie(hdd_adapter_t* pHostapdAdapter,
1351 v_U8_t *genie, v_U8_t *total_ielen)
1352{
1353 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
1354 int left = pBeacon->tail_len;
1355 v_U8_t *ptr = pBeacon->tail;
1356 v_U8_t elem_id, elem_len;
1357 v_U16_t ielen = 0;
1358
1359 if ( NULL == ptr || 0 == left )
1360 return;
1361
1362 while (left >= 2)
1363 {
1364 elem_id = ptr[0];
1365 elem_len = ptr[1];
1366 left -= 2;
1367 if (elem_len > left)
1368 {
1369 hddLog( VOS_TRACE_LEVEL_ERROR,
1370 "****Invalid IEs eid = %d elem_len=%d left=%d*****",
1371 elem_id, elem_len, left);
1372 return;
1373 }
1374 if (IE_EID_VENDOR == elem_id)
1375 {
1376 /* skipping the VSIE's which we don't want to include or
1377 * it will be included by existing code
1378 */
1379 if ((memcmp( &ptr[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) != 0 ) &&
1380#ifdef WLAN_FEATURE_WFD
1381 (memcmp( &ptr[2], WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE) != 0) &&
1382#endif
1383 (memcmp( &ptr[2], WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
1384 (memcmp( &ptr[2], BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
1385 (memcmp( &ptr[2], "\x00\x50\xf2\x02", WPA_OUI_TYPE_SIZE) != 0) &&
1386 (memcmp( &ptr[2], WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
1387 (memcmp( &ptr[2], P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE) != 0))
1388 {
1389 ielen = ptr[1] + 2;
1390 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
1391 {
1392 vos_mem_copy(&genie[*total_ielen], ptr, ielen);
1393 *total_ielen += ielen;
1394 }
1395 else
1396 {
1397 hddLog( VOS_TRACE_LEVEL_ERROR,
1398 "IE Length is too big "
1399 "IEs eid=%d elem_len=%d total_ie_lent=%d",
1400 elem_id, elem_len, *total_ielen);
1401 }
1402 }
1403 }
1404
1405 left -= elem_len;
1406 ptr += (elem_len + 2);
1407 }
1408 return;
1409}
1410
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001411#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07001412static int wlan_hdd_cfg80211_update_apies(hdd_adapter_t* pHostapdAdapter,
1413 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001414#else
1415static int wlan_hdd_cfg80211_update_apies(hdd_adapter_t* pHostapdAdapter,
1416 struct cfg80211_beacon_data *params)
1417#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07001418{
1419 v_U8_t *genie;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05301420 v_U8_t total_ielen = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07001421 v_U8_t addIE[1] = {0};
Jeff Johnsone7245742012-09-05 17:12:55 -07001422 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07001423
1424 genie = vos_mem_malloc(MAX_GENIE_LEN);
1425
1426 if(genie == NULL) {
1427
1428 return -ENOMEM;
1429 }
1430
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05301431 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
1432 &total_ielen, WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07001433 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05301434 hddLog(LOGE,
1435 FL("Adding WPS IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05301436 ret = -EINVAL;
1437 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001438 }
1439
1440#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05301441 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
1442 &total_ielen, WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE))
1443 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05301444 hddLog(LOGE,
1445 FL("Adding WFD IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05301446 ret = -EINVAL;
1447 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001448 }
1449#endif
1450
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05301451 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
1452 &total_ielen, P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07001453 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05301454 hddLog(LOGE,
1455 FL("Adding P2P IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05301456 ret = -EINVAL;
1457 goto done;
1458 }
1459
1460 if (WLAN_HDD_SOFTAP == pHostapdAdapter->device_mode)
1461 {
Arif Hussaine7f3ea52013-09-12 21:56:36 -07001462 wlan_hdd_add_hostapd_conf_vsie(pHostapdAdapter, genie, &total_ielen);
Jeff Johnson295189b2012-06-20 16:38:30 -07001463 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001464
1465 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1466 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, genie, total_ielen, NULL,
1467 eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
1468 {
1469 hddLog(LOGE,
1470 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001471 ret = -EINVAL;
1472 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001473 }
1474
1475 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1476 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
1477 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
1478 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
1479 ==eHAL_STATUS_FAILURE)
1480 {
1481 hddLog(LOGE,
1482 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001483 ret = -EINVAL;
1484 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001485 }
1486
1487 // Added for ProResp IE
1488 if ( (params->proberesp_ies != NULL) && (params->proberesp_ies_len != 0) )
1489 {
1490 u16 rem_probe_resp_ie_len = params->proberesp_ies_len;
1491 u8 probe_rsp_ie_len[3] = {0};
1492 u8 counter = 0;
1493 /* Check Probe Resp Length if it is greater then 255 then Store
1494 Probe Resp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1 &
1495 WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are not able
1496 Store More then 255 bytes into One Variable.
1497 */
1498 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
1499 {
1500 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
1501 {
1502 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
1503 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
1504 }
1505 else
1506 {
1507 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
1508 rem_probe_resp_ie_len = 0;
1509 }
1510 }
1511
1512 rem_probe_resp_ie_len = 0;
1513
1514 if (probe_rsp_ie_len[0] > 0)
1515 {
1516 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1517 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
1518 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
1519 probe_rsp_ie_len[0], NULL,
1520 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
1521 {
1522 hddLog(LOGE,
1523 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001524 ret = -EINVAL;
1525 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001526 }
1527 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
1528 }
1529
1530 if (probe_rsp_ie_len[1] > 0)
1531 {
1532 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1533 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
1534 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
1535 probe_rsp_ie_len[1], NULL,
1536 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
1537 {
1538 hddLog(LOGE,
1539 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001540 ret = -EINVAL;
1541 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001542 }
1543 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
1544 }
1545
1546 if (probe_rsp_ie_len[2] > 0)
1547 {
1548 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1549 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
1550 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
1551 probe_rsp_ie_len[2], NULL,
1552 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
1553 {
1554 hddLog(LOGE,
1555 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001556 ret = -EINVAL;
1557 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001558 }
1559 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
1560 }
1561
1562 if (probe_rsp_ie_len[1] == 0 )
1563 {
1564 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1565 WNI_CFG_PROBE_RSP_ADDNIE_DATA2, (tANI_U8*)addIE, 0, NULL,
1566 eANI_BOOLEAN_FALSE) )
1567 {
1568 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08001569 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07001570 }
1571 }
1572
1573 if (probe_rsp_ie_len[2] == 0 )
1574 {
1575 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1576 WNI_CFG_PROBE_RSP_ADDNIE_DATA3, (tANI_U8*)addIE, 0, NULL,
1577 eANI_BOOLEAN_FALSE) )
1578 {
1579 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08001580 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07001581 }
1582 }
1583
1584 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1585 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
1586 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
1587 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
1588 == eHAL_STATUS_FAILURE)
1589 {
1590 hddLog(LOGE,
1591 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001592 ret = -EINVAL;
1593 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001594 }
1595 }
1596 else
1597 {
1598 // Reset WNI_CFG_PROBE_RSP Flags
1599 wlan_hdd_reset_prob_rspies(pHostapdAdapter);
1600
1601 hddLog(VOS_TRACE_LEVEL_INFO,
1602 "%s: No Probe Response IE received in set beacon",
1603 __func__);
1604 }
1605
1606 // Added for AssocResp IE
1607 if ( (params->assocresp_ies != NULL) && (params->assocresp_ies_len != 0) )
1608 {
1609 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1610 WNI_CFG_ASSOC_RSP_ADDNIE_DATA, (tANI_U8*)params->assocresp_ies,
1611 params->assocresp_ies_len, NULL,
1612 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
1613 {
1614 hddLog(LOGE,
1615 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001616 ret = -EINVAL;
1617 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001618 }
1619
1620 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1621 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 1, NULL,
1622 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
1623 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
1624 == eHAL_STATUS_FAILURE)
1625 {
1626 hddLog(LOGE,
1627 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001628 ret = -EINVAL;
1629 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001630 }
1631 }
1632 else
1633 {
1634 hddLog(VOS_TRACE_LEVEL_INFO,
1635 "%s: No Assoc Response IE received in set beacon",
1636 __func__);
1637
1638 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1639 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
1640 eANI_BOOLEAN_FALSE) )
1641 {
1642 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08001643 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07001644 }
1645 }
1646
Jeff Johnsone7245742012-09-05 17:12:55 -07001647done:
Jeff Johnson295189b2012-06-20 16:38:30 -07001648 vos_mem_free(genie);
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05301649 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07001650}
Jeff Johnson295189b2012-06-20 16:38:30 -07001651
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301652/*
Jeff Johnson295189b2012-06-20 16:38:30 -07001653 * FUNCTION: wlan_hdd_validate_operation_channel
1654 * called by wlan_hdd_cfg80211_start_bss() and
1655 * wlan_hdd_cfg80211_set_channel()
1656 * This function validates whether given channel is part of valid
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301657 * channel list.
1658 */
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07001659VOS_STATUS wlan_hdd_validate_operation_channel(hdd_adapter_t *pAdapter,int channel)
Jeff Johnson295189b2012-06-20 16:38:30 -07001660{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301661
Jeff Johnson295189b2012-06-20 16:38:30 -07001662 v_U32_t num_ch = 0;
1663 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN];
1664 u32 indx = 0;
1665 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05301666 v_U8_t fValidChannel = FALSE, count = 0;
1667 hdd_config_t *hdd_pConfig_ini= (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301668
Jeff Johnson295189b2012-06-20 16:38:30 -07001669 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
1670
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05301671 if ( hdd_pConfig_ini->sapAllowAllChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -07001672 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05301673 /* Validate the channel */
1674 for (count = RF_CHAN_1 ; count <= RF_CHAN_165 ; count++)
Jeff Johnson295189b2012-06-20 16:38:30 -07001675 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05301676 if ( channel == rfChannels[count].channelNum )
1677 {
1678 fValidChannel = TRUE;
1679 break;
1680 }
1681 }
1682 if (fValidChannel != TRUE)
1683 {
1684 hddLog(VOS_TRACE_LEVEL_ERROR,
1685 "%s: Invalid Channel [%d]", __func__, channel);
1686 return VOS_STATUS_E_FAILURE;
Jeff Johnson295189b2012-06-20 16:38:30 -07001687 }
1688 }
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05301689 else
Jeff Johnson295189b2012-06-20 16:38:30 -07001690 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05301691 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
1692 valid_ch, &num_ch))
1693 {
1694 hddLog(VOS_TRACE_LEVEL_ERROR,
1695 "%s: failed to get valid channel list", __func__);
1696 return VOS_STATUS_E_FAILURE;
1697 }
1698 for (indx = 0; indx < num_ch; indx++)
1699 {
1700 if (channel == valid_ch[indx])
1701 {
1702 break;
1703 }
1704 }
1705
Rashmi Ramanna3b59e122014-04-10 14:45:13 +05301706 if (indx >= num_ch)
1707 {
1708 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
1709 {
1710 eCsrBand band;
1711 unsigned int freq;
1712
1713 sme_GetFreqBand(hHal, &band);
1714
1715 if (eCSR_BAND_5G == band)
1716 {
1717#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
1718 if (channel <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
1719 {
1720 freq = ieee80211_channel_to_frequency(channel,
1721 IEEE80211_BAND_2GHZ);
1722 }
1723 else
1724 {
1725 freq = ieee80211_channel_to_frequency(channel,
1726 IEEE80211_BAND_5GHZ);
1727 }
1728#else
1729 freq = ieee80211_channel_to_frequency(channel);
1730#endif
1731 if(WLAN_HDD_IS_SOCIAL_CHANNEL(freq))
1732 return VOS_STATUS_SUCCESS;
1733 }
1734 }
1735
1736 hddLog(VOS_TRACE_LEVEL_ERROR,
1737 "%s: Invalid Channel [%d]", __func__, channel);
1738 return VOS_STATUS_E_FAILURE;
1739 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001740 }
Rashmi Ramanna3b59e122014-04-10 14:45:13 +05301741
Jeff Johnson295189b2012-06-20 16:38:30 -07001742 return VOS_STATUS_SUCCESS;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301743
Jeff Johnson295189b2012-06-20 16:38:30 -07001744}
1745
Viral Modi3a32cc52013-02-08 11:14:52 -08001746/**
1747 * FUNCTION: wlan_hdd_cfg80211_set_channel
1748 * This function is used to set the channel number
1749 */
1750static int wlan_hdd_cfg80211_set_channel( struct wiphy *wiphy, struct net_device *dev,
1751 struct ieee80211_channel *chan,
1752 enum nl80211_channel_type channel_type
1753 )
1754{
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05301755 hdd_adapter_t *pAdapter = NULL;
Viral Modi3a32cc52013-02-08 11:14:52 -08001756 v_U32_t num_ch = 0;
Jeff Johnson4416a782013-03-25 14:17:50 -07001757 int channel = 0;
Viral Modi3a32cc52013-02-08 11:14:52 -08001758 int freq = chan->center_freq; /* freq is in MHZ */
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05301759 hdd_context_t *pHddCtx;
1760 int status;
Viral Modi3a32cc52013-02-08 11:14:52 -08001761
1762 ENTER();
1763
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05301764
Viral Modi3a32cc52013-02-08 11:14:52 -08001765 if( NULL == dev )
1766 {
1767 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08001768 "%s: Called with dev = NULL.", __func__);
Viral Modi3a32cc52013-02-08 11:14:52 -08001769 return -ENODEV;
1770 }
1771 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
1772
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05301773 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
1774 TRACE_CODE_HDD_CFG80211_SET_CHANNEL, pAdapter->sessionId,
1775 channel_type ));
Viral Modi3a32cc52013-02-08 11:14:52 -08001776 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -08001777 "%s: device_mode = %d freq = %d", __func__,
Viral Modi3a32cc52013-02-08 11:14:52 -08001778 pAdapter->device_mode, chan->center_freq);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05301779
1780 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1781 status = wlan_hdd_validate_context(pHddCtx);
1782
1783 if (0 != status)
Viral Modi3a32cc52013-02-08 11:14:52 -08001784 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05301785 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1786 "%s: HDD context is not valid", __func__);
1787 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -08001788 }
1789
1790 /*
1791 * Do freq to chan conversion
1792 * TODO: for 11a
1793 */
1794
1795 channel = ieee80211_frequency_to_channel(freq);
1796
1797 /* Check freq range */
1798 if ((WNI_CFG_CURRENT_CHANNEL_STAMIN > channel) ||
1799 (WNI_CFG_CURRENT_CHANNEL_STAMAX < channel))
1800 {
1801 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08001802 "%s: Channel [%d] is outside valid range from %d to %d",
Viral Modi3a32cc52013-02-08 11:14:52 -08001803 __func__, channel, WNI_CFG_CURRENT_CHANNEL_STAMIN,
1804 WNI_CFG_CURRENT_CHANNEL_STAMAX);
1805 return -EINVAL;
1806 }
1807
1808 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
1809
Gopichand Nakkala6ab19562013-03-07 13:59:42 +05301810 if ((WLAN_HDD_SOFTAP != pAdapter->device_mode) &&
1811 (WLAN_HDD_P2P_GO != pAdapter->device_mode))
Viral Modi3a32cc52013-02-08 11:14:52 -08001812 {
1813 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pAdapter,channel))
1814 {
1815 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08001816 "%s: Invalid Channel [%d]", __func__, channel);
Viral Modi3a32cc52013-02-08 11:14:52 -08001817 return -EINVAL;
1818 }
1819 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
1820 "%s: set channel to [%d] for device mode =%d",
1821 __func__, channel,pAdapter->device_mode);
1822 }
1823 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Viral Modi3a32cc52013-02-08 11:14:52 -08001824 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Viral Modi3a32cc52013-02-08 11:14:52 -08001825 )
1826 {
1827 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
1828 tCsrRoamProfile * pRoamProfile = &pWextState->roamProfile;
1829 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
1830
1831 if (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState)
1832 {
1833 /* Link is up then return cant set channel*/
1834 hddLog( VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08001835 "%s: IBSS Associated, can't set the channel", __func__);
Viral Modi3a32cc52013-02-08 11:14:52 -08001836 return -EINVAL;
1837 }
1838
1839 num_ch = pRoamProfile->ChannelInfo.numOfChannels = 1;
1840 pHddStaCtx->conn_info.operationChannel = channel;
1841 pRoamProfile->ChannelInfo.ChannelList =
1842 &pHddStaCtx->conn_info.operationChannel;
1843 }
1844 else if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Viral Modi3a32cc52013-02-08 11:14:52 -08001845 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Viral Modi3a32cc52013-02-08 11:14:52 -08001846 )
1847 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05301848 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
1849 {
1850 if(VOS_STATUS_SUCCESS !=
1851 wlan_hdd_validate_operation_channel(pAdapter,channel))
1852 {
1853 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08001854 "%s: Invalid Channel [%d]", __func__, channel);
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05301855 return -EINVAL;
1856 }
1857 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
1858 }
1859 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
Viral Modi3a32cc52013-02-08 11:14:52 -08001860 {
1861 hdd_config_t *cfg_param = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
1862
1863 /* If auto channel selection is configured as enable/ 1 then ignore
1864 channel set by supplicant
1865 */
1866 if ( cfg_param->apAutoChannelSelection )
1867 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05301868 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel =
1869 AUTO_CHANNEL_SELECT;
Viral Modi3a32cc52013-02-08 11:14:52 -08001870 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
1871 "%s: set channel to auto channel (0) for device mode =%d",
1872 __func__, pAdapter->device_mode);
1873 }
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05301874 else
1875 {
1876 if(VOS_STATUS_SUCCESS !=
1877 wlan_hdd_validate_operation_channel(pAdapter,channel))
1878 {
1879 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08001880 "%s: Invalid Channel [%d]", __func__, channel);
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05301881 return -EINVAL;
1882 }
1883 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
1884 }
Viral Modi3a32cc52013-02-08 11:14:52 -08001885 }
1886 }
1887 else
1888 {
1889 hddLog(VOS_TRACE_LEVEL_FATAL,
1890 "%s: Invalid device mode failed to set valid channel", __func__);
1891 return -EINVAL;
1892 }
1893 EXIT();
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05301894 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -08001895}
1896
Jeff Johnson295189b2012-06-20 16:38:30 -07001897#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
1898static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
1899 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001900#else
1901static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
1902 struct cfg80211_beacon_data *params,
1903 const u8 *ssid, size_t ssid_len,
1904 enum nl80211_hidden_ssid hidden_ssid)
1905#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07001906{
1907 tsap_Config_t *pConfig;
1908 beacon_data_t *pBeacon = NULL;
1909 struct ieee80211_mgmt *pMgmt_frame;
1910 v_U8_t *pIe=NULL;
1911 v_U16_t capab_info;
1912 eCsrAuthType RSNAuthType;
1913 eCsrEncryptionType RSNEncryptType;
1914 eCsrEncryptionType mcRSNEncryptType;
1915 int status = VOS_STATUS_SUCCESS;
1916 tpWLAN_SAPEventCB pSapEventCallback;
1917 hdd_hostapd_state_t *pHostapdState;
1918 v_U8_t wpaRsnIEdata[(SIR_MAC_MAX_IE_LENGTH * 2)+4]; //Max ie length 255 * 2(WPA+RSN) + 2 bytes (vendor specific ID) * 2
1919 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05301920 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07001921 struct qc_mac_acl_entry *acl_entry = NULL;
1922 v_SINT_t i;
Madan Mohan Koyyalamudi543172b2012-12-05 16:40:18 -08001923 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
Chet Lanctot8cecea22014-02-11 19:09:36 -08001924 v_BOOL_t MFPCapable;
1925 v_BOOL_t MFPRequired;
Abhishek Singhf0ac1752014-03-05 17:47:09 +05301926 eHddDot11Mode sapDot11Mode =
1927 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->sapDot11Mode;
Jeff Johnson295189b2012-06-20 16:38:30 -07001928
1929 ENTER();
1930
1931 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter);
1932
1933 pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
1934
1935 pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
1936
1937 pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
1938
1939 pConfig->beacon_int = pMgmt_frame->u.beacon.beacon_int;
1940
1941 //channel is already set in the set_channel Call back
1942 //pConfig->channel = pCommitConfig->channel;
1943
1944 /*Protection parameter to enable or disable*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301945 pConfig->protEnabled =
Jeff Johnson295189b2012-06-20 16:38:30 -07001946 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtEnabled;
1947
1948 pConfig->dtim_period = pBeacon->dtim_period;
1949
Arif Hussain6d2a3322013-11-17 19:50:10 -08001950 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"****pConfig->dtim_period=%d***",
Jeff Johnson295189b2012-06-20 16:38:30 -07001951 pConfig->dtim_period);
1952
1953
Madan Mohan Koyyalamudie0ca11f2012-11-27 15:57:52 -08001954 if (pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson32d95a32012-09-10 13:15:23 -07001955 {
1956 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -07001957 WLAN_EID_COUNTRY);
Kiet Lam083504c2013-11-25 14:17:45 +05301958 if(memcmp(pHddCtx->cfg_ini->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0)
1959 {
1960 tANI_BOOLEAN restartNeeded;
1961 pConfig->ieee80211d = 1;
1962 vos_mem_copy(pConfig->countryCode, pHddCtx->cfg_ini->apCntryCode, 3);
1963 sme_setRegInfo(hHal, pConfig->countryCode);
1964 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
1965 }
1966 else if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07001967 {
Jeff Johnson32d95a32012-09-10 13:15:23 -07001968 tANI_BOOLEAN restartNeeded;
Jeff Johnson32d95a32012-09-10 13:15:23 -07001969 pConfig->ieee80211d = 1;
1970 vos_mem_copy(pConfig->countryCode, &pIe[2], 3);
1971 sme_setRegInfo(hHal, pConfig->countryCode);
1972 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
Jeff Johnson295189b2012-06-20 16:38:30 -07001973 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07001974 else
1975 {
1976 pConfig->ieee80211d = 0;
1977 }
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05301978 /*
1979 * If auto channel is configured i.e. channel is 0,
1980 * so skip channel validation.
1981 */
1982 if( AUTO_CHANNEL_SELECT != pConfig->channel )
1983 {
1984 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pHostapdAdapter,pConfig->channel))
1985 {
1986 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08001987 "%s: Invalid Channel [%d]", __func__, pConfig->channel);
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05301988 return -EINVAL;
1989 }
1990 }
1991 else
1992 {
1993 if(1 != pHddCtx->is_dynamic_channel_range_set)
1994 {
1995 hdd_config_t *hdd_pConfig= (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini;
1996 WLANSAP_SetChannelRange(hHal, hdd_pConfig->apStartChannelNum,
1997 hdd_pConfig->apEndChannelNum,hdd_pConfig->apOperatingBand);
1998 }
1999 pHddCtx->is_dynamic_channel_range_set = 0;
2000 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002001 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07002002 else
Jeff Johnson295189b2012-06-20 16:38:30 -07002003 {
2004 pConfig->ieee80211d = 0;
2005 }
2006 pConfig->authType = eSAP_AUTO_SWITCH;
2007
2008 capab_info = pMgmt_frame->u.beacon.capab_info;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302009
2010 pConfig->privacy = (pMgmt_frame->u.beacon.capab_info &
Jeff Johnson295189b2012-06-20 16:38:30 -07002011 WLAN_CAPABILITY_PRIVACY) ? VOS_TRUE : VOS_FALSE;
2012
2013 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uPrivacy = pConfig->privacy;
2014
2015 /*Set wps station to configured*/
2016 pIe = wlan_hdd_get_wps_ie_ptr(pBeacon->tail, pBeacon->tail_len);
2017
2018 if(pIe)
2019 {
2020 if(pIe[1] < (2 + WPS_OUI_TYPE_SIZE))
2021 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08002022 hddLog( VOS_TRACE_LEVEL_ERROR, "**Wps Ie Length is too small***");
Jeff Johnson295189b2012-06-20 16:38:30 -07002023 return -EINVAL;
2024 }
2025 else if(memcmp(&pIe[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) == 0)
2026 {
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07002027 hddLog( VOS_TRACE_LEVEL_INFO, "** WPS IE(len %d) ***", (pIe[1]+2));
Jeff Johnson295189b2012-06-20 16:38:30 -07002028 /* Check 15 bit of WPS IE as it contain information for wps state
2029 * WPS state
2030 */
2031 if(SAP_WPS_ENABLED_UNCONFIGURED == pIe[15])
2032 {
2033 pConfig->wps_state = SAP_WPS_ENABLED_UNCONFIGURED;
2034 } else if(SAP_WPS_ENABLED_CONFIGURED == pIe[15])
2035 {
2036 pConfig->wps_state = SAP_WPS_ENABLED_CONFIGURED;
2037 }
2038 }
2039 }
2040 else
2041 {
2042 pConfig->wps_state = SAP_WPS_DISABLED;
2043 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302044 pConfig->fwdWPSPBCProbeReq = 1; // Forward WPS PBC probe request frame up
Jeff Johnson295189b2012-06-20 16:38:30 -07002045
2046 pConfig->RSNWPAReqIELength = 0;
2047 pConfig->pRSNWPAReqIE = NULL;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302048 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -07002049 WLAN_EID_RSN);
2050 if(pIe && pIe[1])
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302051 {
Jeff Johnson295189b2012-06-20 16:38:30 -07002052 pConfig->RSNWPAReqIELength = pIe[1] + 2;
2053 memcpy(&wpaRsnIEdata[0], pIe, pConfig->RSNWPAReqIELength);
2054 pConfig->pRSNWPAReqIE = &wpaRsnIEdata[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302055 /* The actual processing may eventually be more extensive than
2056 * this. Right now, just consume any PMKIDs that are sent in
Jeff Johnson295189b2012-06-20 16:38:30 -07002057 * by the app.
2058 * */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302059 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -07002060 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
2061 &RSNEncryptType,
2062 &mcRSNEncryptType,
2063 &RSNAuthType,
Chet Lanctot8cecea22014-02-11 19:09:36 -08002064 &MFPCapable,
2065 &MFPRequired,
Jeff Johnson295189b2012-06-20 16:38:30 -07002066 pConfig->pRSNWPAReqIE[1]+2,
2067 pConfig->pRSNWPAReqIE );
2068
2069 if( VOS_STATUS_SUCCESS == status )
2070 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302071 /* Now copy over all the security attributes you have
2072 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -07002073 * */
2074 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
2075 pConfig->mcRSNEncryptType = mcRSNEncryptType;
2076 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
2077 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05302078 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -08002079 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -07002080 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
2081 }
2082 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302083
Jeff Johnson295189b2012-06-20 16:38:30 -07002084 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE,
2085 pBeacon->tail, pBeacon->tail_len);
2086
2087 if(pIe && pIe[1] && (pIe[0] == DOT11F_EID_WPA))
2088 {
2089 if (pConfig->pRSNWPAReqIE)
2090 {
2091 /*Mixed mode WPA/WPA2*/
2092 memcpy((&wpaRsnIEdata[0] + pConfig->RSNWPAReqIELength), pIe, pIe[1] + 2);
2093 pConfig->RSNWPAReqIELength += pIe[1] + 2;
2094 }
2095 else
2096 {
2097 pConfig->RSNWPAReqIELength = pIe[1] + 2;
2098 memcpy(&wpaRsnIEdata[0], pIe, pConfig->RSNWPAReqIELength);
2099 pConfig->pRSNWPAReqIE = &wpaRsnIEdata[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302100 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -07002101 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
2102 &RSNEncryptType,
2103 &mcRSNEncryptType,
2104 &RSNAuthType,
Chet Lanctot8cecea22014-02-11 19:09:36 -08002105 &MFPCapable,
2106 &MFPRequired,
Jeff Johnson295189b2012-06-20 16:38:30 -07002107 pConfig->pRSNWPAReqIE[1]+2,
2108 pConfig->pRSNWPAReqIE );
2109
2110 if( VOS_STATUS_SUCCESS == status )
2111 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302112 /* Now copy over all the security attributes you have
2113 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -07002114 * */
2115 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
2116 pConfig->mcRSNEncryptType = mcRSNEncryptType;
2117 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
2118 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05302119 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -08002120 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -07002121 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
2122 }
2123 }
2124 }
2125
Jeff Johnson4416a782013-03-25 14:17:50 -07002126 if (pConfig->RSNWPAReqIELength > sizeof wpaRsnIEdata) {
2127 hddLog( VOS_TRACE_LEVEL_ERROR, "**RSNWPAReqIELength is too large***");
2128 return -EINVAL;
2129 }
2130
Jeff Johnson295189b2012-06-20 16:38:30 -07002131 pConfig->SSIDinfo.ssidHidden = VOS_FALSE;
2132
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002133#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07002134 if (params->ssid != NULL)
2135 {
2136 memcpy(pConfig->SSIDinfo.ssid.ssId, params->ssid, params->ssid_len);
2137 pConfig->SSIDinfo.ssid.length = params->ssid_len;
2138 if (params->hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
2139 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
2140 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002141#else
2142 if (ssid != NULL)
2143 {
2144 memcpy(pConfig->SSIDinfo.ssid.ssId, ssid, ssid_len);
2145 pConfig->SSIDinfo.ssid.length = ssid_len;
2146 if (hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
2147 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
2148 }
2149#endif
2150
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302151 vos_mem_copy(pConfig->self_macaddr.bytes,
Jeff Johnson295189b2012-06-20 16:38:30 -07002152 pHostapdAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302153
Jeff Johnson295189b2012-06-20 16:38:30 -07002154 /* default value */
2155 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
2156 pConfig->num_accept_mac = 0;
2157 pConfig->num_deny_mac = 0;
2158
2159 pIe = wlan_hdd_get_vendor_oui_ie_ptr(BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
2160 pBeacon->tail, pBeacon->tail_len);
2161
2162 /* pIe for black list is following form:
2163 type : 1 byte
2164 length : 1 byte
2165 OUI : 4 bytes
2166 acl type : 1 byte
2167 no of mac addr in black list: 1 byte
2168 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302169 */
2170 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07002171 {
2172 pConfig->SapMacaddr_acl = pIe[6];
2173 pConfig->num_deny_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -08002174 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no deny mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07002175 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05302176 if (pConfig->num_deny_mac > MAX_ACL_MAC_ADDRESS)
2177 pConfig->num_deny_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07002178 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
2179 for (i = 0; i < pConfig->num_deny_mac; i++)
2180 {
2181 vos_mem_copy(&pConfig->deny_mac[i], acl_entry->addr, sizeof(qcmacaddr));
2182 acl_entry++;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302183 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002184 }
2185 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
2186 pBeacon->tail, pBeacon->tail_len);
2187
2188 /* pIe for white list is following form:
2189 type : 1 byte
2190 length : 1 byte
2191 OUI : 4 bytes
2192 acl type : 1 byte
2193 no of mac addr in white list: 1 byte
2194 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302195 */
2196 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07002197 {
2198 pConfig->SapMacaddr_acl = pIe[6];
2199 pConfig->num_accept_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -08002200 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no accept mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07002201 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05302202 if (pConfig->num_accept_mac > MAX_ACL_MAC_ADDRESS)
2203 pConfig->num_accept_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07002204 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
2205 for (i = 0; i < pConfig->num_accept_mac; i++)
2206 {
2207 vos_mem_copy(&pConfig->accept_mac[i], acl_entry->addr, sizeof(qcmacaddr));
2208 acl_entry++;
2209 }
2210 }
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05302211
Jeff Johnson295189b2012-06-20 16:38:30 -07002212 wlan_hdd_set_sapHwmode(pHostapdAdapter);
2213
Jeff Johnsone7245742012-09-05 17:12:55 -07002214#ifdef WLAN_FEATURE_11AC
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -08002215 /* Overwrite the hostapd setting for HW mode only for 11ac.
Kiet Lam0f320422013-11-21 19:29:17 +05302216 * This is valid only if mode is set to 11n in hostapd, either AUTO or
2217 * 11ac in .ini and 11ac is supported by both host and firmware.
2218 * Otherwise, leave whatever is set in hostapd (a OR b OR g OR n mode)
2219 */
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -08002220 if( ((pConfig->SapHw_mode == eSAP_DOT11_MODE_11n) ||
2221 (pConfig->SapHw_mode == eSAP_DOT11_MODE_11n_ONLY)) &&
Abhishek Singhf0ac1752014-03-05 17:47:09 +05302222 (( sapDot11Mode == eHDD_DOT11_MODE_AUTO ) ||
2223 ( sapDot11Mode == eHDD_DOT11_MODE_11ac ) ||
2224 ( sapDot11Mode == eHDD_DOT11_MODE_11ac_ONLY ) ) &&
2225 (sme_IsFeatureSupportedByDriver(DOT11AC)) &&
2226 (sme_IsFeatureSupportedByFW(DOT11AC)) )
Jeff Johnsone7245742012-09-05 17:12:55 -07002227 {
2228 pConfig->SapHw_mode = eSAP_DOT11_MODE_11ac;
Ravi Joshi83bfaa12013-05-28 22:12:08 -07002229
Rashmi Ramanna3b59e122014-04-10 14:45:13 +05302230 /* Disable VHT support in 2.4 GHz and */
Ravi Joshi83bfaa12013-05-28 22:12:08 -07002231 if (pConfig->channel <= 14 &&
2232 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->enableVhtFor24GHzBand == FALSE)
2233 {
2234 pConfig->SapHw_mode = eSAP_DOT11_MODE_11n;
2235 }
Jeff Johnsone7245742012-09-05 17:12:55 -07002236 }
2237#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302238
Ravi Joshiaeb7d9e2013-05-02 12:28:14 -07002239 if ( AUTO_CHANNEL_SELECT != pConfig->channel )
2240 {
2241 sme_SelectCBMode(hHal,
2242 sapConvertSapPhyModeToCsrPhyMode(pConfig->SapHw_mode),
2243 pConfig->channel);
2244 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002245 // ht_capab is not what the name conveys,this is used for protection bitmap
2246 pConfig->ht_capab =
2247 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtection;
2248
2249 if ( 0 != wlan_hdd_cfg80211_update_apies(pHostapdAdapter, params) )
2250 {
2251 hddLog(LOGE, FL("SAP Not able to set AP IEs"));
2252 return -EINVAL;
2253 }
2254
2255 //Uapsd Enabled Bit
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302256 pConfig->UapsdEnable =
Jeff Johnson295189b2012-06-20 16:38:30 -07002257 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apUapsdEnabled;
2258 //Enable OBSS protection
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302259 pConfig->obssProtEnabled =
2260 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apOBSSProtEnabled;
Jeff Johnson295189b2012-06-20 16:38:30 -07002261
Chet Lanctot8cecea22014-02-11 19:09:36 -08002262#ifdef WLAN_FEATURE_11W
2263 pConfig->mfpCapable = MFPCapable;
2264 pConfig->mfpRequired = MFPRequired;
2265 hddLog(LOGW, FL("Soft AP MFP capable %d, MFP required %d\n"),
2266 pConfig->mfpCapable, pConfig->mfpRequired);
2267#endif
2268
Arif Hussain6d2a3322013-11-17 19:50:10 -08002269 hddLog(LOGW, FL("SOftAP macaddress : "MAC_ADDRESS_STR),
Jeff Johnson295189b2012-06-20 16:38:30 -07002270 MAC_ADDR_ARRAY(pHostapdAdapter->macAddressCurrent.bytes));
Arif Hussain6d2a3322013-11-17 19:50:10 -08002271 hddLog(LOGW,FL("ssid =%s, beaconint=%d, channel=%d"),
2272 pConfig->SSIDinfo.ssid.ssId, (int)pConfig->beacon_int,
2273 (int)pConfig->channel);
2274 hddLog(LOGW,FL("hw_mode=%x, privacy=%d, authType=%d"),
2275 pConfig->SapHw_mode, pConfig->privacy,
2276 pConfig->authType);
2277 hddLog(LOGW,FL("RSN/WPALen=%d, Uapsd = %d"),
2278 (int)pConfig->RSNWPAReqIELength, pConfig->UapsdEnable);
2279 hddLog(LOGW,FL("ProtEnabled = %d, OBSSProtEnabled = %d"),
2280 pConfig->protEnabled, pConfig->obssProtEnabled);
Jeff Johnson295189b2012-06-20 16:38:30 -07002281
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302282 if(test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -07002283 {
2284 //Bss already started. just return.
2285 //TODO Probably it should update some beacon params.
2286 hddLog( LOGE, "Bss Already started...Ignore the request");
2287 EXIT();
2288 return 0;
2289 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302290
Jeff Johnson295189b2012-06-20 16:38:30 -07002291 pConfig->persona = pHostapdAdapter->device_mode;
2292
2293 pSapEventCallback = hdd_hostapd_SAPEventCB;
2294 if(WLANSAP_StartBss(pVosContext, pSapEventCallback, pConfig,
2295 (v_PVOID_t)pHostapdAdapter->dev) != VOS_STATUS_SUCCESS)
2296 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08002297 hddLog(LOGE,FL("SAP Start Bss fail"));
Jeff Johnson295189b2012-06-20 16:38:30 -07002298 return -EINVAL;
2299 }
2300
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302301 hddLog(LOG1,
Jeff Johnson295189b2012-06-20 16:38:30 -07002302 FL("Waiting for Scan to complete(auto mode) and BSS to start"));
2303
2304 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302305
Jeff Johnson295189b2012-06-20 16:38:30 -07002306 if (!VOS_IS_STATUS_SUCCESS(status))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302307 {
2308 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08002309 ("ERROR: HDD vos wait for single_event failed!!"));
Tushnim Bhattacharyyaad37df12013-10-02 12:01:33 -07002310 smeGetCommandQStatus(hHal);
Jeff Johnson295189b2012-06-20 16:38:30 -07002311 VOS_ASSERT(0);
2312 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302313
Jeff Johnson295189b2012-06-20 16:38:30 -07002314 set_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags);
2315
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07002316#ifdef WLAN_FEATURE_P2P_DEBUG
2317 if (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO)
2318 {
2319 if(globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED)
2320 {
2321 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
2322 hddLog(LOGE,"[P2P State] From Go nego completed to "
Jeff Johnson1250df42012-12-10 14:31:52 -08002323 "Non-autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07002324 }
2325 else if(globalP2PConnectionStatus == P2P_NOT_ACTIVE)
2326 {
2327 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
2328 hddLog(LOGE,"[P2P State] From Inactive to "
Jeff Johnson1250df42012-12-10 14:31:52 -08002329 "Autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07002330 }
2331 }
2332#endif
2333
Jeff Johnson295189b2012-06-20 16:38:30 -07002334 pHostapdState->bCommit = TRUE;
2335 EXIT();
2336
2337 return 0;
2338}
2339
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002340#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302341static int wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy,
2342 struct net_device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -07002343 struct beacon_parameters *params)
2344{
2345 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302346 hdd_context_t *pHddCtx;
2347 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07002348
2349 ENTER();
2350
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302351 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2352 TRACE_CODE_HDD_CFG80211_ADD_BEACON,
2353 pAdapter->sessionId, params->interval));
Arif Hussain6d2a3322013-11-17 19:50:10 -08002354 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "device mode=%d",pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07002355
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302356 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2357 status = wlan_hdd_validate_context(pHddCtx);
2358
2359 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002360 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302361 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2362 "%s: HDD context is not valid", __func__);
2363 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002364 }
2365
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302366 if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07002367 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07002368 )
2369 {
2370 beacon_data_t *old,*new;
2371
2372 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302373
Jeff Johnson295189b2012-06-20 16:38:30 -07002374 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302375 {
2376 hddLog(VOS_TRACE_LEVEL_WARN,
2377 FL("already beacon info added to session(%d)"),
2378 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07002379 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302380 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002381
2382 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
2383
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302384 if(status != VOS_STATUS_SUCCESS)
Jeff Johnson295189b2012-06-20 16:38:30 -07002385 {
2386 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08002387 "%s:Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002388 return -EINVAL;
2389 }
2390
2391 pAdapter->sessionCtx.ap.beacon = new;
2392
2393 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
2394 }
2395
2396 EXIT();
2397 return status;
2398}
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302399
2400static int wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07002401 struct net_device *dev,
2402 struct beacon_parameters *params)
2403{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302404 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302405 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302406 hdd_context_t *pHddCtx;
2407 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07002408
2409 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302410 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2411 TRACE_CODE_HDD_CFG80211_SET_BEACON,
2412 pAdapter->sessionId, pHddStaCtx->conn_info.authType));
Arif Hussain6d2a3322013-11-17 19:50:10 -08002413 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07002414 __func__,pAdapter->device_mode);
2415
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)
Jeff Johnson04dd8a82012-06-29 20:41:40 -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 Johnson04dd8a82012-06-29 20:41:40 -07002424 }
2425
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302426 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07002427 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302428 )
Jeff Johnson295189b2012-06-20 16:38:30 -07002429 {
2430 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302431
Jeff Johnson295189b2012-06-20 16:38:30 -07002432 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302433
Jeff Johnson295189b2012-06-20 16:38:30 -07002434 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302435 {
2436 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2437 FL("session(%d) old and new heads points to NULL"),
2438 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07002439 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302440 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002441
2442 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
2443
2444 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302445 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08002446 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002447 return -EINVAL;
2448 }
2449
2450 pAdapter->sessionCtx.ap.beacon = new;
2451
2452 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
2453 }
2454
2455 EXIT();
2456 return status;
2457}
2458
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002459#endif //(LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
2460
2461#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07002462static int wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy,
2463 struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002464#else
2465static int wlan_hdd_cfg80211_stop_ap (struct wiphy *wiphy,
2466 struct net_device *dev)
2467#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07002468{
2469 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnsone7245742012-09-05 17:12:55 -07002470 hdd_context_t *pHddCtx = NULL;
2471 hdd_scaninfo_t *pScanInfo = NULL;
2472 hdd_adapter_t *staAdapter = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302473 VOS_STATUS status;
Jeff Johnson295189b2012-06-20 16:38:30 -07002474
2475 ENTER();
2476
2477 if (NULL == pAdapter)
2478 {
2479 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002480 "%s: HDD adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002481 return -ENODEV;
2482 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07002483
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302484 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2485 TRACE_CODE_HDD_CFG80211_STOP_AP,
2486 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302487 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2488 status = wlan_hdd_validate_context(pHddCtx);
2489
2490 if (0 != status)
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07002491 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302492 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2493 "%s: HDD context is not valid", __func__);
2494 return status;
Jeff Johnson4416a782013-03-25 14:17:50 -07002495 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07002496
2497 staAdapter = hdd_get_adapter(pAdapter->pHddCtx, WLAN_HDD_INFRA_STATION);
2498 if (NULL == staAdapter)
2499 {
2500 staAdapter = hdd_get_adapter(pAdapter->pHddCtx, WLAN_HDD_P2P_CLIENT);
2501 if (NULL == staAdapter)
2502 {
Rajesh Chauhan52d885b2013-11-01 10:54:25 -07002503 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
2504 "%s: HDD adapter context for STA/P2P-CLI is Null",
2505 __func__);
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07002506 }
2507 }
2508
2509 pScanInfo = &pHddCtx->scan_info;
2510
Arif Hussain6d2a3322013-11-17 19:50:10 -08002511 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07002512 __func__,pAdapter->device_mode);
2513
Rajesh Chauhan52d885b2013-11-01 10:54:25 -07002514 if ((pScanInfo != NULL) && pScanInfo->mScanPending && staAdapter)
Jeff Johnsone7245742012-09-05 17:12:55 -07002515 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302516 long ret;
2517
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -08002518 INIT_COMPLETION(pScanInfo->abortscan_event_var);
Srinivas, Dasari138af4f2014-02-07 11:13:45 +05302519 hdd_abort_mac_scan(staAdapter->pHddCtx, pAdapter->sessionId,
2520 eCSR_SCAN_ABORT_DEFAULT);
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302521 ret = wait_for_completion_interruptible_timeout(
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -08002522 &pScanInfo->abortscan_event_var,
Jeff Johnsone7245742012-09-05 17:12:55 -07002523 msecs_to_jiffies(WLAN_WAIT_TIME_ABORTSCAN));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302524 if (ret <= 0)
Jeff Johnsone7245742012-09-05 17:12:55 -07002525 {
Rajesh Chauhan52d885b2013-11-01 10:54:25 -07002526 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302527 FL("Timeout occurred while waiting for abortscan %ld"),
2528 ret);
Yue Ma4f55ef32014-01-23 16:45:33 -08002529
2530 if (pHddCtx->isLogpInProgress)
2531 {
2532 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2533 "%s: LOGP in Progress. Ignore!!!", __func__);
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302534
2535 VOS_ASSERT(pScanInfo->mScanPending);
Yue Ma4f55ef32014-01-23 16:45:33 -08002536 return -EAGAIN;
2537 }
Jeff Johnsone7245742012-09-05 17:12:55 -07002538 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -07002539 }
2540 }
2541
Arun Kumar Khandavallia3bd8002014-01-17 16:21:19 +05302542 hdd_hostapd_stop(dev);
2543
Jeff Johnson295189b2012-06-20 16:38:30 -07002544 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07002545 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07002546 )
2547 {
2548 beacon_data_t *old;
2549
2550 old = pAdapter->sessionCtx.ap.beacon;
2551
2552 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302553 {
2554 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2555 FL("session(%d) beacon data points to NULL"),
2556 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07002557 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302558 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002559
Jeff Johnson295189b2012-06-20 16:38:30 -07002560 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07002561
2562 mutex_lock(&pHddCtx->sap_lock);
2563 if(test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
2564 {
Jeff Johnson4416a782013-03-25 14:17:50 -07002565 if ( VOS_STATUS_SUCCESS == (status = WLANSAP_StopBss(pHddCtx->pvosContext) ) )
Jeff Johnson295189b2012-06-20 16:38:30 -07002566 {
2567 hdd_hostapd_state_t *pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
2568
2569 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
2570
2571 if (!VOS_IS_STATUS_SUCCESS(status))
2572 {
2573 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08002574 ("ERROR: HDD vos wait for single_event failed!!"));
Jeff Johnson295189b2012-06-20 16:38:30 -07002575 VOS_ASSERT(0);
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302576 }
2577 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002578 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
2579 }
2580 mutex_unlock(&pHddCtx->sap_lock);
2581
2582 if(status != VOS_STATUS_SUCCESS)
2583 {
2584 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08002585 "%s:Error!!! Stopping the BSS",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002586 return -EINVAL;
2587 }
2588
Jeff Johnson4416a782013-03-25 14:17:50 -07002589 if (ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -07002590 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 0,NULL, eANI_BOOLEAN_FALSE)
2591 ==eHAL_STATUS_FAILURE)
2592 {
2593 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08002594 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07002595 }
2596
Jeff Johnson4416a782013-03-25 14:17:50 -07002597 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -07002598 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
2599 eANI_BOOLEAN_FALSE) )
2600 {
2601 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08002602 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07002603 }
2604
2605 // Reset WNI_CFG_PROBE_RSP Flags
2606 wlan_hdd_reset_prob_rspies(pAdapter);
2607
2608 pAdapter->sessionCtx.ap.beacon = NULL;
2609 kfree(old);
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07002610#ifdef WLAN_FEATURE_P2P_DEBUG
2611 if((pAdapter->device_mode == WLAN_HDD_P2P_GO) &&
2612 (globalP2PConnectionStatus == P2P_GO_COMPLETED_STATE))
2613 {
2614 hddLog(LOGE,"[P2P State] From GO completed to Inactive state "
2615 "GO got removed");
2616 globalP2PConnectionStatus = P2P_NOT_ACTIVE;
2617 }
2618#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07002619 }
2620 EXIT();
2621 return status;
2622}
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002623
2624#if (LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
2625
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302626static int wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
2627 struct net_device *dev,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002628 struct cfg80211_ap_settings *params)
2629{
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302630 hdd_adapter_t *pAdapter;
2631 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302632 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002633
2634 ENTER();
2635
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302636 if (NULL == dev)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07002637 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302638 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302639 "%s: Device is Null", __func__);
2640 return -ENODEV;
2641 }
2642
2643 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2644 if (NULL == pAdapter)
2645 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302646 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302647 "%s: HDD adapter is Null", __func__);
2648 return -ENODEV;
2649 }
2650
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302651 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2652 TRACE_CODE_HDD_CFG80211_START_AP, pAdapter->sessionId,
2653 params-> beacon_interval));
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302654 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
2655 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302656 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302657 "%s: HDD adapter magic is invalid", __func__);
2658 return -ENODEV;
2659 }
2660
2661 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302662 status = wlan_hdd_validate_context(pHddCtx);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302663
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302664 if (0 != status)
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302665 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302666 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2667 "%s: HDD context is not valid", __func__);
2668 return status;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302669 }
2670
2671 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device mode = %d",
2672 __func__, pAdapter->device_mode);
2673
2674 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002675 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002676 )
2677 {
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302678 beacon_data_t *old, *new;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002679
2680 old = pAdapter->sessionCtx.ap.beacon;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302681
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002682 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302683 {
2684 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
2685 FL("already beacon info added to session(%d)"),
2686 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002687 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302688 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002689
2690 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter, &new, &params->beacon, params->dtim_period);
2691
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302692 if (status != 0)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002693 {
2694 hddLog(VOS_TRACE_LEVEL_FATAL,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302695 "%s:Error!!! Allocating the new beacon", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002696 return -EINVAL;
2697 }
2698 pAdapter->sessionCtx.ap.beacon = new;
Viral Modi3a32cc52013-02-08 11:14:52 -08002699#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
Yue Maf49ba872013-08-19 12:04:25 -07002700 wlan_hdd_cfg80211_set_channel(wiphy, dev,
2701#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
2702 params->channel, params->channel_type);
2703#else
2704 params->chandef.chan, cfg80211_get_chandef_type(&(params->chandef)));
2705#endif
Viral Modi3a32cc52013-02-08 11:14:52 -08002706#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002707 status = wlan_hdd_cfg80211_start_bss(pAdapter, &params->beacon, params->ssid,
2708 params->ssid_len, params->hidden_ssid);
2709 }
2710
2711 EXIT();
2712 return status;
2713}
2714
2715
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302716static int wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002717 struct net_device *dev,
2718 struct cfg80211_beacon_data *params)
2719{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302720 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302721 hdd_context_t *pHddCtx;
2722 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002723
2724 ENTER();
2725
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302726 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2727 TRACE_CODE_HDD_CFG80211_CHANGE_BEACON,
2728 pAdapter->sessionId, pAdapter->device_mode));
Arif Hussain6d2a3322013-11-17 19:50:10 -08002729 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002730 __func__, pAdapter->device_mode);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302731
2732 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2733 status = wlan_hdd_validate_context(pHddCtx);
2734
2735 if (0 != status)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07002736 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302737 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2738 "%s: HDD context is not valid", __func__);
2739 return status;
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07002740 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002741
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302742 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002743 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302744 )
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002745 {
2746 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302747
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002748 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302749
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002750 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302751 {
2752 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2753 FL("session(%d) beacon data points to NULL"),
2754 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002755 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302756 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002757
2758 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter, &new, params, 0);
2759
2760 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302761 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08002762 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002763 return -EINVAL;
2764 }
2765
2766 pAdapter->sessionCtx.ap.beacon = new;
2767
2768 status = wlan_hdd_cfg80211_start_bss(pAdapter, params, NULL, 0, 0);
2769 }
2770
2771 EXIT();
2772 return status;
2773}
2774
2775#endif //(LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
2776
Jeff Johnson295189b2012-06-20 16:38:30 -07002777
2778static int wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
2779 struct net_device *dev,
2780 struct bss_parameters *params)
2781{
2782 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2783
2784 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302785
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302786 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2787 TRACE_CODE_HDD_CFG80211_CHANGE_BSS,
2788 pAdapter->sessionId, params->ap_isolate));
Arif Hussain6d2a3322013-11-17 19:50:10 -08002789 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07002790 __func__,pAdapter->device_mode);
2791
2792 if((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07002793 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302794 )
Jeff Johnson295189b2012-06-20 16:38:30 -07002795 {
2796 /* ap_isolate == -1 means that in change bss, upper layer doesn't
2797 * want to update this parameter */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302798 if (-1 != params->ap_isolate)
Jeff Johnson295189b2012-06-20 16:38:30 -07002799 {
2800 pAdapter->sessionCtx.ap.apDisableIntraBssFwd = !!params->ap_isolate;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302801 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002802 }
2803
2804 EXIT();
2805 return 0;
2806}
2807
Kiet Lam10841362013-11-01 11:36:50 +05302808/* FUNCTION: wlan_hdd_change_country_code_cd
2809* to wait for contry code completion
2810*/
2811void* wlan_hdd_change_country_code_cb(void *pAdapter)
2812{
2813 hdd_adapter_t *call_back_pAdapter = pAdapter;
2814 complete(&call_back_pAdapter->change_country_code);
2815 return NULL;
2816}
2817
Jeff Johnson295189b2012-06-20 16:38:30 -07002818/*
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +05302819 * FUNCTION: __wlan_hdd_cfg80211_change_iface
Jeff Johnson295189b2012-06-20 16:38:30 -07002820 * This function is used to set the interface type (INFRASTRUCTURE/ADHOC)
2821 */
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +05302822int __wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07002823 struct net_device *ndev,
2824 enum nl80211_iftype type,
2825 u32 *flags,
2826 struct vif_params *params
2827 )
2828{
2829 struct wireless_dev *wdev;
2830 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Rajesh Chauhana0516c62014-01-30 16:11:18 -08002831 hdd_context_t *pHddCtx;
Mohit Khanna0f232092012-09-11 14:46:08 -07002832 hdd_adapter_t *pP2pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07002833 tCsrRoamProfile *pRoamProfile = NULL;
2834 eCsrRoamBssType LastBSSType;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302835 hdd_config_t *pConfig = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07002836 eMib_dot11DesiredBssType connectedBssType;
2837 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302838 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07002839
2840 ENTER();
2841
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302842 if (!pAdapter)
Rajesh Chauhana0516c62014-01-30 16:11:18 -08002843 {
2844 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2845 "%s: Adapter context is null", __func__);
2846 return VOS_STATUS_E_FAILURE;
2847 }
2848
2849 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2850 if (!pHddCtx)
2851 {
2852 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2853 "%s: HDD context is null", __func__);
2854 return VOS_STATUS_E_FAILURE;
2855 }
2856
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302857 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2858 TRACE_CODE_HDD_CFG80211_CHANGE_IFACE,
2859 pAdapter->sessionId, type));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302860 status = wlan_hdd_validate_context(pHddCtx);
2861
2862 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -07002863 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302864 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2865 "%s: HDD context is not valid", __func__);
2866 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -07002867 }
2868
2869 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
2870 __func__, pAdapter->device_mode);
2871
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302872 pConfig = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -07002873 wdev = ndev->ieee80211_ptr;
2874
2875#ifdef WLAN_BTAMP_FEATURE
2876 if((NL80211_IFTYPE_P2P_CLIENT == type)||
2877 (NL80211_IFTYPE_ADHOC == type)||
2878 (NL80211_IFTYPE_AP == type)||
2879 (NL80211_IFTYPE_P2P_GO == type))
2880 {
2881 pHddCtx->isAmpAllowed = VOS_FALSE;
2882 // stop AMP traffic
2883 status = WLANBAP_StopAmp();
2884 if(VOS_STATUS_SUCCESS != status )
2885 {
2886 pHddCtx->isAmpAllowed = VOS_TRUE;
2887 hddLog(VOS_TRACE_LEVEL_FATAL,
2888 "%s: Failed to stop AMP", __func__);
2889 return -EINVAL;
2890 }
2891 }
2892#endif //WLAN_BTAMP_FEATURE
2893 /* Reset the current device mode bit mask*/
2894 wlan_hdd_clear_concurrency_mode(pHddCtx, pAdapter->device_mode);
2895
2896 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -07002897 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnsone7245742012-09-05 17:12:55 -07002898 || (pAdapter->device_mode == WLAN_HDD_P2P_DEVICE)
Jeff Johnson295189b2012-06-20 16:38:30 -07002899 )
2900 {
2901 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -08002902 if (!pWextState)
2903 {
2904 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2905 "%s: pWextState is null", __func__);
2906 return VOS_STATUS_E_FAILURE;
2907 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002908 pRoamProfile = &pWextState->roamProfile;
2909 LastBSSType = pRoamProfile->BSSType;
2910
2911 switch (type)
2912 {
2913 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -07002914 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -07002915 hddLog(VOS_TRACE_LEVEL_INFO,
2916 "%s: setting interface Type to INFRASTRUCTURE", __func__);
2917 pRoamProfile->BSSType = eCSR_BSS_TYPE_INFRASTRUCTURE;
Jeff Johnsone7245742012-09-05 17:12:55 -07002918#ifdef WLAN_FEATURE_11AC
2919 if(pConfig->dot11Mode == eHDD_DOT11_MODE_AUTO)
2920 {
2921 pConfig->dot11Mode = eHDD_DOT11_MODE_11ac;
2922 }
2923#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302924 pRoamProfile->phyMode =
Jeff Johnsone7245742012-09-05 17:12:55 -07002925 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07002926 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08002927 //Check for sub-string p2p to confirm its a p2p interface
2928 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302929 {
Gopichand Nakkala864d3552012-12-31 16:08:51 -08002930 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
2931 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
2932 }
2933 else
2934 {
2935 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -07002936 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -08002937 }
Madan Mohan Koyyalamudi81746922013-07-17 14:38:51 +05302938#ifdef FEATURE_WLAN_TDLS
2939 /* The open adapter for the p2p shall skip initializations in
2940 * tdls_init if the device mode is WLAN_HDD_P2P_DEVICE, for
2941 * TDLS is supported only on WLAN_HDD_P2P_CLIENT. Hence invoke
2942 * tdls_init when the change_iface sets the device mode to
2943 * WLAN_HDD_P2P_CLIENT.
2944 */
2945
2946 if ( pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
2947 {
2948 if (0 != wlan_hdd_tdls_init (pAdapter))
2949 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302950 hddLog(VOS_TRACE_LEVEL_ERROR,
2951 "%s: tdls initialization failed", __func__);
Madan Mohan Koyyalamudi81746922013-07-17 14:38:51 +05302952 return -EINVAL;
2953 }
2954 }
2955#endif
2956
Jeff Johnson295189b2012-06-20 16:38:30 -07002957 break;
2958 case NL80211_IFTYPE_ADHOC:
2959 hddLog(VOS_TRACE_LEVEL_INFO,
2960 "%s: setting interface Type to ADHOC", __func__);
2961 pRoamProfile->BSSType = eCSR_BSS_TYPE_START_IBSS;
2962 pRoamProfile->phyMode =
2963 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Shailender Karmuchia734f332013-04-19 14:02:48 -07002964 pAdapter->device_mode = WLAN_HDD_IBSS;
Jeff Johnson295189b2012-06-20 16:38:30 -07002965 wdev->iftype = type;
2966 break;
2967
2968 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -07002969 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07002970 {
2971 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
2972 "%s: setting interface Type to %s", __func__,
2973 (type == NL80211_IFTYPE_AP) ? "SoftAP" : "P2pGo");
2974
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08002975 //Cancel any remain on channel for GO mode
2976 if (NL80211_IFTYPE_P2P_GO == type)
2977 {
2978 wlan_hdd_cancel_existing_remain_on_channel(pAdapter);
2979 }
Mohit Khanna0f232092012-09-11 14:46:08 -07002980 if (NL80211_IFTYPE_AP == type)
2981 {
2982 /* As Loading WLAN Driver one interface being created for p2p device
2983 * address. This will take one HW STA and the max number of clients
2984 * that can connect to softAP will be reduced by one. so while changing
2985 * the interface type to NL80211_IFTYPE_AP (SoftAP) remove p2p0
2986 * interface as it is not required in SoftAP mode.
2987 */
2988
2989 // Get P2P Adapter
2990 pP2pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_DEVICE);
2991
2992 if (pP2pAdapter)
2993 {
2994 hdd_stop_adapter(pHddCtx, pP2pAdapter);
2995 hdd_deinit_adapter(pHddCtx, pP2pAdapter);
2996 hdd_close_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
2997 }
2998 }
Swaroop Goltia2e32212014-04-09 23:37:33 +05302999 //Disable IMPS & BMPS for SAP/GO
3000 if(VOS_STATUS_E_FAILURE ==
3001 hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_P2P_GO))
3002 {
3003 //Fail to Exit BMPS
3004 VOS_ASSERT(0);
3005 }
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05303006#ifdef FEATURE_WLAN_TDLS
Mohit Khanna0f232092012-09-11 14:46:08 -07003007
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05303008 /* A Mutex Lock is introduced while changing the mode to
3009 * protect the concurrent access for the Adapters by TDLS
3010 * module.
3011 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05303012 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05303013#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07003014 //De-init the adapter.
3015 hdd_stop_adapter( pHddCtx, pAdapter );
3016 hdd_deinit_adapter( pHddCtx, pAdapter );
3017 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
Jeff Johnson295189b2012-06-20 16:38:30 -07003018 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
3019 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05303020#ifdef FEATURE_WLAN_TDLS
3021 mutex_unlock(&pHddCtx->tdls_lock);
3022#endif
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -07003023 if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) &&
3024 (pConfig->apRandomBssidEnabled))
3025 {
3026 /* To meet Android requirements create a randomized
3027 MAC address of the form 02:1A:11:Fx:xx:xx */
3028 get_random_bytes(&ndev->dev_addr[3], 3);
3029 ndev->dev_addr[0] = 0x02;
3030 ndev->dev_addr[1] = 0x1A;
3031 ndev->dev_addr[2] = 0x11;
3032 ndev->dev_addr[3] |= 0xF0;
3033 memcpy(pAdapter->macAddressCurrent.bytes, ndev->dev_addr,
3034 VOS_MAC_ADDR_SIZE);
Arif Hussain24bafea2013-11-15 15:10:03 -08003035 pr_info("wlan: Generated HotSpot BSSID " MAC_ADDRESS_STR"\n",
3036 MAC_ADDR_ARRAY(ndev->dev_addr));
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -07003037 }
3038
Jeff Johnson295189b2012-06-20 16:38:30 -07003039 hdd_set_ap_ops( pAdapter->dev );
3040
Kiet Lam10841362013-11-01 11:36:50 +05303041 /* This is for only SAP mode where users can
3042 * control country through ini.
3043 * P2P GO follows station country code
3044 * acquired during the STA scanning. */
3045 if((NL80211_IFTYPE_AP == type) &&
3046 (memcmp(pConfig->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0))
3047 {
3048 int status = 0;
3049 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_INFO,
3050 "%s: setting country code from INI ", __func__);
3051 init_completion(&pAdapter->change_country_code);
3052 status = (int)sme_ChangeCountryCode(pHddCtx->hHal,
3053 (void *)(tSmeChangeCountryCallback)
3054 wlan_hdd_change_country_code_cb,
3055 pConfig->apCntryCode, pAdapter,
3056 pHddCtx->pvosContext,
Abhishek Singha306a442013-11-07 18:39:01 +05303057 eSIR_FALSE,
3058 eSIR_TRUE);
Kiet Lam10841362013-11-01 11:36:50 +05303059 if (eHAL_STATUS_SUCCESS == status)
3060 {
3061 /* Wait for completion */
c_hpothu6ff1c3c2013-10-01 19:01:57 +05303062 ret = wait_for_completion_interruptible_timeout(
Kiet Lam10841362013-11-01 11:36:50 +05303063 &pAdapter->change_country_code,
3064 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05303065 if (ret <= 0)
Kiet Lam10841362013-11-01 11:36:50 +05303066 {
3067 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05303068 FL("SME Timed out while setting country code %ld"),
3069 ret);
Yue Ma4f55ef32014-01-23 16:45:33 -08003070
3071 if (pHddCtx->isLogpInProgress)
3072 {
3073 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3074 "%s: LOGP in Progress. Ignore!!!", __func__);
3075 return -EAGAIN;
3076 }
Kiet Lam10841362013-11-01 11:36:50 +05303077 }
3078 }
3079 else
3080 {
3081 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08003082 "%s: SME Change Country code failed",__func__);
Kiet Lam10841362013-11-01 11:36:50 +05303083 return -EINVAL;
3084 }
3085 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003086 status = hdd_init_ap_mode(pAdapter);
3087 if(status != VOS_STATUS_SUCCESS)
3088 {
3089 hddLog(VOS_TRACE_LEVEL_FATAL,
3090 "%s: Error initializing the ap mode", __func__);
3091 return -EINVAL;
3092 }
3093 hdd_set_conparam(1);
3094
Jeff Johnson295189b2012-06-20 16:38:30 -07003095 /*interface type changed update in wiphy structure*/
3096 if(wdev)
3097 {
3098 wdev->iftype = type;
3099 pHddCtx->change_iface = type;
3100 }
3101 else
3102 {
3103 hddLog(VOS_TRACE_LEVEL_ERROR,
3104 "%s: ERROR !!!! Wireless dev is NULL", __func__);
3105 return -EINVAL;
3106 }
3107 goto done;
3108 }
3109
3110 default:
3111 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
3112 __func__);
3113 return -EOPNOTSUPP;
3114 }
3115 }
3116 else if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07003117 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07003118 )
3119 {
3120 switch(type)
3121 {
3122 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -07003123 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -07003124 case NL80211_IFTYPE_ADHOC:
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05303125#ifdef FEATURE_WLAN_TDLS
3126
3127 /* A Mutex Lock is introduced while changing the mode to
3128 * protect the concurrent access for the Adapters by TDLS
3129 * module.
3130 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05303131 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05303132#endif
Jeff Johnson32d95a32012-09-10 13:15:23 -07003133 hdd_stop_adapter( pHddCtx, pAdapter );
3134 hdd_deinit_adapter( pHddCtx, pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07003135 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08003136 //Check for sub-string p2p to confirm its a p2p interface
3137 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala864d3552012-12-31 16:08:51 -08003138 {
3139 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
3140 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
3141 }
3142 else
3143 {
3144 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -07003145 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -08003146 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003147 hdd_set_conparam(0);
3148 pHddCtx->change_iface = type;
Jeff Johnson295189b2012-06-20 16:38:30 -07003149 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
3150 hdd_set_station_ops( pAdapter->dev );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05303151#ifdef FEATURE_WLAN_TDLS
3152 mutex_unlock(&pHddCtx->tdls_lock);
3153#endif
Sunil Dutt66485cb2013-12-19 19:05:03 +05303154 status = hdd_init_station_mode( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07003155 if( VOS_STATUS_SUCCESS != status )
3156 return -EOPNOTSUPP;
Jeff Johnsone7245742012-09-05 17:12:55 -07003157 /* In case of JB, for P2P-GO, only change interface will be called,
3158 * This is the right place to enable back bmps_imps()
3159 */
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05303160 if (pHddCtx->hdd_wlan_suspended)
3161 {
3162 hdd_set_pwrparams(pHddCtx);
3163 }
Jeff Johnsone7245742012-09-05 17:12:55 -07003164 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07003165 goto done;
3166 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -07003167 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07003168 wdev->iftype = type;
Jeff Johnson295189b2012-06-20 16:38:30 -07003169 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
3170 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Jeff Johnson295189b2012-06-20 16:38:30 -07003171 goto done;
3172 default:
3173 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
3174 __func__);
3175 return -EOPNOTSUPP;
3176
3177 }
3178
3179 }
3180 else
3181 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05303182 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: unsupported device mode(%d)",
3183 __func__, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07003184 return -EOPNOTSUPP;
3185 }
3186
3187
3188 if(pRoamProfile)
3189 {
3190 if ( LastBSSType != pRoamProfile->BSSType )
3191 {
3192 /*interface type changed update in wiphy structure*/
3193 wdev->iftype = type;
3194
3195 /*the BSS mode changed, We need to issue disconnect
3196 if connected or in IBSS disconnect state*/
3197 if ( hdd_connGetConnectedBssType(
3198 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), &connectedBssType ) ||
3199 ( eCSR_BSS_TYPE_START_IBSS == LastBSSType ) )
3200 {
3201 /*need to issue a disconnect to CSR.*/
3202 INIT_COMPLETION(pAdapter->disconnect_comp_var);
3203 if( eHAL_STATUS_SUCCESS ==
3204 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
3205 pAdapter->sessionId,
3206 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
3207 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05303208 ret = wait_for_completion_interruptible_timeout(
3209 &pAdapter->disconnect_comp_var,
3210 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
3211 if (ret <= 0)
3212 {
3213 hddLog(VOS_TRACE_LEVEL_ERROR,
3214 FL("wait on disconnect_comp_var failed %ld"), ret);
3215 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003216 }
3217 }
3218 }
3219 }
3220
3221done:
3222 /*set bitmask based on updated value*/
3223 wlan_hdd_set_concurrency_mode(pHddCtx, pAdapter->device_mode);
Leo Chang6fe1f922013-06-07 19:21:24 -07003224
3225 /* Only STA mode support TM now
3226 * all other mode, TM feature should be disabled */
3227 if ( (pHddCtx->cfg_ini->thermalMitigationEnable) &&
3228 (~VOS_STA & pHddCtx->concurrency_mode) )
3229 {
3230 hddDevTmLevelChangedHandler(pHddCtx->parent_dev, 0);
3231 }
3232
Jeff Johnson295189b2012-06-20 16:38:30 -07003233#ifdef WLAN_BTAMP_FEATURE
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303234 if((NL80211_IFTYPE_STATION == type) && (pHddCtx->concurrency_mode <= 1) &&
Jeff Johnson295189b2012-06-20 16:38:30 -07003235 (pHddCtx->no_of_sessions[WLAN_HDD_INFRA_STATION] <=1))
3236 {
3237 //we are ok to do AMP
3238 pHddCtx->isAmpAllowed = VOS_TRUE;
3239 }
3240#endif //WLAN_BTAMP_FEATURE
3241 EXIT();
3242 return 0;
3243}
3244
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +05303245/*
3246 * FUNCTION: wlan_hdd_cfg80211_change_iface
3247 * wrapper function to protect the actual implementation from SSR.
3248 */
3249int wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
3250 struct net_device *ndev,
3251 enum nl80211_iftype type,
3252 u32 *flags,
3253 struct vif_params *params
3254 )
3255{
3256 int ret;
3257
3258 vos_ssr_protect(__func__);
3259 ret = __wlan_hdd_cfg80211_change_iface(wiphy, ndev, type, flags, params);
3260 vos_ssr_unprotect(__func__);
3261
3262 return ret;
3263}
3264
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003265#ifdef FEATURE_WLAN_TDLS
3266static int wlan_hdd_tdls_add_station(struct wiphy *wiphy,
3267 struct net_device *dev, u8 *mac, bool update, tCsrStaParams *StaParams)
3268{
3269 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3270 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3271 VOS_STATUS status;
Hoonki Lee5305c3a2013-04-29 23:28:59 -07003272 hddTdlsPeer_t *pTdlsPeer;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05303273 long ret;
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05303274 tANI_U16 numCurrTdlsPeers;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003275
3276 ENTER();
3277
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05303278 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003279 {
3280 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3281 "Invalid arguments");
3282 return -EINVAL;
3283 }
Hoonki Lee27511902013-03-14 18:19:06 -07003284
3285 if ((eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode) ||
3286 (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode))
3287 {
3288 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
3289 "%s: TDLS mode is disabled OR not enabled in FW."
3290 MAC_ADDRESS_STR " Request declined.",
3291 __func__, MAC_ADDR_ARRAY(mac));
3292 return -ENOTSUPP;
3293 }
3294
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003295 if (pHddCtx->isLogpInProgress)
3296 {
3297 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3298 "%s:LOGP in Progress. Ignore!!!", __func__);
Gopichand Nakkala05922802013-03-14 12:23:19 -07003299 wlan_hdd_tdls_set_link_status(pAdapter, mac, eTDLS_LINK_IDLE);
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003300 return -EBUSY;
3301 }
3302
Naresh Jayaram9c6f4462014-02-13 12:20:31 +05303303 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, mac);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07003304
3305 if ( NULL == pTdlsPeer ) {
3306 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
3307 "%s: " MAC_ADDRESS_STR " (update %d) not exist. return invalid",
3308 __func__, MAC_ADDR_ARRAY(mac), update);
3309 return -EINVAL;
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07003310 }
Hoonki Lee5305c3a2013-04-29 23:28:59 -07003311
3312 /* in add station, we accept existing valid staId if there is */
3313 if ((0 == update) &&
3314 ((pTdlsPeer->link_status >= eTDLS_LINK_CONNECTING) ||
3315 (TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003316 {
Hoonki Lee5305c3a2013-04-29 23:28:59 -07003317 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003318 "%s: " MAC_ADDRESS_STR
Hoonki Lee5305c3a2013-04-29 23:28:59 -07003319 " link_status %d. staId %d. add station ignored.",
3320 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, pTdlsPeer->staId);
3321 return 0;
3322 }
3323 /* in change station, we accept only when staId is valid */
3324 if ((1 == update) &&
3325 ((pTdlsPeer->link_status > eTDLS_LINK_CONNECTING) ||
3326 (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
3327 {
3328 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
3329 "%s: " MAC_ADDRESS_STR
3330 " link status %d. staId %d. change station %s.",
3331 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, pTdlsPeer->staId,
3332 (TDLS_STA_INDEX_VALID(pTdlsPeer->staId)) ? "ignored" : "declined");
3333 return (TDLS_STA_INDEX_VALID(pTdlsPeer->staId)) ? 0 : -EPERM;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003334 }
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07003335
3336 /* when others are on-going, we want to change link_status to idle */
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05303337 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, mac, TRUE))
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003338 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07003339 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3340 "%s: " MAC_ADDRESS_STR
3341 " TDLS setup is ongoing. Request declined.",
3342 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala05922802013-03-14 12:23:19 -07003343 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003344 }
3345
3346 /* first to check if we reached to maximum supported TDLS peer.
3347 TODO: for now, return -EPERM looks working fine,
3348 but need to check if any other errno fit into this category.*/
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05303349 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
3350 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003351 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07003352 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3353 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05303354 " TDLS Max peer already connected. Request declined."
3355 " Num of peers (%d), Max allowed (%d).",
3356 __func__, MAC_ADDR_ARRAY(mac), numCurrTdlsPeers,
3357 HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -07003358 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003359 }
3360 else
3361 {
3362 hddTdlsPeer_t *pTdlsPeer;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05303363 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, mac, TRUE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003364 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003365 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07003366 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3367 "%s: " MAC_ADDRESS_STR " already connected. Request declined.",
3368 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003369 return -EPERM;
3370 }
3371 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003372 if (0 == update)
3373 wlan_hdd_tdls_set_link_status(pAdapter, mac, eTDLS_LINK_CONNECTING);
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003374
Jeff Johnsond75fe012013-04-06 10:53:06 -07003375 /* debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05303376 if (NULL != StaParams)
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003377 {
3378 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
3379 "%s: TDLS Peer Parameters.", __func__);
Hoonki Lee66b75f32013-04-16 18:30:07 -07003380 if(StaParams->htcap_present)
3381 {
3382 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
3383 "ht_capa->cap_info: %0x", StaParams->HTCap.capInfo);
3384 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
3385 "ht_capa->extended_capabilities: %0x",
3386 StaParams->HTCap.extendedHtCapInfo);
3387 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003388 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
3389 "params->capability: %0x",StaParams->capability);
3390 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07003391 "params->ext_capab_len: %0x",StaParams->extn_capability[0]);
Hoonki Lee66b75f32013-04-16 18:30:07 -07003392 if(StaParams->vhtcap_present)
3393 {
3394 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
3395 "rxMcsMap %x rxHighest %x txMcsMap %x txHighest %x",
3396 StaParams->VHTCap.suppMcs.rxMcsMap, StaParams->VHTCap.suppMcs.rxHighest,
3397 StaParams->VHTCap.suppMcs.txMcsMap, StaParams->VHTCap.suppMcs.txHighest);
3398 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003399 {
3400 int i = 0;
Hoonki Lee5305c3a2013-04-29 23:28:59 -07003401 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "Supported rates:");
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003402 for (i = 0; i < sizeof(StaParams->supported_rates); i++)
3403 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
3404 "[%d]: %x ", i, StaParams->supported_rates[i]);
3405 }
Jeff Johnsond75fe012013-04-06 10:53:06 -07003406 } /* end debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05303407 else if ((1 == update) && (NULL == StaParams))
3408 {
3409 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3410 "%s : update is true, but staParams is NULL. Error!", __func__);
3411 return -EPERM;
3412 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003413
3414 INIT_COMPLETION(pAdapter->tdls_add_station_comp);
3415
3416 if (!update)
3417 {
3418 status = sme_AddTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
3419 pAdapter->sessionId, mac);
3420 }
3421 else
3422 {
3423 status = sme_ChangeTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
3424 pAdapter->sessionId, mac, StaParams);
3425 }
3426
c_hpothu6ff1c3c2013-10-01 19:01:57 +05303427 ret = wait_for_completion_interruptible_timeout(&pAdapter->tdls_add_station_comp,
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003428 msecs_to_jiffies(WAIT_TIME_TDLS_ADD_STA));
3429
c_hpothu6ff1c3c2013-10-01 19:01:57 +05303430 if (ret <= 0)
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003431 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07003432 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05303433 "%s: timeout waiting for tdls add station indication %ld",
3434 __func__, ret);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07003435 return -EPERM;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003436 }
c_hpothu6ff1c3c2013-10-01 19:01:57 +05303437
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003438 if ( eHAL_STATUS_SUCCESS != pAdapter->tdlsAddStaStatus)
3439 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07003440 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003441 "%s: Add Station is unsucessful", __func__);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07003442 return -EPERM;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003443 }
3444
3445 return 0;
Gopichand Nakkala05922802013-03-14 12:23:19 -07003446
3447error:
3448 wlan_hdd_tdls_set_link_status(pAdapter, mac, eTDLS_LINK_IDLE);
3449 return -EPERM;
3450
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003451}
3452#endif
3453
Jeff Johnson295189b2012-06-20 16:38:30 -07003454static int wlan_hdd_change_station(struct wiphy *wiphy,
3455 struct net_device *dev,
3456 u8 *mac,
3457 struct station_parameters *params)
3458{
3459 VOS_STATUS status = VOS_STATUS_SUCCESS;
3460 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Gopichand Nakkala29149562013-05-10 21:43:41 +05303461 hdd_context_t *pHddCtx;
3462 hdd_station_ctx_t *pHddStaCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07003463 v_MACADDR_t STAMacAddress;
Gopichand Nakkalab0856222013-03-12 22:39:05 -07003464#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003465 tCsrStaParams StaParams = {0};
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003466 tANI_U8 isBufSta = 0;
Naresh Jayaram3180aa42014-02-12 21:47:26 +05303467 tANI_U8 isOffChannelSupported = 0;
Gopichand Nakkalab0856222013-03-12 22:39:05 -07003468#endif
Jeff Johnsone7245742012-09-05 17:12:55 -07003469 ENTER();
3470
Gopichand Nakkala29149562013-05-10 21:43:41 +05303471 if ((NULL == pAdapter))
3472 {
3473 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
3474 "invalid adapter ");
3475 return -EINVAL;
3476 }
3477
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05303478 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
3479 TRACE_CODE_HDD_CHANGE_STATION,
3480 pAdapter->sessionId, params->listen_interval));
Gopichand Nakkala29149562013-05-10 21:43:41 +05303481 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
3482 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3483
3484 if ((NULL == pHddCtx) || (NULL == pHddStaCtx))
3485 {
3486 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
3487 "invalid HDD state or HDD station context");
3488 return -EINVAL;
3489 }
3490
3491 if (pHddCtx->isLogpInProgress)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07003492 {
3493 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3494 "%s:LOGP in Progress. Ignore!!!", __func__);
3495 return -EAGAIN;
3496 }
3497
Jeff Johnson295189b2012-06-20 16:38:30 -07003498 vos_mem_copy(STAMacAddress.bytes, mac, sizeof(v_MACADDR_t));
3499
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003500 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
3501 || (pAdapter->device_mode == WLAN_HDD_P2P_GO))
Jeff Johnson295189b2012-06-20 16:38:30 -07003502 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003503 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED))
Jeff Johnson295189b2012-06-20 16:38:30 -07003504 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303505 status = hdd_softap_change_STA_state( pAdapter, &STAMacAddress,
Jeff Johnson295189b2012-06-20 16:38:30 -07003506 WLANTL_STA_AUTHENTICATED);
3507
Gopichand Nakkala29149562013-05-10 21:43:41 +05303508 if (status != VOS_STATUS_SUCCESS)
3509 {
3510 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3511 "%s: Not able to change TL state to AUTHENTICATED", __func__);
3512 return -EINVAL;
3513 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003514 }
3515 }
Hoonki Leea6d49be2013-04-05 09:43:25 -07003516 else if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
3517 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)) {
Gopichand Nakkala29149562013-05-10 21:43:41 +05303518#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003519 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
3520 StaParams.capability = params->capability;
3521 StaParams.uapsd_queues = params->uapsd_queues;
3522 StaParams.max_sp = params->max_sp;
3523
Naresh Jayaram3180aa42014-02-12 21:47:26 +05303524 /* Convert (first channel , number of channels) tuple to
3525 * the total list of channels. This goes with the assumption
3526 * that if the first channel is < 14, then the next channels
3527 * are an incremental of 1 else an incremental of 4 till the number
3528 * of channels.
3529 */
3530 if (0 != params->supported_channels_len) {
3531 int i = 0,j = 0,k = 0, no_of_channels = 0 ;
3532 for ( i = 0 ; i < params->supported_channels_len ; i+=2)
3533 {
3534 int wifi_chan_index;
3535 StaParams.supported_channels[j] = params->supported_channels[i];
3536 wifi_chan_index =
3537 ((StaParams.supported_channels[j] <= HDD_CHANNEL_14 ) ? 1 : 4 );
3538 no_of_channels = params->supported_channels[i+1];
3539 for(k=1; k <= no_of_channels; k++)
3540 {
3541 StaParams.supported_channels[j+1] =
3542 StaParams.supported_channels[j] + wifi_chan_index;
3543 j+=1;
3544 }
3545 }
3546 StaParams.supported_channels_len = j;
3547 }
3548 vos_mem_copy(StaParams.supported_oper_classes,
3549 params->supported_oper_classes,
3550 params->supported_oper_classes_len);
3551 StaParams.supported_oper_classes_len =
3552 params->supported_oper_classes_len;
3553
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003554 if (0 != params->ext_capab_len)
3555 vos_mem_copy(StaParams.extn_capability, params->ext_capab,
3556 sizeof(StaParams.extn_capability));
3557
3558 if (NULL != params->ht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -07003559 {
3560 StaParams.htcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003561 vos_mem_copy(&StaParams.HTCap, params->ht_capa, sizeof(tSirHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -07003562 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003563
3564 StaParams.supported_rates_len = params->supported_rates_len;
3565
3566 /* Note : The Maximum sizeof supported_rates sent by the Supplicant is 32.
3567 * The supported_rates array , for all the structures propogating till Add Sta
3568 * to the firmware has to be modified , if the supplicant (ieee80211) is
3569 * modified to send more rates.
3570 */
3571
3572 /* To avoid Data Currption , set to max length to SIR_MAC_MAX_SUPP_RATES
3573 */
3574 if (StaParams.supported_rates_len > SIR_MAC_MAX_SUPP_RATES)
3575 StaParams.supported_rates_len = SIR_MAC_MAX_SUPP_RATES;
3576
3577 if (0 != StaParams.supported_rates_len) {
3578 int i = 0;
3579 vos_mem_copy(StaParams.supported_rates, params->supported_rates,
3580 StaParams.supported_rates_len);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07003581 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003582 "Supported Rates with Length %d", StaParams.supported_rates_len);
3583 for (i=0; i < StaParams.supported_rates_len; i++)
Hoonki Lee5305c3a2013-04-29 23:28:59 -07003584 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003585 "[%d]: %0x", i, StaParams.supported_rates[i]);
3586 }
3587
3588 if (NULL != params->vht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -07003589 {
3590 StaParams.vhtcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003591 vos_mem_copy(&StaParams.VHTCap, params->vht_capa, sizeof(tSirVHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -07003592 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003593
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003594 if (0 != params->ext_capab_len ) {
3595 /*Define A Macro : TODO Sunil*/
3596 if ((1<<4) & StaParams.extn_capability[3]) {
3597 isBufSta = 1;
3598 }
Naresh Jayaram3180aa42014-02-12 21:47:26 +05303599 /* TDLS Channel Switching Support */
3600 if ((1<<6) & StaParams.extn_capability[3]) {
3601 isOffChannelSupported = 1;
3602 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003603 }
Naresh Jayaram3180aa42014-02-12 21:47:26 +05303604 status = wlan_hdd_tdls_set_peer_caps( pAdapter, mac,
3605 &StaParams, isBufSta,
3606 isOffChannelSupported);
3607
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05303608 if (VOS_STATUS_SUCCESS != status) {
3609 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3610 "%s: wlan_hdd_tdls_set_peer_caps failed!", __func__);
3611 return -EINVAL;
3612 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003613 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 1, &StaParams);
3614
3615 if (VOS_STATUS_SUCCESS != status) {
3616 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3617 "%s: sme_ChangeTdlsPeerSta failed!", __func__);
3618 return -EINVAL;
3619 }
3620 }
Gopichand Nakkalab0856222013-03-12 22:39:05 -07003621#endif
Gopichand Nakkala6239acd2013-06-14 14:48:00 +05303622 }
Jeff Johnsone7245742012-09-05 17:12:55 -07003623 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07003624 return status;
3625}
3626
3627/*
Jeff Johnson295189b2012-06-20 16:38:30 -07003628 * FUNCTION: wlan_hdd_cfg80211_add_key
3629 * This function is used to initialize the key information
3630 */
3631#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003632static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07003633 struct net_device *ndev,
3634 u8 key_index, bool pairwise,
3635 const u8 *mac_addr,
3636 struct key_params *params
3637 )
3638#else
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003639static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07003640 struct net_device *ndev,
3641 u8 key_index, const u8 *mac_addr,
3642 struct key_params *params
3643 )
3644#endif
3645{
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003646 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -07003647 tCsrRoamSetKey setKey;
3648 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05303649 int status;
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003650 v_U32_t roamId= 0xFF;
3651 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07003652 hdd_hostapd_state_t *pHostapdState;
3653 VOS_STATUS vos_status;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07003654 eHalStatus halStatus;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05303655 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07003656
3657 ENTER();
3658
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05303659 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
3660 TRACE_CODE_HDD_CFG80211_ADD_KEY,
3661 pAdapter->sessionId, params->key_len));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05303662 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
3663 status = wlan_hdd_validate_context(pHddCtx);
3664
3665 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07003666 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05303667 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3668 "%s: HDD context is not valid", __func__);
3669 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07003670 }
3671
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003672 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
3673 __func__, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07003674
3675 if (CSR_MAX_NUM_KEY <= key_index)
3676 {
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003677 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07003678 key_index);
3679
3680 return -EINVAL;
3681 }
3682
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003683 if (CSR_MAX_KEY_LEN < params->key_len)
3684 {
3685 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key length %d", __func__,
3686 params->key_len);
3687
3688 return -EINVAL;
3689 }
3690
3691 hddLog(VOS_TRACE_LEVEL_INFO,
3692 "%s: called with key index = %d & key length %d",
3693 __func__, key_index, params->key_len);
Jeff Johnson295189b2012-06-20 16:38:30 -07003694
3695 /*extract key idx, key len and key*/
3696 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
3697 setKey.keyId = key_index;
3698 setKey.keyLength = params->key_len;
3699 vos_mem_copy(&setKey.Key[0],params->key, params->key_len);
3700
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003701 switch (params->cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -07003702 {
3703 case WLAN_CIPHER_SUITE_WEP40:
3704 setKey.encType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
3705 break;
3706
3707 case WLAN_CIPHER_SUITE_WEP104:
3708 setKey.encType = eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
3709 break;
3710
3711 case WLAN_CIPHER_SUITE_TKIP:
3712 {
3713 u8 *pKey = &setKey.Key[0];
3714 setKey.encType = eCSR_ENCRYPT_TYPE_TKIP;
3715
3716 vos_mem_zero(pKey, CSR_MAX_KEY_LEN);
3717
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003718 /*Supplicant sends the 32bytes key in this order
Jeff Johnson295189b2012-06-20 16:38:30 -07003719
3720 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003721 | Tk1 |TX-MIC | RX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -07003722 |--------------|----------|----------|
3723 <---16bytes---><--8bytes--><--8bytes-->
3724
3725 */
3726 /*Sme expects the 32 bytes key to be in the below order
3727
3728 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003729 | Tk1 |RX-MIC | TX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -07003730 |--------------|----------|----------|
3731 <---16bytes---><--8bytes--><--8bytes-->
3732 */
3733 /* Copy the Temporal Key 1 (TK1) */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003734 vos_mem_copy(pKey, params->key, 16);
Jeff Johnson295189b2012-06-20 16:38:30 -07003735
3736 /*Copy the rx mic first*/
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003737 vos_mem_copy(&pKey[16], &params->key[24], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -07003738
3739 /*Copy the tx mic */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003740 vos_mem_copy(&pKey[24], &params->key[16], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -07003741
3742
3743 break;
3744 }
3745
3746 case WLAN_CIPHER_SUITE_CCMP:
3747 setKey.encType = eCSR_ENCRYPT_TYPE_AES;
3748 break;
3749
3750#ifdef FEATURE_WLAN_WAPI
3751 case WLAN_CIPHER_SUITE_SMS4:
3752 {
3753 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
3754 wlan_hdd_cfg80211_set_key_wapi(pAdapter, key_index, mac_addr,
3755 params->key, params->key_len);
3756 return 0;
3757 }
3758#endif
Chet Lanctot186b5732013-03-18 10:26:30 -07003759
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003760#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -07003761 case WLAN_CIPHER_SUITE_KRK:
3762 setKey.encType = eCSR_ENCRYPT_TYPE_KRK;
3763 break;
3764#endif
Chet Lanctot186b5732013-03-18 10:26:30 -07003765
3766#ifdef WLAN_FEATURE_11W
3767 case WLAN_CIPHER_SUITE_AES_CMAC:
3768 setKey.encType = eCSR_ENCRYPT_TYPE_AES_CMAC;
Chet Lanctot3b5158a2013-03-31 16:45:21 -07003769 break;
Chet Lanctot186b5732013-03-18 10:26:30 -07003770#endif
3771
Jeff Johnson295189b2012-06-20 16:38:30 -07003772 default:
Jeff Johnson0299d0a2013-10-30 12:37:43 -07003773 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unsupported cipher type %u",
Jeff Johnson295189b2012-06-20 16:38:30 -07003774 __func__, params->cipher);
3775 return -EOPNOTSUPP;
3776 }
3777
3778 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: encryption type %d",
3779 __func__, setKey.encType);
3780
Shailender Karmuchi642e9812013-05-30 14:34:49 -07003781 if (
Jeff Johnson295189b2012-06-20 16:38:30 -07003782#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
3783 (!pairwise)
3784#else
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003785 (!mac_addr || is_broadcast_ether_addr(mac_addr))
Jeff Johnson295189b2012-06-20 16:38:30 -07003786#endif
Shailender Karmuchi642e9812013-05-30 14:34:49 -07003787 )
3788 {
3789 /* set group key*/
3790 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3791 "%s- %d: setting Broadcast key",
3792 __func__, __LINE__);
3793 setKey.keyDirection = eSIR_RX_ONLY;
3794 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
3795 }
3796 else
3797 {
3798 /* set pairwise key*/
3799 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3800 "%s- %d: setting pairwise key",
3801 __func__, __LINE__);
3802 setKey.keyDirection = eSIR_TX_RX;
3803 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
3804 }
3805 if ((WLAN_HDD_IBSS == pAdapter->device_mode) && !pairwise)
3806 {
3807 setKey.keyDirection = eSIR_TX_RX;
3808 /*Set the group key*/
3809 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
3810 pAdapter->sessionId, &setKey, &roamId );
Jeff Johnson295189b2012-06-20 16:38:30 -07003811
Shailender Karmuchi642e9812013-05-30 14:34:49 -07003812 if ( 0 != status )
3813 {
3814 hddLog(VOS_TRACE_LEVEL_ERROR,
3815 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
3816 return -EINVAL;
3817 }
3818 /*Save the keys here and call sme_RoamSetKey for setting
3819 the PTK after peer joins the IBSS network*/
3820 vos_mem_copy(&pAdapter->sessionCtx.station.ibss_enc_key,
3821 &setKey, sizeof(tCsrRoamSetKey));
3822 return status;
3823 }
Gopichand Nakkala29149562013-05-10 21:43:41 +05303824 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP) ||
3825 (pAdapter->device_mode == WLAN_HDD_P2P_GO))
3826 {
Jeff Johnson295189b2012-06-20 16:38:30 -07003827 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003828 if( pHostapdState->bssState == BSS_START )
3829 {
c_hpothu7c55da62014-01-23 18:34:02 +05303830 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3831 vos_status = wlan_hdd_check_ula_done(pAdapter);
3832
3833 if ( vos_status != VOS_STATUS_SUCCESS )
3834 {
3835 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3836 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
3837 __LINE__, vos_status );
3838
3839 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
3840
3841 return -EINVAL;
3842 }
3843
Jeff Johnson295189b2012-06-20 16:38:30 -07003844 status = WLANSAP_SetKeySta( pVosContext, &setKey);
3845
3846 if ( status != eHAL_STATUS_SUCCESS )
3847 {
3848 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3849 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
3850 __LINE__, status );
3851 }
3852 }
3853
3854 /* Saving WEP keys */
3855 else if( eCSR_ENCRYPT_TYPE_WEP40_STATICKEY == setKey.encType ||
3856 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY == setKey.encType )
3857 {
3858 //Save the wep key in ap context. Issue setkey after the BSS is started.
3859 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
3860 vos_mem_copy(&pAPCtx->wepKey[key_index], &setKey, sizeof(tCsrRoamSetKey));
3861 }
3862 else
3863 {
3864 //Save the key in ap context. Issue setkey after the BSS is started.
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003865 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07003866 vos_mem_copy(&pAPCtx->groupKey, &setKey, sizeof(tCsrRoamSetKey));
3867 }
3868 }
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003869 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION) ||
3870 (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT) )
Jeff Johnson295189b2012-06-20 16:38:30 -07003871 {
3872 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
3873 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3874
Gopichand Nakkala3d295922013-05-07 16:19:14 +05303875#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
3876 if (!pairwise)
3877#else
3878 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
3879#endif
3880 {
3881 /* set group key*/
3882 if (pHddStaCtx->roam_info.deferKeyComplete)
3883 {
3884 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3885 "%s- %d: Perform Set key Complete",
3886 __func__, __LINE__);
3887 hdd_PerformRoamSetKeyComplete(pAdapter);
3888 }
3889 }
3890
Jeff Johnson295189b2012-06-20 16:38:30 -07003891 pWextState->roamProfile.Keys.KeyLength[key_index] = (u8)params->key_len;
3892
Venkata Prathyusha Kuntupalliee2ce712013-01-17 14:09:24 -08003893 pWextState->roamProfile.Keys.defaultIndex = key_index;
3894
3895
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003896 vos_mem_copy(&pWextState->roamProfile.Keys.KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -07003897 params->key, params->key_len);
3898
Gopichand Nakkala3d295922013-05-07 16:19:14 +05303899
Jeff Johnson295189b2012-06-20 16:38:30 -07003900 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
3901
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303902 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -07003903 "%s: set key for peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303904 __func__, setKey.peerMac[0], setKey.peerMac[1],
3905 setKey.peerMac[2], setKey.peerMac[3],
3906 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -07003907 setKey.keyDirection);
3908
3909 vos_status = wlan_hdd_check_ula_done(pAdapter);
3910
3911 if ( vos_status != VOS_STATUS_SUCCESS )
3912 {
3913 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3914 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
3915 __LINE__, vos_status );
3916
3917 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
3918
3919 return -EINVAL;
3920
3921 }
3922
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07003923#ifdef WLAN_FEATURE_VOWIFI_11R
Gopichand Nakkala3d295922013-05-07 16:19:14 +05303924 /* The supplicant may attempt to set the PTK once pre-authentication
3925 is done. Save the key in the UMAC and include it in the ADD BSS
3926 request */
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07003927 halStatus = sme_FTUpdateKey( WLAN_HDD_GET_HAL_CTX(pAdapter), &setKey);
Gopichand Nakkala3d295922013-05-07 16:19:14 +05303928 if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_SUCCESS )
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07003929 {
Gopichand Nakkala3d295922013-05-07 16:19:14 +05303930 hddLog(VOS_TRACE_LEVEL_INFO_MED,
3931 "%s: Update PreAuth Key success", __func__);
3932 return 0;
3933 }
3934 else if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_FAILED )
3935 {
3936 hddLog(VOS_TRACE_LEVEL_ERROR,
3937 "%s: Update PreAuth Key failed", __func__);
Gopichand Nakkalad7d13652013-02-15 01:48:00 +05303938 return -EINVAL;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07003939 }
3940#endif /* WLAN_FEATURE_VOWIFI_11R */
Jeff Johnson295189b2012-06-20 16:38:30 -07003941
3942 /* issue set key request to SME*/
3943 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
3944 pAdapter->sessionId, &setKey, &roamId );
3945
3946 if ( 0 != status )
3947 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303948 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07003949 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
3950 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
3951 return -EINVAL;
3952 }
3953
3954
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303955 /* in case of IBSS as there was no information available about WEP keys during
3956 * IBSS join, group key intialized with NULL key, so re-initialize group key
Jeff Johnson295189b2012-06-20 16:38:30 -07003957 * with correct value*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303958 if ( (eCSR_BSS_TYPE_START_IBSS == pWextState->roamProfile.BSSType) &&
3959 !( ( IW_AUTH_KEY_MGMT_802_1X
3960 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X))
Jeff Johnson295189b2012-06-20 16:38:30 -07003961 && (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType)
3962 )
3963 &&
3964 ( (WLAN_CIPHER_SUITE_WEP40 == params->cipher)
3965 || (WLAN_CIPHER_SUITE_WEP104 == params->cipher)
3966 )
3967 )
3968 {
3969 setKey.keyDirection = eSIR_RX_ONLY;
3970 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
3971
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303972 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -07003973 "%s: set key peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303974 __func__, setKey.peerMac[0], setKey.peerMac[1],
3975 setKey.peerMac[2], setKey.peerMac[3],
3976 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -07003977 setKey.keyDirection);
3978
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303979 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07003980 pAdapter->sessionId, &setKey, &roamId );
3981
3982 if ( 0 != status )
3983 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303984 hddLog(VOS_TRACE_LEVEL_ERROR,
3985 "%s: sme_RoamSetKey failed for group key (IBSS), returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07003986 __func__, status);
3987 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
3988 return -EINVAL;
3989 }
3990 }
3991 }
3992
3993 return 0;
3994}
3995
3996/*
3997 * FUNCTION: wlan_hdd_cfg80211_get_key
3998 * This function is used to get the key information
3999 */
4000#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304001static int wlan_hdd_cfg80211_get_key(
4002 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07004003 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304004 u8 key_index, bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -07004005 const u8 *mac_addr, void *cookie,
4006 void (*callback)(void *cookie, struct key_params*)
4007 )
4008#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304009static int wlan_hdd_cfg80211_get_key(
4010 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07004011 struct net_device *ndev,
4012 u8 key_index, const u8 *mac_addr, void *cookie,
4013 void (*callback)(void *cookie, struct key_params*)
4014 )
4015#endif
4016{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304017 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -07004018 hdd_wext_state_t *pWextState= WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
4019 tCsrRoamProfile *pRoamProfile = &(pWextState->roamProfile);
4020 struct key_params params;
4021
4022 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304023
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05304024 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
4025 TRACE_CODE_HDD_CFG80211_GET_KEY,
4026 pAdapter->sessionId, params.cipher));
Arif Hussain6d2a3322013-11-17 19:50:10 -08004027 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07004028 __func__,pAdapter->device_mode);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304029
Jeff Johnson295189b2012-06-20 16:38:30 -07004030 memset(&params, 0, sizeof(params));
4031
4032 if (CSR_MAX_NUM_KEY <= key_index)
4033 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05304034 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid key index %d"), key_index);
Jeff Johnson295189b2012-06-20 16:38:30 -07004035 return -EINVAL;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304036 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004037
4038 switch(pRoamProfile->EncryptionType.encryptionType[0])
4039 {
4040 case eCSR_ENCRYPT_TYPE_NONE:
4041 params.cipher = IW_AUTH_CIPHER_NONE;
4042 break;
4043
4044 case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY:
4045 case eCSR_ENCRYPT_TYPE_WEP40:
4046 params.cipher = WLAN_CIPHER_SUITE_WEP40;
4047 break;
4048
4049 case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY:
4050 case eCSR_ENCRYPT_TYPE_WEP104:
4051 params.cipher = WLAN_CIPHER_SUITE_WEP104;
4052 break;
4053
4054 case eCSR_ENCRYPT_TYPE_TKIP:
4055 params.cipher = WLAN_CIPHER_SUITE_TKIP;
4056 break;
4057
4058 case eCSR_ENCRYPT_TYPE_AES:
4059 params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
4060 break;
4061
4062 default:
4063 params.cipher = IW_AUTH_CIPHER_NONE;
4064 break;
4065 }
4066
4067 params.key_len = pRoamProfile->Keys.KeyLength[key_index];
4068 params.seq_len = 0;
4069 params.seq = NULL;
4070 params.key = &pRoamProfile->Keys.KeyMaterial[key_index][0];
4071 callback(cookie, &params);
4072 return 0;
4073}
4074
4075/*
4076 * FUNCTION: wlan_hdd_cfg80211_del_key
4077 * This function is used to delete the key information
4078 */
4079#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304080static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07004081 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304082 u8 key_index,
4083 bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -07004084 const u8 *mac_addr
4085 )
4086#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304087static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07004088 struct net_device *ndev,
4089 u8 key_index,
4090 const u8 *mac_addr
4091 )
4092#endif
4093{
4094 int status = 0;
4095
4096 //This code needs to be revisited. There is sme_removeKey API, we should
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304097 //plan to use that. After the change to use correct index in setkey,
Jeff Johnson295189b2012-06-20 16:38:30 -07004098 //it is observed that this is invalidating peer
4099 //key index whenever re-key is done. This is affecting data link.
4100 //It should be ok to ignore del_key.
4101#if 0
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304102 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
4103 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07004104 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
4105 tCsrRoamSetKey setKey;
4106 v_U32_t roamId= 0xFF;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304107
Jeff Johnson295189b2012-06-20 16:38:30 -07004108 ENTER();
4109
4110 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device_mode = %d\n",
4111 __func__,pAdapter->device_mode);
4112
4113 if (CSR_MAX_NUM_KEY <= key_index)
4114 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304115 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07004116 key_index);
4117
4118 return -EINVAL;
4119 }
4120
4121 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
4122 setKey.keyId = key_index;
4123
4124 if (mac_addr)
4125 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
4126 else
4127 vos_mem_copy(setKey.peerMac, groupmacaddr, WNI_CFG_BSSID_LEN);
4128
4129 setKey.encType = eCSR_ENCRYPT_TYPE_NONE;
4130
4131 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07004132 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304133 )
4134 {
4135
4136 hdd_hostapd_state_t *pHostapdState =
Jeff Johnson295189b2012-06-20 16:38:30 -07004137 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
4138 if( pHostapdState->bssState == BSS_START)
4139 {
4140 status = WLANSAP_SetKeySta( pVosContext, &setKey);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304141
Jeff Johnson295189b2012-06-20 16:38:30 -07004142 if ( status != eHAL_STATUS_SUCCESS )
4143 {
4144 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4145 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
4146 __LINE__, status );
4147 }
4148 }
4149 }
4150 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304151 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnson295189b2012-06-20 16:38:30 -07004152 )
4153 {
4154 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4155
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304156 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
4157
4158 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -07004159 "%s: delete key for peerMac %2x:%2x:%2x:%2x:%2x:%2x",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304160 __func__, setKey.peerMac[0], setKey.peerMac[1],
4161 setKey.peerMac[2], setKey.peerMac[3],
Jeff Johnson295189b2012-06-20 16:38:30 -07004162 setKey.peerMac[4], setKey.peerMac[5]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304163 if(pAdapter->sessionCtx.station.conn_info.connState ==
4164 eConnectionState_Associated)
Jeff Johnson295189b2012-06-20 16:38:30 -07004165 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304166 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07004167 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304168
Jeff Johnson295189b2012-06-20 16:38:30 -07004169 if ( 0 != status )
4170 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304171 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07004172 "%s: sme_RoamSetKey failure, returned %d",
4173 __func__, status);
4174 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
4175 return -EINVAL;
4176 }
4177 }
4178 }
4179#endif
Jeff Johnsone7245742012-09-05 17:12:55 -07004180 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07004181 return status;
4182}
4183
4184/*
4185 * FUNCTION: wlan_hdd_cfg80211_set_default_key
4186 * This function is used to set the default tx key index
4187 */
4188#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
4189static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
4190 struct net_device *ndev,
4191 u8 key_index,
4192 bool unicast, bool multicast)
4193#else
4194static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
4195 struct net_device *ndev,
4196 u8 key_index)
4197#endif
4198{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304199 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05304200 int status;
Gopichand Nakkala29149562013-05-10 21:43:41 +05304201 hdd_wext_state_t *pWextState;
4202 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05304203 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07004204
4205 ENTER();
4206
Gopichand Nakkala29149562013-05-10 21:43:41 +05304207 if ((NULL == pAdapter))
4208 {
4209 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
4210 "invalid adapter");
4211 return -EINVAL;
4212 }
4213
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05304214 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
4215 TRACE_CODE_HDD_CFG80211_SET_DEFAULT_KEY,
4216 pAdapter->sessionId, key_index));
4217
Gopichand Nakkala29149562013-05-10 21:43:41 +05304218 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
4219 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4220
4221 if ((NULL == pWextState) || (NULL == pHddStaCtx))
4222 {
4223 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
4224 "invalid Wext state or HDD context");
4225 return -EINVAL;
4226 }
4227
Arif Hussain6d2a3322013-11-17 19:50:10 -08004228 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d key_index = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07004229 __func__,pAdapter->device_mode, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304230
Jeff Johnson295189b2012-06-20 16:38:30 -07004231 if (CSR_MAX_NUM_KEY <= key_index)
4232 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304233 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07004234 key_index);
4235
4236 return -EINVAL;
4237 }
4238
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05304239 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
4240 status = wlan_hdd_validate_context(pHddCtx);
4241
4242 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004243 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05304244 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4245 "%s: HDD context is not valid", __func__);
4246 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004247 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304248
Jeff Johnson295189b2012-06-20 16:38:30 -07004249 if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -07004250 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304251 )
Jeff Johnson295189b2012-06-20 16:38:30 -07004252 {
Gopichand Nakkala29149562013-05-10 21:43:41 +05304253 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
Arif Hussain6943f522013-11-04 20:10:10 -08004254 pHddStaCtx->conn_info.ucEncryptionType) &&
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304255 (eCSR_ENCRYPT_TYPE_AES !=
Arif Hussain6943f522013-11-04 20:10:10 -08004256 pHddStaCtx->conn_info.ucEncryptionType)
Jeff Johnson295189b2012-06-20 16:38:30 -07004257 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304258 {
4259 /* if default key index is not same as previous one,
Jeff Johnson295189b2012-06-20 16:38:30 -07004260 * then update the default key index */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304261
Jeff Johnson295189b2012-06-20 16:38:30 -07004262 tCsrRoamSetKey setKey;
4263 v_U32_t roamId= 0xFF;
4264 tCsrKeys *Keys = &pWextState->roamProfile.Keys;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304265
4266 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: default tx key index %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07004267 __func__, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304268
Jeff Johnson295189b2012-06-20 16:38:30 -07004269 Keys->defaultIndex = (u8)key_index;
4270 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
4271 setKey.keyId = key_index;
4272 setKey.keyLength = Keys->KeyLength[key_index];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304273
4274 vos_mem_copy(&setKey.Key[0],
4275 &Keys->KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -07004276 Keys->KeyLength[key_index]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304277
Gopichand Nakkala29149562013-05-10 21:43:41 +05304278 setKey.keyDirection = eSIR_TX_RX;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304279
4280 vos_mem_copy(setKey.peerMac,
Jeff Johnson295189b2012-06-20 16:38:30 -07004281 &pHddStaCtx->conn_info.bssId[0],
4282 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304283
Gopichand Nakkala29149562013-05-10 21:43:41 +05304284 if (Keys->KeyLength[key_index] == CSR_WEP40_KEY_LEN &&
4285 pWextState->roamProfile.EncryptionType.encryptionType[0] ==
4286 eCSR_ENCRYPT_TYPE_WEP104)
4287 {
4288 /*In the case of dynamic wep supplicant hardcodes DWEP type to eCSR_ENCRYPT_TYPE_WEP104
4289 even though ap is configured for WEP-40 encryption. In this canse the key length
4290 is 5 but the encryption type is 104 hence checking the key langht(5) and encryption
4291 type(104) and switching encryption type to 40*/
4292 pWextState->roamProfile.EncryptionType.encryptionType[0] =
4293 eCSR_ENCRYPT_TYPE_WEP40;
4294 pWextState->roamProfile.mcEncryptionType.encryptionType[0] =
4295 eCSR_ENCRYPT_TYPE_WEP40;
4296 }
4297
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304298 setKey.encType =
Jeff Johnson295189b2012-06-20 16:38:30 -07004299 pWextState->roamProfile.EncryptionType.encryptionType[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304300
Jeff Johnson295189b2012-06-20 16:38:30 -07004301 /* issue set key request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304302 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07004303 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304304
Jeff Johnson295189b2012-06-20 16:38:30 -07004305 if ( 0 != status )
4306 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304307 hddLog(VOS_TRACE_LEVEL_ERROR,
4308 "%s: sme_RoamSetKey failed, returned %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07004309 status);
4310 return -EINVAL;
4311 }
4312 }
4313 }
4314
4315 /* In SoftAp mode setting key direction for default mode */
4316 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
4317 {
4318 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
4319 pWextState->roamProfile.EncryptionType.encryptionType[0]) &&
4320 (eCSR_ENCRYPT_TYPE_AES !=
4321 pWextState->roamProfile.EncryptionType.encryptionType[0])
4322 )
4323 {
4324 /* Saving key direction for default key index to TX default */
4325 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
4326 pAPCtx->wepKey[key_index].keyDirection = eSIR_TX_DEFAULT;
4327 }
4328 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304329
Jeff Johnson295189b2012-06-20 16:38:30 -07004330 return status;
4331}
4332
Jeff Johnson295189b2012-06-20 16:38:30 -07004333/*
4334 * FUNCTION: wlan_hdd_cfg80211_inform_bss
4335 * This function is used to inform the BSS details to nl80211 interface.
4336 */
4337static struct cfg80211_bss* wlan_hdd_cfg80211_inform_bss(
4338 hdd_adapter_t *pAdapter, tCsrRoamConnectedProfile *roamProfile)
4339{
4340 struct net_device *dev = pAdapter->dev;
4341 struct wireless_dev *wdev = dev->ieee80211_ptr;
4342 struct wiphy *wiphy = wdev->wiphy;
4343 tSirBssDescription *pBssDesc = roamProfile->pBssDesc;
4344 int chan_no;
4345 int ie_length;
4346 const char *ie;
4347 unsigned int freq;
4348 struct ieee80211_channel *chan;
4349 int rssi = 0;
4350 struct cfg80211_bss *bss = NULL;
4351
4352 ENTER();
4353
4354 if( NULL == pBssDesc )
4355 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08004356 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pBssDesc is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004357 return bss;
4358 }
4359
4360 chan_no = pBssDesc->channelId;
4361 ie_length = GET_IE_LEN_IN_BSS_DESC( pBssDesc->length );
4362 ie = ((ie_length != 0) ? (const char *)&pBssDesc->ieFields: NULL);
4363
4364 if( NULL == ie )
4365 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08004366 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: IE of BSS descriptor is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004367 return bss;
4368 }
4369
4370#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
4371 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
4372 {
4373 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
4374 }
4375 else
4376 {
4377 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
4378 }
4379#else
4380 freq = ieee80211_channel_to_frequency(chan_no);
4381#endif
4382
4383 chan = __ieee80211_get_channel(wiphy, freq);
4384
Santhosh Kumar Padmaa45fdb12014-04-15 15:54:38 +05304385 if (!chan) {
4386 hddLog(VOS_TRACE_LEVEL_ERROR, "%s chan pointer is NULL", __func__);
4387 return NULL;
4388 }
4389
Jeff Johnson295189b2012-06-20 16:38:30 -07004390 bss = cfg80211_get_bss(wiphy, chan, pBssDesc->bssId,
4391 &roamProfile->SSID.ssId[0], roamProfile->SSID.length,
4392 WLAN_CAPABILITY_ESS, WLAN_CAPABILITY_ESS);
4393 if (bss == NULL)
4394 {
4395 rssi = (VOS_MIN ((pBssDesc->rssi + pBssDesc->sinr), 0))*100;
4396
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304397 return (cfg80211_inform_bss(wiphy, chan, pBssDesc->bssId,
4398 le64_to_cpu(*(__le64 *)pBssDesc->timeStamp),
Jeff Johnson295189b2012-06-20 16:38:30 -07004399 pBssDesc->capabilityInfo,
4400 pBssDesc->beaconInterval, ie, ie_length,
4401 rssi, GFP_KERNEL ));
4402}
4403 else
4404 {
4405 return bss;
4406 }
4407}
4408
4409
4410
4411/*
4412 * FUNCTION: wlan_hdd_cfg80211_inform_bss_frame
4413 * This function is used to inform the BSS details to nl80211 interface.
4414 */
4415struct cfg80211_bss*
4416wlan_hdd_cfg80211_inform_bss_frame( hdd_adapter_t *pAdapter,
4417 tSirBssDescription *bss_desc
4418 )
4419{
4420 /*
4421 cfg80211_inform_bss() is not updating ie field of bss entry, if entry
4422 already exists in bss data base of cfg80211 for that particular BSS ID.
4423 Using cfg80211_inform_bss_frame to update the bss entry instead of
4424 cfg80211_inform_bss, But this call expects mgmt packet as input. As of
4425 now there is no possibility to get the mgmt(probe response) frame from PE,
4426 converting bss_desc to ieee80211_mgmt(probe response) and passing to
4427 cfg80211_inform_bss_frame.
4428 */
4429 struct net_device *dev = pAdapter->dev;
4430 struct wireless_dev *wdev = dev->ieee80211_ptr;
4431 struct wiphy *wiphy = wdev->wiphy;
4432 int chan_no = bss_desc->channelId;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08004433#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
4434 qcom_ie_age *qie_age = NULL;
4435 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length ) + sizeof(qcom_ie_age);
4436#else
Jeff Johnson295189b2012-06-20 16:38:30 -07004437 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length );
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08004438#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07004439 const char *ie =
4440 ((ie_length != 0) ? (const char *)&bss_desc->ieFields: NULL);
4441 unsigned int freq;
4442 struct ieee80211_channel *chan;
Abhishek Singh1e2bfa32014-01-02 15:44:15 +05304443 struct ieee80211_mgmt *mgmt = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07004444 struct cfg80211_bss *bss_status = NULL;
4445 size_t frame_len = sizeof (struct ieee80211_mgmt) + ie_length;
4446 int rssi = 0;
Wilson Yangf80a0542013-10-07 13:02:37 -07004447 hdd_context_t *pHddCtx;
4448 int status;
Jeff Johnsone7245742012-09-05 17:12:55 -07004449#ifdef WLAN_OPEN_SOURCE
4450 struct timespec ts;
4451#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07004452
Wilson Yangf80a0542013-10-07 13:02:37 -07004453 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
4454 status = wlan_hdd_validate_context(pHddCtx);
4455
4456 /*bss_update is not allowed during wlan driver loading or unloading*/
Mihir Shete18156292014-03-11 15:38:30 +05304457 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Wilson Yangf80a0542013-10-07 13:02:37 -07004458 {
4459 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4460 "%s:Loading_unloading in Progress. Ignore!!!",__func__);
4461 return NULL;
4462 }
4463
4464
4465 if (0 != status)
4466 {
4467 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4468 "%s: HDD context is not valid", __func__);
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -07004469 return NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -07004470 }
4471
Abhishek Singh1e2bfa32014-01-02 15:44:15 +05304472 mgmt = kzalloc((sizeof (struct ieee80211_mgmt) + ie_length), GFP_KERNEL);
Wilson Yangf80a0542013-10-07 13:02:37 -07004473 if (!mgmt)
4474 {
4475 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4476 "%s: memory allocation failed ", __func__);
4477 return NULL;
4478 }
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -07004479
Jeff Johnson295189b2012-06-20 16:38:30 -07004480 memcpy(mgmt->bssid, bss_desc->bssId, ETH_ALEN);
Jeff Johnsone7245742012-09-05 17:12:55 -07004481
4482#ifdef WLAN_OPEN_SOURCE
4483 /* Android does not want the timestamp from the frame.
4484 Instead it wants a monotonic increasing value */
4485 get_monotonic_boottime(&ts);
4486 mgmt->u.probe_resp.timestamp =
4487 ((u64)ts.tv_sec * 1000000) + (ts.tv_nsec / 1000);
4488#else
4489 /* keep old behavior for non-open source (for now) */
Jeff Johnson295189b2012-06-20 16:38:30 -07004490 memcpy(&mgmt->u.probe_resp.timestamp, bss_desc->timeStamp,
4491 sizeof (bss_desc->timeStamp));
Jeff Johnsone7245742012-09-05 17:12:55 -07004492
4493#endif
4494
Jeff Johnson295189b2012-06-20 16:38:30 -07004495 mgmt->u.probe_resp.beacon_int = bss_desc->beaconInterval;
4496 mgmt->u.probe_resp.capab_info = bss_desc->capabilityInfo;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08004497
4498#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
4499 /* GPS Requirement: need age ie per entry. Using vendor specific. */
4500 /* Assuming this is the last IE, copy at the end */
4501 ie_length -=sizeof(qcom_ie_age);
4502 qie_age = (qcom_ie_age *)(mgmt->u.probe_resp.variable + ie_length);
4503 qie_age->element_id = QCOM_VENDOR_IE_ID;
4504 qie_age->len = QCOM_VENDOR_IE_AGE_LEN;
4505 qie_age->oui_1 = QCOM_OUI1;
4506 qie_age->oui_2 = QCOM_OUI2;
4507 qie_age->oui_3 = QCOM_OUI3;
4508 qie_age->type = QCOM_VENDOR_IE_AGE_TYPE;
4509 qie_age->age = vos_timer_get_system_ticks() - bss_desc->nReceivedTime;
4510#endif
4511
Jeff Johnson295189b2012-06-20 16:38:30 -07004512 memcpy(mgmt->u.probe_resp.variable, ie, ie_length);
Gopichand Nakkalad908ec82013-05-16 19:32:19 +05304513 if (bss_desc->fProbeRsp)
4514 {
4515 mgmt->frame_control |=
4516 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_RESP);
4517 }
4518 else
4519 {
4520 mgmt->frame_control |=
4521 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_BEACON);
4522 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004523
4524#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304525 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ) &&
Jeff Johnson295189b2012-06-20 16:38:30 -07004526 (wiphy->bands[IEEE80211_BAND_2GHZ] != NULL))
4527 {
4528 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
4529 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304530 else if ((chan_no > ARRAY_SIZE(hdd_channels_2_4_GHZ)) &&
Jeff Johnson295189b2012-06-20 16:38:30 -07004531 (wiphy->bands[IEEE80211_BAND_5GHZ] != NULL))
4532
4533 {
4534 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
4535 }
4536 else
4537 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05304538 hddLog(VOS_TRACE_LEVEL_ERROR, "%s Invalid chan_no:%d",
4539 __func__, chan_no);
Jeff Johnson295189b2012-06-20 16:38:30 -07004540 kfree(mgmt);
4541 return NULL;
4542 }
4543#else
4544 freq = ieee80211_channel_to_frequency(chan_no);
4545#endif
4546 chan = __ieee80211_get_channel(wiphy, freq);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -08004547 /*when the band is changed on the fly using the GUI, three things are done
4548 * 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)
4549 * as part of the scan abort, message willbe queued to PE and we proceed with flushing and changinh the band.
4550 * pe will stop the scanning further and report back the results what ever it had till now by calling the call back function.
4551 * if the time between update band and scandone call back is sufficent enough the band change reflects in SME, SME validates the channels
4552 * and discards the channels correponding to previous band and calls back with zero bss results.
4553 * 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
4554 * all the channels correponding to previous band.this is due to race condition.but those channels are invalid to the new band and so
4555 * this function __ieee80211_get_channel will return NULL.Each time we report scan result with this pointer null warning kernel trace is printed.
4556 * if the scan results contain large number of APs continuosly kernel warning trace is printed and it will lead to apps watch dog bark.
4557 * So drop the bss and continue to next bss.
4558 */
4559 if(chan == NULL)
4560 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05304561 hddLog(VOS_TRACE_LEVEL_ERROR, "%s chan pointer is NULL", __func__);
Chilam Ngc4244af2013-04-01 15:37:32 -07004562 kfree(mgmt);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -08004563 return NULL;
4564 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004565 /*To keep the rssi icon of the connected AP in the scan window
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304566 *and the rssi icon of the wireless networks in sync
Jeff Johnson295189b2012-06-20 16:38:30 -07004567 * */
4568 if (( eConnectionState_Associated ==
4569 pAdapter->sessionCtx.station.conn_info.connState ) &&
4570 ( VOS_TRUE == vos_mem_compare(bss_desc->bssId,
4571 pAdapter->sessionCtx.station.conn_info.bssId,
4572 WNI_CFG_BSSID_LEN)))
4573 {
4574 /* supplicant takes the signal strength in terms of mBm(100*dBm) */
4575 rssi = (pAdapter->rssi * 100);
4576 }
4577 else
4578 {
4579 rssi = (VOS_MIN ((bss_desc->rssi + bss_desc->sinr), 0))*100;
4580 }
4581
Nirav Shah20ac06f2013-12-12 18:14:06 +05304582 hddLog(VOS_TRACE_LEVEL_INFO, "%s: BSSID:" MAC_ADDRESS_STR " Channel:%d"
4583 "RSSI:%d", __func__, MAC_ADDR_ARRAY(mgmt->bssid),
4584 chan->center_freq, (int)(rssi/100));
4585
Jeff Johnson295189b2012-06-20 16:38:30 -07004586 bss_status = cfg80211_inform_bss_frame(wiphy, chan, mgmt,
4587 frame_len, rssi, GFP_KERNEL);
4588 kfree(mgmt);
4589 return bss_status;
4590}
4591
4592/*
4593 * FUNCTION: wlan_hdd_cfg80211_update_bss_db
4594 * This function is used to update the BSS data base of CFG8011
4595 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304596struct cfg80211_bss* wlan_hdd_cfg80211_update_bss_db( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07004597 tCsrRoamInfo *pRoamInfo
4598 )
4599{
4600 tCsrRoamConnectedProfile roamProfile;
4601 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
4602 struct cfg80211_bss *bss = NULL;
4603
4604 ENTER();
4605
4606 memset(&roamProfile, 0, sizeof(tCsrRoamConnectedProfile));
4607 sme_RoamGetConnectProfile(hHal, pAdapter->sessionId, &roamProfile);
4608
4609 if (NULL != roamProfile.pBssDesc)
4610 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304611 bss = wlan_hdd_cfg80211_inform_bss(pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07004612 &roamProfile);
4613
4614 if (NULL == bss)
4615 {
4616 hddLog(VOS_TRACE_LEVEL_INFO, "%s: cfg80211_inform_bss return NULL",
4617 __func__);
4618 }
4619
4620 sme_RoamFreeConnectProfile(hHal, &roamProfile);
4621 }
4622 else
4623 {
4624 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: roamProfile.pBssDesc is NULL",
4625 __func__);
4626 }
4627 return bss;
4628}
4629
4630/*
4631 * FUNCTION: wlan_hdd_cfg80211_update_bss
4632 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304633static int wlan_hdd_cfg80211_update_bss( struct wiphy *wiphy,
4634 hdd_adapter_t *pAdapter
Jeff Johnson295189b2012-06-20 16:38:30 -07004635 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304636{
Jeff Johnson295189b2012-06-20 16:38:30 -07004637 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
4638 tCsrScanResultInfo *pScanResult;
4639 eHalStatus status = 0;
4640 tScanResultHandle pResult;
4641 struct cfg80211_bss *bss_status = NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -07004642 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07004643
4644 ENTER();
4645
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05304646 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
4647 TRACE_CODE_HDD_CFG80211_UPDATE_BSS,
4648 NO_SESSION, pAdapter->sessionId));
4649
Wilson Yangf80a0542013-10-07 13:02:37 -07004650 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
4651
4652 if (pHddCtx->isLogpInProgress)
Jeff Johnson295189b2012-06-20 16:38:30 -07004653 {
Wilson Yangf80a0542013-10-07 13:02:37 -07004654 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
4655 "%s:LOGP in Progress. Ignore!!!",__func__);
4656 return -EAGAIN;
Jeff Johnson295189b2012-06-20 16:38:30 -07004657 }
4658
Wilson Yangf80a0542013-10-07 13:02:37 -07004659
4660 /*bss_update is not allowed during wlan driver loading or unloading*/
Mihir Shete18156292014-03-11 15:38:30 +05304661 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Wilson Yangf80a0542013-10-07 13:02:37 -07004662 {
4663 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4664 "%s:Loading_unloading in Progress. Ignore!!!",__func__);
4665 return VOS_STATUS_E_PERM;
4666 }
4667
4668
Jeff Johnson295189b2012-06-20 16:38:30 -07004669 /*
4670 * start getting scan results and populate cgf80211 BSS database
4671 */
4672 status = sme_ScanGetResult(hHal, pAdapter->sessionId, NULL, &pResult);
4673
4674 /* no scan results */
4675 if (NULL == pResult)
4676 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05304677 hddLog(VOS_TRACE_LEVEL_INFO, "%s: No scan result Status %d",
4678 __func__, status);
Jeff Johnson295189b2012-06-20 16:38:30 -07004679 return status;
4680 }
4681
4682 pScanResult = sme_ScanResultGetFirst(hHal, pResult);
4683
4684 while (pScanResult)
4685 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304686 /*
4687 * cfg80211_inform_bss() is not updating ie field of bss entry, if
4688 * entry already exists in bss data base of cfg80211 for that
4689 * particular BSS ID. Using cfg80211_inform_bss_frame to update the
4690 * bss entry instead of cfg80211_inform_bss, But this call expects
4691 * mgmt packet as input. As of now there is no possibility to get
4692 * the mgmt(probe response) frame from PE, converting bss_desc to
Jeff Johnson295189b2012-06-20 16:38:30 -07004693 * ieee80211_mgmt(probe response) and passing to c
4694 * fg80211_inform_bss_frame.
4695 * */
4696
4697 bss_status = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
4698 &pScanResult->BssDescriptor);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304699
Jeff Johnson295189b2012-06-20 16:38:30 -07004700
4701 if (NULL == bss_status)
4702 {
4703 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -08004704 "%s: NULL returned by cfg80211_inform_bss", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004705 }
4706 else
4707 {
Yue Maf49ba872013-08-19 12:04:25 -07004708 cfg80211_put_bss(
4709#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0))
4710 wiphy,
4711#endif
4712 bss_status);
Jeff Johnson295189b2012-06-20 16:38:30 -07004713 }
4714
4715 pScanResult = sme_ScanResultGetNext(hHal, pResult);
4716 }
4717
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304718 sme_ScanResultPurge(hHal, pResult);
Jeff Johnson295189b2012-06-20 16:38:30 -07004719
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304720 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07004721}
4722
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004723void
4724hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel)
4725{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304726 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussaina7c8e412013-11-20 11:06:42 -08004727 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(macAddr));
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004728} /****** end hddPrintMacAddr() ******/
4729
4730void
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07004731hddPrintPmkId(tANI_U8 *pmkId, tANI_U8 logLevel)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004732{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304733 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussain6d2a3322013-11-17 19:50:10 -08004734 "%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X",
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07004735 pmkId[0], pmkId[1], pmkId[2], pmkId[3], pmkId[4],
4736 pmkId[5], pmkId[6], pmkId[7], pmkId[8], pmkId[9], pmkId[10],
4737 pmkId[11], pmkId[12], pmkId[13], pmkId[14], pmkId[15]);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004738} /****** end hddPrintPmkId() ******/
4739
4740//hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel);
4741//hddPrintMacAddr(macAddr, VOS_TRACE_LEVEL_FATAL);
4742
4743//void sirDumpBuf(tpAniSirGlobal pMac, tANI_U8 modId, tANI_U32 level, tANI_U8 *buf, tANI_U32 size);
4744//sirDumpBuf(pMac, VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, pmkid, 16);
4745
4746#define dump_bssid(bssid) \
4747 { \
Jeff Johnsone7245742012-09-05 17:12:55 -07004748 hddLog(VOS_TRACE_LEVEL_INFO, "BSSID (MAC) address:\t"); \
4749 hddPrintMacAddr(bssid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004750 }
4751
4752#define dump_pmkid(pMac, pmkid) \
4753 { \
Jeff Johnsone7245742012-09-05 17:12:55 -07004754 hddLog(VOS_TRACE_LEVEL_INFO, "PMKSA-ID:\t"); \
4755 hddPrintPmkId(pmkid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004756 }
4757
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -07004758#if defined(FEATURE_WLAN_LFR) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004759/*
4760 * FUNCTION: wlan_hdd_cfg80211_pmksa_candidate_notify
4761 * This function is used to notify the supplicant of a new PMKSA candidate.
4762 */
4763int wlan_hdd_cfg80211_pmksa_candidate_notify(
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304764 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004765 int index, bool preauth )
4766{
Jeff Johnsone7245742012-09-05 17:12:55 -07004767#ifdef FEATURE_WLAN_OKC
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004768 struct net_device *dev = pAdapter->dev;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004769 hdd_context_t *pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004770
4771 ENTER();
Jeff Johnsone7245742012-09-05 17:12:55 -07004772 hddLog(VOS_TRACE_LEVEL_INFO, "%s is going to notify supplicant of:", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004773
4774 if( NULL == pRoamInfo )
4775 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08004776 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pRoamInfo is NULL", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004777 return -EINVAL;
4778 }
4779
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004780 if (eANI_BOOLEAN_TRUE == hdd_is_okc_mode_enabled(pHddCtx))
4781 {
4782 dump_bssid(pRoamInfo->bssid);
4783 cfg80211_pmksa_candidate_notify(dev, index,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004784 pRoamInfo->bssid, preauth, GFP_KERNEL);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004785 }
Jeff Johnsone7245742012-09-05 17:12:55 -07004786#endif /* FEATURE_WLAN_OKC */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304787 return 0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004788}
4789#endif //FEATURE_WLAN_LFR
4790
Yue Maef608272013-04-08 23:09:17 -07004791#ifdef FEATURE_WLAN_LFR_METRICS
4792/*
4793 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth
4794 * 802.11r/LFR metrics reporting function to report preauth initiation
4795 *
4796 */
4797#define MAX_LFR_METRICS_EVENT_LENGTH 100
4798VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth(hdd_adapter_t *pAdapter,
4799 tCsrRoamInfo *pRoamInfo)
4800{
4801 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
4802 union iwreq_data wrqu;
4803
4804 ENTER();
4805
4806 if (NULL == pAdapter)
4807 {
4808 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
4809 return VOS_STATUS_E_FAILURE;
4810 }
4811
4812 /* create the event */
4813 memset(&wrqu, 0, sizeof(wrqu));
4814 memset(metrics_notification, 0, sizeof(metrics_notification));
4815
4816 wrqu.data.pointer = metrics_notification;
4817 wrqu.data.length = scnprintf(metrics_notification,
4818 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_INIT "
4819 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
4820
4821 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
4822
4823 EXIT();
4824
4825 return VOS_STATUS_SUCCESS;
4826}
4827
4828/*
4829 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth_status
4830 * 802.11r/LFR metrics reporting function to report preauth completion
4831 * or failure
4832 */
4833VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth_status(
4834 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo, bool preauth_status)
4835{
4836 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
4837 union iwreq_data wrqu;
4838
4839 ENTER();
4840
4841 if (NULL == pAdapter)
4842 {
4843 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
4844 return VOS_STATUS_E_FAILURE;
4845 }
4846
4847 /* create the event */
4848 memset(&wrqu, 0, sizeof(wrqu));
4849 memset(metrics_notification, 0, sizeof(metrics_notification));
4850
4851 scnprintf(metrics_notification, sizeof(metrics_notification),
4852 "QCOM: LFR_PREAUTH_STATUS "MAC_ADDRESS_STR,
4853 MAC_ADDR_ARRAY(pRoamInfo->bssid));
4854
4855 if (1 == preauth_status)
4856 strncat(metrics_notification, " TRUE", 5);
4857 else
4858 strncat(metrics_notification, " FALSE", 6);
4859
4860 wrqu.data.pointer = metrics_notification;
4861 wrqu.data.length = strlen(metrics_notification);
4862
4863 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
4864
4865 EXIT();
4866
4867 return VOS_STATUS_SUCCESS;
4868}
4869
4870/*
4871 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_handover
4872 * 802.11r/LFR metrics reporting function to report handover initiation
4873 *
4874 */
4875VOS_STATUS wlan_hdd_cfg80211_roam_metrics_handover(hdd_adapter_t * pAdapter,
4876 tCsrRoamInfo *pRoamInfo)
4877{
4878 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
4879 union iwreq_data wrqu;
4880
4881 ENTER();
4882
4883 if (NULL == pAdapter)
4884 {
4885 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
4886 return VOS_STATUS_E_FAILURE;
4887 }
4888
4889 /* create the event */
4890 memset(&wrqu, 0, sizeof(wrqu));
4891 memset(metrics_notification, 0, sizeof(metrics_notification));
4892
4893 wrqu.data.pointer = metrics_notification;
4894 wrqu.data.length = scnprintf(metrics_notification,
4895 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_HANDOVER "
4896 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
4897
4898 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
4899
4900 EXIT();
4901
4902 return VOS_STATUS_SUCCESS;
4903}
4904#endif
4905
Jeff Johnson295189b2012-06-20 16:38:30 -07004906/*
4907 * FUNCTION: hdd_cfg80211_scan_done_callback
4908 * scanning callback function, called after finishing scan
4909 *
4910 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304911static eHalStatus hdd_cfg80211_scan_done_callback(tHalHandle halHandle,
Jeff Johnson295189b2012-06-20 16:38:30 -07004912 void *pContext, tANI_U32 scanId, eCsrScanStatus status)
4913{
4914 struct net_device *dev = (struct net_device *) pContext;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304915 //struct wireless_dev *wdev = dev->ieee80211_ptr;
Jeff Johnson295189b2012-06-20 16:38:30 -07004916 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07004917 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
4918 hdd_scaninfo_t *pScanInfo = &pHddCtx->scan_info;
Jeff Johnson295189b2012-06-20 16:38:30 -07004919 struct cfg80211_scan_request *req = NULL;
4920 int ret = 0;
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +05304921 bool aborted = false;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05304922 long waitRet = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07004923
4924 ENTER();
4925
4926 hddLog(VOS_TRACE_LEVEL_INFO,
4927 "%s called with halHandle = %p, pContext = %p,"
Arif Hussain6d2a3322013-11-17 19:50:10 -08004928 "scanID = %d, returned status = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07004929 __func__, halHandle, pContext, (int) scanId, (int) status);
4930
Kiet Lamac06e2c2013-10-23 16:25:07 +05304931 pScanInfo->mScanPendingCounter = 0;
4932
Jeff Johnson295189b2012-06-20 16:38:30 -07004933 //Block on scan req completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +05304934 waitRet = wait_for_completion_interruptible_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07004935 &pScanInfo->scan_req_completion_event,
4936 msecs_to_jiffies(WLAN_WAIT_TIME_SCAN_REQ));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05304937 if (waitRet <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -07004938 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05304939 hddLog(VOS_TRACE_LEVEL_ERROR,
4940 "%s wait on scan_req_completion_event failed %ld",__func__, waitRet);
Jeff Johnson295189b2012-06-20 16:38:30 -07004941 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -07004942 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -07004943 }
4944
Yue Maef608272013-04-08 23:09:17 -07004945 if (pScanInfo->mScanPending != VOS_TRUE)
Jeff Johnson295189b2012-06-20 16:38:30 -07004946 {
4947 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -07004948 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -07004949 }
4950
4951 /* Check the scanId */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304952 if (pScanInfo->scanId != scanId)
Jeff Johnson295189b2012-06-20 16:38:30 -07004953 {
4954 hddLog(VOS_TRACE_LEVEL_INFO,
4955 "%s called with mismatched scanId pScanInfo->scanId = %d "
Arif Hussain6d2a3322013-11-17 19:50:10 -08004956 "scanId = %d", __func__, (int) pScanInfo->scanId,
Jeff Johnson295189b2012-06-20 16:38:30 -07004957 (int) scanId);
4958 }
4959
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304960 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07004961 pAdapter);
4962
4963 if (0 > ret)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304964 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004965
4966
4967 /* If any client wait scan result through WEXT
4968 * send scan done event to client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07004969 if (pHddCtx->scan_info.waitScanResult)
Jeff Johnson295189b2012-06-20 16:38:30 -07004970 {
4971 /* The other scan request waiting for current scan finish
4972 * Send event to notify current scan finished */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07004973 if(WEXT_SCAN_PENDING_DELAY == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -07004974 {
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07004975 vos_event_set(&pHddCtx->scan_info.scan_finished_event);
Jeff Johnson295189b2012-06-20 16:38:30 -07004976 }
4977 /* Send notify to WEXT client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07004978 else if(WEXT_SCAN_PENDING_PIGGYBACK == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -07004979 {
4980 struct net_device *dev = pAdapter->dev;
4981 union iwreq_data wrqu;
4982 int we_event;
4983 char *msg;
4984
4985 memset(&wrqu, '\0', sizeof(wrqu));
4986 we_event = SIOCGIWSCAN;
4987 msg = NULL;
4988 wireless_send_event(dev, we_event, &wrqu, msg);
4989 }
4990 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07004991 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07004992
4993 /* Get the Scan Req */
4994 req = pAdapter->request;
4995
4996 if (!req)
4997 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08004998 hddLog(VOS_TRACE_LEVEL_ERROR, "request is became NULL");
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07004999 pScanInfo->mScanPending = VOS_FALSE;
Jeff Johnsone7245742012-09-05 17:12:55 -07005000 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -07005001 }
5002
5003 /*
5004 * setting up 0, just in case.
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305005 */
Jeff Johnson295189b2012-06-20 16:38:30 -07005006 req->n_ssids = 0;
5007 req->n_channels = 0;
5008 req->ie = 0;
5009
Jeff Johnson295189b2012-06-20 16:38:30 -07005010 pAdapter->request = NULL;
Jeff Johnsone7245742012-09-05 17:12:55 -07005011 /* Scan is no longer pending */
5012 pScanInfo->mScanPending = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07005013
Madan Mohan Koyyalamudib764bf82012-10-11 16:38:51 -07005014 /*
5015 * cfg80211_scan_done informing NL80211 about completion
5016 * of scanning
5017 */
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +05305018 if (status == eCSR_SCAN_ABORT || status == eCSR_SCAN_FAILURE)
5019 {
5020 aborted = true;
5021 }
5022 cfg80211_scan_done(req, aborted);
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -08005023 complete(&pScanInfo->abortscan_event_var);
Jeff Johnson295189b2012-06-20 16:38:30 -07005024
Jeff Johnsone7245742012-09-05 17:12:55 -07005025allow_suspend:
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07005026 /* release the wake lock at the end of the scan*/
5027 hdd_allow_suspend();
Jeff Johnsone7245742012-09-05 17:12:55 -07005028
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -07005029 /* Acquire wakelock to handle the case where APP's tries to suspend
5030 * immediatly after the driver gets connect request(i.e after scan)
5031 * from supplicant, this result in app's is suspending and not able
5032 * to process the connect request to AP */
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +05305033 hdd_prevent_suspend_timeout(1000);
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -07005034
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07005035#ifdef FEATURE_WLAN_TDLS
5036 wlan_hdd_tdls_scan_done_callback(pAdapter);
5037#endif
5038
Jeff Johnson295189b2012-06-20 16:38:30 -07005039 EXIT();
5040 return 0;
5041}
5042
5043/*
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08005044 * FUNCTION: hdd_isScanAllowed
5045 * Go through each adapter and check if scan allowed
5046 *
5047 */
5048v_BOOL_t hdd_isScanAllowed( hdd_context_t *pHddCtx )
5049{
5050 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
5051 hdd_station_ctx_t *pHddStaCtx = NULL;
5052 hdd_adapter_t *pAdapter = NULL;
5053 VOS_STATUS status = 0;
5054 v_U8_t staId = 0;
5055 v_U8_t *staMac = NULL;
5056
c_hpothu9b781ba2013-12-30 20:57:45 +05305057 if (TRUE == pHddCtx->btCoexModeSet)
5058 {
5059 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5060 FL("BTCoex Mode operation in progress, Do not allow scan"));
5061 return VOS_FALSE;
5062 }
5063
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08005064 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
5065
5066 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
5067 {
5068 pAdapter = pAdapterNode->pAdapter;
5069
5070 if( pAdapter )
5071 {
5072 hddLog(VOS_TRACE_LEVEL_INFO,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305073 "%s: Adapter with device mode %d exists",
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08005074 __func__, pAdapter->device_mode);
5075 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
5076 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
5077 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
5078 {
5079 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
5080 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
5081 (VOS_FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
5082 {
5083 staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]);
5084 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain24bafea2013-11-15 15:10:03 -08005085 "%s: client " MAC_ADDRESS_STR
5086 " is in the middle of WPS/EAPOL exchange.", __func__,
5087 MAC_ADDR_ARRAY(staMac));
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08005088 return VOS_FALSE;
5089 }
5090 }
5091 else if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) ||
5092 (WLAN_HDD_P2P_GO == pAdapter->device_mode))
5093 {
5094 for (staId = 0; staId < WLAN_MAX_STA_COUNT; staId++)
5095 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305096 if ((pAdapter->aStaInfo[staId].isUsed) &&
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08005097 (WLANTL_STA_CONNECTED == pAdapter->aStaInfo[staId].tlSTAState))
5098 {
5099 staMac = (v_U8_t *) &(pAdapter->aStaInfo[staId].macAddrSTA.bytes[0]);
5100
5101 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain24bafea2013-11-15 15:10:03 -08005102 "%s: client " MAC_ADDRESS_STR " of SoftAP/P2P-GO is in the "
5103 "middle of WPS/EAPOL exchange.", __func__,
5104 MAC_ADDR_ARRAY(staMac));
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08005105 return VOS_FALSE;
5106 }
5107 }
5108 }
5109 }
5110 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
5111 pAdapterNode = pNext;
5112 }
5113 hddLog(VOS_TRACE_LEVEL_INFO,
5114 "%s: Scan allowed", __func__);
5115 return VOS_TRUE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305116}
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08005117
5118/*
Jeff Johnson295189b2012-06-20 16:38:30 -07005119 * FUNCTION: wlan_hdd_cfg80211_scan
5120 * this scan respond to scan trigger and update cfg80211 scan database
5121 * later, scan dump command can be used to recieve scan results
5122 */
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -08005123int wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
5124#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
5125 struct net_device *dev,
5126#endif
5127 struct cfg80211_scan_request *request)
5128{
5129#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
5130 struct net_device *dev = request->wdev->netdev;
5131#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305132 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Jeff Johnson295189b2012-06-20 16:38:30 -07005133 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
5134 hdd_wext_state_t *pwextBuf = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305135 hdd_config_t *cfg_param = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07005136 tCsrScanRequest scanRequest;
5137 tANI_U8 *channelList = NULL, i;
5138 v_U32_t scanId = 0;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305139 int status;
5140 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07005141 v_U8_t* pP2pIe = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07005142
5143 ENTER();
5144
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05305145 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
5146 TRACE_CODE_HDD_CFG80211_SCAN,
5147 pAdapter->sessionId, request->n_channels));
5148
Arif Hussain6d2a3322013-11-17 19:50:10 -08005149 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07005150 __func__,pAdapter->device_mode);
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08005151
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305152 status = wlan_hdd_validate_context(pHddCtx);
5153
5154 if (0 != status)
5155 {
5156 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5157 "%s: HDD context is not valid", __func__);
5158 return status;
5159 }
5160
5161 cfg_param = pHddCtx->cfg_ini;
5162 pScanInfo = &pHddCtx->scan_info;
5163
Gopichand Nakkala681989c2013-03-06 22:27:48 -08005164 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08005165 (eConnectionState_Connecting ==
Gopichand Nakkala681989c2013-03-06 22:27:48 -08005166 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08005167 {
5168 hddLog(VOS_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08005169 "%s: %p(%d) Connection in progress: Scan request denied (EBUSY)", __func__, \
5170 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08005171 return -EBUSY;
5172 }
5173
Jeff Johnson295189b2012-06-20 16:38:30 -07005174#ifdef WLAN_BTAMP_FEATURE
5175 //Scan not supported when AMP traffic is on.
Gopichand Nakkala681989c2013-03-06 22:27:48 -08005176 if (VOS_TRUE == WLANBAP_AmpSessionOn())
Jeff Johnson295189b2012-06-20 16:38:30 -07005177 {
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08005178 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07005179 "%s: No scanning when AMP is on", __func__);
5180 return -EOPNOTSUPP;
5181 }
5182#endif
5183 //Scan on any other interface is not supported.
Gopichand Nakkala681989c2013-03-06 22:27:48 -08005184 if (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07005185 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -08005186 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07005187 "%s: Not scanning on device_mode = %d",
5188 __func__, pAdapter->device_mode);
5189 return -EOPNOTSUPP;
5190 }
5191
5192 if (TRUE == pScanInfo->mScanPending)
5193 {
Kiet Lamac06e2c2013-10-23 16:25:07 +05305194 if ( MAX_PENDING_LOG > pScanInfo->mScanPendingCounter++ )
5195 {
5196 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: mScanPending is TRUE", __func__);
5197 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08005198 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -07005199 }
5200
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305201 //Don't Allow Scan and return busy if Remain On
Jeff Johnson32d95a32012-09-10 13:15:23 -07005202 //Channel and action frame is pending
5203 //Otherwise Cancel Remain On Channel and allow Scan
5204 //If no action frame pending
Gopichand Nakkala681989c2013-03-06 22:27:48 -08005205 if (0 != wlan_hdd_check_remain_on_channel(pAdapter))
Jeff Johnson32d95a32012-09-10 13:15:23 -07005206 {
Kiet Lamac06e2c2013-10-23 16:25:07 +05305207 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Remain On Channel Pending", __func__);
Jeff Johnson32d95a32012-09-10 13:15:23 -07005208 return -EBUSY;
5209 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08005210#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07005211 /* if tdls disagree scan right now, return immediately.
5212 tdls will schedule the scan when scan is allowed. (return SUCCESS)
5213 or will reject the scan if any TDLS is in progress. (return -EBUSY)
5214 */
5215 status = wlan_hdd_tdls_scan_callback (pAdapter,
5216 wiphy,
5217#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
5218 dev,
Gopichand Nakkalac3c42b92013-03-20 19:42:34 -07005219#endif
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07005220 request);
5221 if(status <= 0)
5222 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05305223 if(!status)
5224 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS in progress."
5225 "scan rejected %d", __func__, status);
5226 else
5227 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS teardown is ongoing %d",
5228 __func__, status);
5229
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07005230 return status;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08005231 }
5232#endif
Jeff Johnson32d95a32012-09-10 13:15:23 -07005233
Jeff Johnson295189b2012-06-20 16:38:30 -07005234 if (mutex_lock_interruptible(&pHddCtx->tmInfo.tmOperationLock))
5235 {
5236 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_ERROR,
Jeff Johnson1250df42012-12-10 14:31:52 -08005237 "%s: Acquire lock fail", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005238 return -EAGAIN;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305239 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005240 if (TRUE == pHddCtx->tmInfo.tmAction.enterImps)
5241 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05305242 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07005243 "%s: MAX TM Level Scan not allowed", __func__);
5244 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305245 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -07005246 }
5247 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
5248
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08005249 /* Check if scan is allowed at this point of time.
5250 */
5251 if (!hdd_isScanAllowed(pHddCtx))
5252 {
5253 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Scan not allowed", __func__);
5254 return -EBUSY;
5255 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305256
Jeff Johnson295189b2012-06-20 16:38:30 -07005257 vos_mem_zero( &scanRequest, sizeof(scanRequest));
5258
5259 if (NULL != request)
5260 {
5261 hddLog(VOS_TRACE_LEVEL_INFO, "scan request for ssid = %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305262 (int)request->n_ssids);
Jeff Johnson295189b2012-06-20 16:38:30 -07005263
5264 /* Even though supplicant doesn't provide any SSIDs, n_ssids is set to 1.
5265 * Becasue of this, driver is assuming that this is not wildcard scan and so
5266 * is not aging out the scan results.
5267 */
Jeff Johnson32d95a32012-09-10 13:15:23 -07005268 if (request->ssids && '\0' == request->ssids->ssid[0])
Jeff Johnson295189b2012-06-20 16:38:30 -07005269 {
5270 request->n_ssids = 0;
5271 }
5272
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07005273 if ((request->ssids) && (0 < request->n_ssids))
Jeff Johnson295189b2012-06-20 16:38:30 -07005274 {
5275 tCsrSSIDInfo *SsidInfo;
5276 int j;
5277 scanRequest.SSIDs.numOfSSIDs = request->n_ssids;
5278 /* Allocate num_ssid tCsrSSIDInfo structure */
5279 SsidInfo = scanRequest.SSIDs.SSIDList =
5280 ( tCsrSSIDInfo *)vos_mem_malloc(
5281 request->n_ssids*sizeof(tCsrSSIDInfo));
5282
5283 if(NULL == scanRequest.SSIDs.SSIDList)
5284 {
5285 hddLog(VOS_TRACE_LEVEL_ERROR,
Nirav Shah20ac06f2013-12-12 18:14:06 +05305286 "%s: memory alloc failed SSIDInfo buffer", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005287 return -ENOMEM;
5288 }
5289
5290 /* copy all the ssid's and their length */
5291 for(j = 0; j < request->n_ssids; j++, SsidInfo++)
5292 {
5293 /* get the ssid length */
5294 SsidInfo->SSID.length = request->ssids[j].ssid_len;
5295 vos_mem_copy(SsidInfo->SSID.ssId, &request->ssids[j].ssid[0],
5296 SsidInfo->SSID.length);
5297 SsidInfo->SSID.ssId[SsidInfo->SSID.length] = '\0';
Nirav Shah20ac06f2013-12-12 18:14:06 +05305298 hddLog(VOS_TRACE_LEVEL_INFO, "SSID number %d: %s",
Jeff Johnson295189b2012-06-20 16:38:30 -07005299 j, SsidInfo->SSID.ssId);
5300 }
5301 /* set the scan type to active */
5302 scanRequest.scanType = eSIR_ACTIVE_SCAN;
5303 }
5304 else if(WLAN_HDD_P2P_GO == pAdapter->device_mode)
5305 {
5306 /* set the scan type to active */
5307 scanRequest.scanType = eSIR_ACTIVE_SCAN;
5308 }
5309 else
5310 {
5311 /*Set the scan type to default type, in this case it is ACTIVE*/
5312 scanRequest.scanType = pScanInfo->scan_mode;
5313 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305314 scanRequest.minChnTime = cfg_param->nActiveMinChnTime;
Jeff Johnson295189b2012-06-20 16:38:30 -07005315 scanRequest.maxChnTime = cfg_param->nActiveMaxChnTime;
5316 }
5317 else
5318 {
5319 /* set the scan type to active */
5320 scanRequest.scanType = eSIR_ACTIVE_SCAN;
5321 vos_mem_set( scanRequest.bssid, sizeof( tCsrBssid ), 0xff );
5322
5323 /* set min and max channel time to zero */
5324 scanRequest.minChnTime = 0;
5325 scanRequest.maxChnTime = 0;
5326 }
5327
5328 /* set BSSType to default type */
5329 scanRequest.BSSType = eCSR_BSS_TYPE_ANY;
5330
5331 /*TODO: scan the requested channels only*/
5332
5333 /*Right now scanning all the channels */
5334 if( request )
5335 {
c_hpothu53512302014-04-15 18:49:53 +05305336 if (MAX_CHANNEL < request->n_channels)
5337 {
5338 hddLog(VOS_TRACE_LEVEL_WARN,
5339 "No of Scan Channels exceeded limit: %d", request->n_channels);
5340 request->n_channels = MAX_CHANNEL;
5341 }
Nirav Shah20ac06f2013-12-12 18:14:06 +05305342 hddLog(VOS_TRACE_LEVEL_INFO,
5343 "No of Scan Channels: %d", request->n_channels);
c_hpothu53512302014-04-15 18:49:53 +05305344
Jeff Johnson295189b2012-06-20 16:38:30 -07005345 if( request->n_channels )
5346 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05305347 char chList [(request->n_channels*5)+1];
5348 int len;
Jeff Johnson295189b2012-06-20 16:38:30 -07005349 channelList = vos_mem_malloc( request->n_channels );
5350 if( NULL == channelList )
5351 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305352 hddLog(VOS_TRACE_LEVEL_ERROR,
Nirav Shah20ac06f2013-12-12 18:14:06 +05305353 "%s: memory alloc failed channelList", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005354 status = -ENOMEM;
5355 goto free_mem;
5356 }
5357
Nirav Shah20ac06f2013-12-12 18:14:06 +05305358 for( i = 0, len = 0; i < request->n_channels ; i++ )
5359 {
Jeff Johnson295189b2012-06-20 16:38:30 -07005360 channelList[i] = request->channels[i]->hw_value;
Nirav Shah20ac06f2013-12-12 18:14:06 +05305361 len += snprintf(chList+len, 5, "%d ", channelList[i]);
5362 }
5363
5364 hddLog(VOS_TRACE_LEVEL_INFO,
5365 "Channel-List: %s ", chList);
Jeff Johnson295189b2012-06-20 16:38:30 -07005366 }
5367
5368 scanRequest.ChannelInfo.numOfChannels = request->n_channels;
5369 scanRequest.ChannelInfo.ChannelList = channelList;
5370
5371 /* set requestType to full scan */
5372 scanRequest.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305373
5374 /* Flush the scan results(only p2p beacons) for STA scan and P2P
Madan Mohan Koyyalamudi8d50f312012-11-27 15:48:57 -08005375 * search (Flush on both full scan and social scan but not on single
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305376 * channel scan).P2P search happens on 3 social channels (1, 6, 11)
Madan Mohan Koyyalamudi8d50f312012-11-27 15:48:57 -08005377 */
5378
5379 /* Supplicant does single channel scan after 8-way handshake
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305380 * and in that case driver shoudnt flush scan results. If
5381 * driver flushes the scan results here and unfortunately if
5382 * the AP doesnt respond to our probe req then association
Madan Mohan Koyyalamudi8d50f312012-11-27 15:48:57 -08005383 * fails which is not desired
5384 */
5385
5386 if( request->n_channels != WLAN_HDD_P2P_SINGLE_CHANNEL_SCAN )
5387 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05305388 hddLog(VOS_TRACE_LEVEL_DEBUG, "Flushing P2P Results");
Madan Mohan Koyyalamudi8d50f312012-11-27 15:48:57 -08005389 sme_ScanFlushP2PResult( WLAN_HDD_GET_HAL_CTX(pAdapter),
5390 pAdapter->sessionId );
5391 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005392
5393 if( request->ie_len )
5394 {
5395 /* save this for future association (join requires this) */
Agarwal Ashish4f616132013-12-30 23:32:50 +05305396 /*TODO: Array needs to be converted to dynamic allocation,
5397 * as multiple ie.s can be sent in cfg80211_scan_request structure
5398 * CR 597966
5399 */
Jeff Johnson295189b2012-06-20 16:38:30 -07005400 memset( &pScanInfo->scanAddIE, 0, sizeof(pScanInfo->scanAddIE) );
5401 memcpy( pScanInfo->scanAddIE.addIEdata, request->ie, request->ie_len);
5402 pScanInfo->scanAddIE.length = request->ie_len;
5403
Agarwal Ashish4f616132013-12-30 23:32:50 +05305404 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Jeff Johnsone7245742012-09-05 17:12:55 -07005405 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
Agarwal Ashish4f616132013-12-30 23:32:50 +05305406 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -07005407 {
Agarwal Ashish4f616132013-12-30 23:32:50 +05305408 if ( request->ie_len <= SIR_MAC_MAX_IE_LENGTH)
5409 {
5410 pwextBuf->roamProfile.nAddIEScanLength = request->ie_len;
5411 memcpy( pwextBuf->roamProfile.addIEScan,
5412 request->ie, request->ie_len);
5413 }
5414 else
5415 {
5416 hddLog(VOS_TRACE_LEVEL_ERROR, "Scan Ie length is invalid:"
Arun Kumar Khandavalli75eeb122014-03-27 21:43:12 +05305417 "%zu", request->ie_len);
Agarwal Ashish4f616132013-12-30 23:32:50 +05305418 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005419
Agarwal Ashish4f616132013-12-30 23:32:50 +05305420 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005421 scanRequest.uIEFieldLen = pScanInfo->scanAddIE.length;
5422 scanRequest.pIEField = pScanInfo->scanAddIE.addIEdata;
5423
Jeff Johnson295189b2012-06-20 16:38:30 -07005424 pP2pIe = wlan_hdd_get_p2p_ie_ptr((v_U8_t*)request->ie,
5425 request->ie_len);
5426 if (pP2pIe != NULL)
5427 {
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07005428#ifdef WLAN_FEATURE_P2P_DEBUG
5429 if (((globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED) ||
5430 (globalP2PConnectionStatus == P2P_GO_NEG_PROCESS)) &&
5431 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
5432 {
5433 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_1;
5434 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
5435 "Go nego completed to Connection is started");
5436 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
5437 "for 8way Handshake");
5438 }
5439 else if((globalP2PConnectionStatus == P2P_CLIENT_DISCONNECTED_STATE) &&
5440 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
5441 {
5442 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_2;
5443 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
5444 "Disconnected state to Connection is started");
5445 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
5446 "for 4way Handshake");
5447 }
5448#endif
5449
Jeff Johnsone7245742012-09-05 17:12:55 -07005450 /* no_cck will be set during p2p find to disable 11b rates */
5451 if(TRUE == request->no_cck)
Jeff Johnson295189b2012-06-20 16:38:30 -07005452 {
Jeff Johnson295189b2012-06-20 16:38:30 -07005453 hddLog(VOS_TRACE_LEVEL_INFO,
5454 "%s: This is a P2P Search", __func__);
5455 scanRequest.p2pSearch = 1;
Jeff Johnsone7245742012-09-05 17:12:55 -07005456
Jeff Johnsone7245742012-09-05 17:12:55 -07005457 if( request->n_channels == WLAN_HDD_P2P_SOCIAL_CHANNELS )
5458 {
Madan Mohan Koyyalamudi1b1d9e82012-10-21 11:38:33 -07005459 /* set requestType to P2P Discovery */
5460 scanRequest.requestType = eCSR_SCAN_P2P_DISCOVERY;
Jeff Johnsone7245742012-09-05 17:12:55 -07005461 }
5462
5463 /*
5464 Skip Dfs Channel in case of P2P Search
5465 if it is set in ini file
5466 */
5467 if(cfg_param->skipDfsChnlInP2pSearch)
5468 {
5469 scanRequest.skipDfsChnlInP2pSearch = 1;
5470 }
5471 else
5472 {
5473 scanRequest.skipDfsChnlInP2pSearch = 0;
5474 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005475
Jeff Johnson295189b2012-06-20 16:38:30 -07005476 }
5477 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005478 }
5479 }
5480
5481 INIT_COMPLETION(pScanInfo->scan_req_completion_event);
5482
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07005483 /* acquire the wakelock to avoid the apps suspend during the scan. To
5484 * address the following issues.
5485 * 1) Disconnected scenario: we are not allowing the suspend as WLAN is not in
5486 * BMPS/IMPS this result in android trying to suspend aggressively and backing off
5487 * for long time, this result in apps running at full power for long time.
5488 * 2) Connected scenario: If we allow the suspend during the scan, RIVA will
5489 * be stuck in full power because of resume BMPS
5490 */
5491 hdd_prevent_suspend();
Jeff Johnsone7245742012-09-05 17:12:55 -07005492
Nirav Shah20ac06f2013-12-12 18:14:06 +05305493 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
5494 "requestType %d, scanType %d, minChnTime %d, maxChnTime %d,"
5495 "p2pSearch %d, skipDfsChnlInP2pSearch %d", scanRequest.requestType,
5496 scanRequest.scanType, scanRequest.minChnTime, scanRequest.maxChnTime,
5497 scanRequest.p2pSearch, scanRequest.skipDfsChnlInP2pSearch);
5498
Jeff Johnsone7245742012-09-05 17:12:55 -07005499 status = sme_ScanRequest( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07005500 pAdapter->sessionId, &scanRequest, &scanId,
5501 &hdd_cfg80211_scan_done_callback, dev );
Jeff Johnsone7245742012-09-05 17:12:55 -07005502
Jeff Johnson295189b2012-06-20 16:38:30 -07005503 if (eHAL_STATUS_SUCCESS != status)
5504 {
5505 hddLog(VOS_TRACE_LEVEL_ERROR,
5506 "%s: sme_ScanRequest returned error %d", __func__, status);
5507 complete(&pScanInfo->scan_req_completion_event);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -07005508 if(eHAL_STATUS_RESOURCES == status)
5509 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05305510 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: HO is in progress."
5511 "So defer the scan by informing busy",__func__);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -07005512 status = -EBUSY;
5513 } else {
5514 status = -EIO;
5515 }
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07005516 hdd_allow_suspend();
Jeff Johnson295189b2012-06-20 16:38:30 -07005517 goto free_mem;
5518 }
5519
5520 pScanInfo->mScanPending = TRUE;
5521 pAdapter->request = request;
5522 pScanInfo->scanId = scanId;
5523
5524 complete(&pScanInfo->scan_req_completion_event);
5525
5526free_mem:
5527 if( scanRequest.SSIDs.SSIDList )
5528 {
5529 vos_mem_free(scanRequest.SSIDs.SSIDList);
5530 }
5531
5532 if( channelList )
5533 vos_mem_free( channelList );
5534
5535 EXIT();
5536
5537 return status;
5538}
5539
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07005540
5541void hdd_select_cbmode( hdd_adapter_t *pAdapter,v_U8_t operationChannel)
5542{
5543 v_U8_t iniDot11Mode =
5544 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->dot11Mode;
5545 eHddDot11Mode hddDot11Mode = iniDot11Mode;
5546
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +05305547 hddLog(LOG1, FL("Channel Bonding Mode Selected is %u"),
5548 iniDot11Mode);
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07005549 switch ( iniDot11Mode )
5550 {
5551 case eHDD_DOT11_MODE_AUTO:
5552 case eHDD_DOT11_MODE_11ac:
5553 case eHDD_DOT11_MODE_11ac_ONLY:
5554#ifdef WLAN_FEATURE_11AC
5555 hddDot11Mode = eHDD_DOT11_MODE_11ac;
5556#else
5557 hddDot11Mode = eHDD_DOT11_MODE_11n;
5558#endif
5559 break;
5560 case eHDD_DOT11_MODE_11n:
5561 case eHDD_DOT11_MODE_11n_ONLY:
5562 hddDot11Mode = eHDD_DOT11_MODE_11n;
5563 break;
5564 default:
5565 hddDot11Mode = iniDot11Mode;
5566 break;
5567 }
5568 /* This call decides required channel bonding mode */
5569 sme_SelectCBMode((WLAN_HDD_GET_CTX(pAdapter)->hHal),
5570 hdd_cfg_xlate_to_csr_phy_mode(hddDot11Mode),
5571 operationChannel);
5572}
5573
Jeff Johnson295189b2012-06-20 16:38:30 -07005574/*
5575 * FUNCTION: wlan_hdd_cfg80211_connect_start
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305576 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -07005577 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305578int wlan_hdd_cfg80211_connect_start( hdd_adapter_t *pAdapter,
Jeff Johnson32d95a32012-09-10 13:15:23 -07005579 const u8 *ssid, size_t ssid_len, const u8 *bssid, u8 operatingChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -07005580{
5581 int status = 0;
5582 hdd_wext_state_t *pWextState;
Yue Mae36e3552014-03-05 17:06:20 -08005583 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07005584 v_U32_t roamId;
5585 tCsrRoamProfile *pRoamProfile;
Jeff Johnson295189b2012-06-20 16:38:30 -07005586 eCsrAuthType RSNAuthType;
5587
5588 ENTER();
5589
5590 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Yue Mae36e3552014-03-05 17:06:20 -08005591 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
5592
5593 status = wlan_hdd_validate_context(pHddCtx);
5594 if (status)
5595 {
5596 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5597 "%s: HDD context is not valid!", __func__);
5598 return status;
5599 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305600
Jeff Johnson295189b2012-06-20 16:38:30 -07005601 if (SIR_MAC_MAX_SSID_LENGTH < ssid_len)
5602 {
5603 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wrong SSID len", __func__);
5604 return -EINVAL;
5605 }
5606
5607 pRoamProfile = &pWextState->roamProfile;
5608
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305609 if (pRoamProfile)
Jeff Johnson295189b2012-06-20 16:38:30 -07005610 {
Jeff Johnsone7245742012-09-05 17:12:55 -07005611 hdd_station_ctx_t *pHddStaCtx;
5612 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07005613
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305614 if (HDD_WMM_USER_MODE_NO_QOS ==
Jeff Johnson295189b2012-06-20 16:38:30 -07005615 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->WmmMode)
5616 {
5617 /*QoS not enabled in cfg file*/
5618 pRoamProfile->uapsd_mask = 0;
5619 }
5620 else
5621 {
5622 /*QoS enabled, update uapsd mask from cfg file*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305623 pRoamProfile->uapsd_mask =
Jeff Johnson295189b2012-06-20 16:38:30 -07005624 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask;
5625 }
5626
5627 pRoamProfile->SSIDs.numOfSSIDs = 1;
5628 pRoamProfile->SSIDs.SSIDList->SSID.length = ssid_len;
5629 vos_mem_zero(pRoamProfile->SSIDs.SSIDList->SSID.ssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305630 sizeof(pRoamProfile->SSIDs.SSIDList->SSID.ssId));
Jeff Johnson295189b2012-06-20 16:38:30 -07005631 vos_mem_copy((void *)(pRoamProfile->SSIDs.SSIDList->SSID.ssId),
5632 ssid, ssid_len);
5633
5634 if (bssid)
5635 {
5636 pRoamProfile->BSSIDs.numOfBSSIDs = 1;
5637 vos_mem_copy((void *)(pRoamProfile->BSSIDs.bssid), bssid,
5638 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305639 /* Save BSSID in seperate variable as well, as RoamProfile
5640 BSSID is getting zeroed out in the association process. And in
Jeff Johnson295189b2012-06-20 16:38:30 -07005641 case of join failure we should send valid BSSID to supplicant
5642 */
5643 vos_mem_copy((void *)(pWextState->req_bssId), bssid,
5644 WNI_CFG_BSSID_LEN);
5645 }
Dhanashri Atre51981c62013-06-13 11:47:57 -07005646 else
5647 {
5648 vos_mem_zero((void *)(pRoamProfile->BSSIDs.bssid),WNI_CFG_BSSID_LEN);
5649 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005650
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +05305651 hddLog(LOG1, FL("Connect to SSID: %s opertating Channel: %u"),
5652 pRoamProfile->SSIDs.SSIDList->SSID.ssId, operatingChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -07005653 if ((IW_AUTH_WPA_VERSION_WPA == pWextState->wpaVersion) ||
5654 (IW_AUTH_WPA_VERSION_WPA2 == pWextState->wpaVersion))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305655 {
Jeff Johnson295189b2012-06-20 16:38:30 -07005656 /*set gen ie*/
5657 hdd_SetGENIEToCsr(pAdapter, &RSNAuthType);
5658 /*set auth*/
5659 hdd_set_csr_auth_type(pAdapter, RSNAuthType);
5660 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005661#ifdef FEATURE_WLAN_WAPI
5662 if (pAdapter->wapi_info.nWapiMode)
5663 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005664 hddLog(LOG1, "%s: Setting WAPI AUTH Type and Encryption Mode values", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005665 switch (pAdapter->wapi_info.wapiAuthMode)
5666 {
5667 case WAPI_AUTH_MODE_PSK:
5668 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005669 hddLog(LOG1, "%s: WAPI AUTH TYPE: PSK: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07005670 pAdapter->wapi_info.wapiAuthMode);
5671 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_PSK;
5672 break;
5673 }
5674 case WAPI_AUTH_MODE_CERT:
5675 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005676 hddLog(LOG1, "%s: WAPI AUTH TYPE: CERT: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07005677 pAdapter->wapi_info.wapiAuthMode);
5678 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE;
5679 break;
5680 }
5681 } // End of switch
5682 if ( pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_PSK ||
5683 pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_CERT)
5684 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005685 hddLog(LOG1, "%s: WAPI PAIRWISE/GROUP ENCRYPTION: WPI", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005686 pRoamProfile->AuthType.numEntries = 1;
5687 pRoamProfile->EncryptionType.numEntries = 1;
5688 pRoamProfile->EncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
5689 pRoamProfile->mcEncryptionType.numEntries = 1;
5690 pRoamProfile->mcEncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
5691 }
5692 }
5693#endif /* FEATURE_WLAN_WAPI */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05305694#ifdef WLAN_FEATURE_GTK_OFFLOAD
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05305695 /* Initializing gtkOffloadReqParams */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05305696 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
5697 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
5698 {
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05305699 memset(&pHddStaCtx->gtkOffloadReqParams, 0,
5700 sizeof (tSirGtkOffloadParams));
5701 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_DISABLE;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05305702 }
5703#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005704 pRoamProfile->csrPersona = pAdapter->device_mode;
5705
Jeff Johnson32d95a32012-09-10 13:15:23 -07005706 if( operatingChannel )
5707 {
5708 pRoamProfile->ChannelInfo.ChannelList = &operatingChannel;
5709 pRoamProfile->ChannelInfo.numOfChannels = 1;
5710 }
Chet Lanctot186b5732013-03-18 10:26:30 -07005711 else
5712 {
5713 pRoamProfile->ChannelInfo.ChannelList = NULL;
5714 pRoamProfile->ChannelInfo.numOfChannels = 0;
5715 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07005716 if ( (WLAN_HDD_IBSS == pAdapter->device_mode) && operatingChannel)
5717 {
5718 hdd_select_cbmode(pAdapter,operatingChannel);
5719 }
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +05305720
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08005721 /* change conn_state to connecting before sme_RoamConnect(), because sme_RoamConnect()
5722 * has a direct path to call hdd_smeRoamCallback(), which will change the conn_state
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305723 * If direct path, conn_state will be accordingly changed to NotConnected or Associated
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08005724 * by either hdd_AssociationCompletionHandler() or hdd_DisConnectHandler() in sme_RoamCallback()
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -08005725 * if sme_RomConnect is to be queued, Connecting state will remain until it is completed.
5726 */
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05305727 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
5728 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode)
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -08005729 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
5730 eConnectionState_Connecting);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305731
5732 status = sme_RoamConnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07005733 pAdapter->sessionId, pRoamProfile, &roamId);
5734
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05305735 if ((eHAL_STATUS_SUCCESS != status) &&
5736 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
5737 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +05305738
5739 {
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08005740 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: sme_RoamConnect (session %d) failed with "
5741 "status %d. -> NotConnected", __func__, pAdapter->sessionId, status);
5742 /* change back to NotAssociated */
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +05305743 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08005744 eConnectionState_NotConnected);
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +05305745 }
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -08005746
5747 pRoamProfile->ChannelInfo.ChannelList = NULL;
5748 pRoamProfile->ChannelInfo.numOfChannels = 0;
5749
Jeff Johnson295189b2012-06-20 16:38:30 -07005750 }
5751 else
5752 {
5753 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid Roam profile", __func__);
5754 return -EINVAL;
5755 }
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08005756 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07005757 return status;
5758}
5759
5760/*
5761 * FUNCTION: wlan_hdd_set_cfg80211_auth_type
5762 * This function is used to set the authentication type (OPEN/SHARED).
5763 *
5764 */
5765static int wlan_hdd_cfg80211_set_auth_type(hdd_adapter_t *pAdapter,
5766 enum nl80211_auth_type auth_type)
5767{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305768 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07005769 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
5770
5771 ENTER();
5772
5773 /*set authentication type*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305774 switch (auth_type)
Jeff Johnson295189b2012-06-20 16:38:30 -07005775 {
Jeff Johnson295189b2012-06-20 16:38:30 -07005776 case NL80211_AUTHTYPE_AUTOMATIC:
Gopichand Nakkala29149562013-05-10 21:43:41 +05305777 hddLog(VOS_TRACE_LEVEL_INFO,
5778 "%s: set authentication type to AUTOSWITCH", __func__);
5779 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_AUTOSWITCH;
5780 break;
5781
5782 case NL80211_AUTHTYPE_OPEN_SYSTEM:
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07005783#ifdef WLAN_FEATURE_VOWIFI_11R
5784 case NL80211_AUTHTYPE_FT:
5785#endif /* WLAN_FEATURE_VOWIFI_11R */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305786 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -07005787 "%s: set authentication type to OPEN", __func__);
5788 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
5789 break;
5790
5791 case NL80211_AUTHTYPE_SHARED_KEY:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305792 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -07005793 "%s: set authentication type to SHARED", __func__);
5794 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_SHARED_KEY;
5795 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005796#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -07005797 case NL80211_AUTHTYPE_NETWORK_EAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305798 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -07005799 "%s: set authentication type to CCKM WPA", __func__);
5800 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_CCKM_WPA;//eCSR_AUTH_TYPE_CCKM_RSN needs to be handled as well if required.
5801 break;
5802#endif
5803
5804
5805 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305806 hddLog(VOS_TRACE_LEVEL_ERROR,
5807 "%s: Unsupported authentication type %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07005808 auth_type);
5809 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_UNKNOWN;
5810 return -EINVAL;
5811 }
5812
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305813 pWextState->roamProfile.AuthType.authType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -07005814 pHddStaCtx->conn_info.authType;
5815 return 0;
5816}
5817
5818/*
5819 * FUNCTION: wlan_hdd_set_akm_suite
5820 * This function is used to set the key mgmt type(PSK/8021x).
5821 *
5822 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305823static int wlan_hdd_set_akm_suite( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07005824 u32 key_mgmt
5825 )
5826{
5827 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
5828 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305829
Jeff Johnson295189b2012-06-20 16:38:30 -07005830 /*set key mgmt type*/
5831 switch(key_mgmt)
5832 {
5833 case WLAN_AKM_SUITE_PSK:
Gopichand Nakkala356fb102013-03-06 12:34:04 +05305834#ifdef WLAN_FEATURE_VOWIFI_11R
5835 case WLAN_AKM_SUITE_FT_PSK:
5836#endif
5837 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to PSK",
Jeff Johnson295189b2012-06-20 16:38:30 -07005838 __func__);
5839 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_PSK;
5840 break;
5841
5842 case WLAN_AKM_SUITE_8021X:
Gopichand Nakkala356fb102013-03-06 12:34:04 +05305843#ifdef WLAN_FEATURE_VOWIFI_11R
5844 case WLAN_AKM_SUITE_FT_8021X:
5845#endif
5846 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to 8021x",
Jeff Johnson295189b2012-06-20 16:38:30 -07005847 __func__);
5848 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
5849 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005850#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -07005851#define WLAN_AKM_SUITE_CCKM 0x00409600 /* Should be in ieee802_11_defs.h */
5852#define IW_AUTH_KEY_MGMT_CCKM 8 /* Should be in linux/wireless.h */
5853 case WLAN_AKM_SUITE_CCKM:
5854 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to CCKM",
5855 __func__);
5856 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_CCKM;
5857 break;
5858#endif
5859
5860 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305861 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported key mgmt type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07005862 __func__, key_mgmt);
5863 return -EINVAL;
5864
5865 }
5866 return 0;
5867}
5868
5869/*
5870 * FUNCTION: wlan_hdd_cfg80211_set_cipher
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305871 * This function is used to set the encryption type
Jeff Johnson295189b2012-06-20 16:38:30 -07005872 * (NONE/WEP40/WEP104/TKIP/CCMP).
5873 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305874static int wlan_hdd_cfg80211_set_cipher( hdd_adapter_t *pAdapter,
5875 u32 cipher,
Jeff Johnson295189b2012-06-20 16:38:30 -07005876 bool ucast
5877 )
5878{
5879 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305880 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07005881 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
5882
5883 ENTER();
5884
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305885 if (!cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -07005886 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305887 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: received cipher %d - considering none",
Jeff Johnson295189b2012-06-20 16:38:30 -07005888 __func__, cipher);
5889 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
5890 }
5891 else
5892 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305893
Jeff Johnson295189b2012-06-20 16:38:30 -07005894 /*set encryption method*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305895 switch (cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -07005896 {
5897 case IW_AUTH_CIPHER_NONE:
5898 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
5899 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305900
Jeff Johnson295189b2012-06-20 16:38:30 -07005901 case WLAN_CIPHER_SUITE_WEP40:
Gopichand Nakkala29149562013-05-10 21:43:41 +05305902 encryptionType = eCSR_ENCRYPT_TYPE_WEP40;
Jeff Johnson295189b2012-06-20 16:38:30 -07005903 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305904
Jeff Johnson295189b2012-06-20 16:38:30 -07005905 case WLAN_CIPHER_SUITE_WEP104:
Gopichand Nakkala29149562013-05-10 21:43:41 +05305906 encryptionType = eCSR_ENCRYPT_TYPE_WEP104;
Jeff Johnson295189b2012-06-20 16:38:30 -07005907 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305908
Jeff Johnson295189b2012-06-20 16:38:30 -07005909 case WLAN_CIPHER_SUITE_TKIP:
5910 encryptionType = eCSR_ENCRYPT_TYPE_TKIP;
5911 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305912
Jeff Johnson295189b2012-06-20 16:38:30 -07005913 case WLAN_CIPHER_SUITE_CCMP:
5914 encryptionType = eCSR_ENCRYPT_TYPE_AES;
5915 break;
5916#ifdef FEATURE_WLAN_WAPI
5917 case WLAN_CIPHER_SUITE_SMS4:
5918 encryptionType = eCSR_ENCRYPT_TYPE_WPI;
5919 break;
5920#endif
5921
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005922#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -07005923 case WLAN_CIPHER_SUITE_KRK:
5924 encryptionType = eCSR_ENCRYPT_TYPE_KRK;
5925 break;
5926#endif
5927 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305928 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported cipher type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07005929 __func__, cipher);
5930 return -EOPNOTSUPP;
5931 }
5932 }
5933
5934 if (ucast)
5935 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305936 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting unicast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07005937 __func__, encryptionType);
5938 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
5939 pWextState->roamProfile.EncryptionType.numEntries = 1;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305940 pWextState->roamProfile.EncryptionType.encryptionType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -07005941 encryptionType;
5942 }
5943 else
5944 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305945 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting mcast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07005946 __func__, encryptionType);
5947 pHddStaCtx->conn_info.mcEncryptionType = encryptionType;
5948 pWextState->roamProfile.mcEncryptionType.numEntries = 1;
5949 pWextState->roamProfile.mcEncryptionType.encryptionType[0] = encryptionType;
5950 }
5951
5952 return 0;
5953}
5954
5955
5956/*
5957 * FUNCTION: wlan_hdd_cfg80211_set_ie
5958 * This function is used to parse WPA/RSN IE's.
5959 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305960int wlan_hdd_cfg80211_set_ie( hdd_adapter_t *pAdapter,
5961 u8 *ie,
Jeff Johnson295189b2012-06-20 16:38:30 -07005962 size_t ie_len
5963 )
5964{
5965 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
5966 u8 *genie = ie;
5967 v_U16_t remLen = ie_len;
5968#ifdef FEATURE_WLAN_WAPI
5969 v_U32_t akmsuite[MAX_NUM_AKM_SUITES];
5970 u16 *tmp;
5971 v_U16_t akmsuiteCount;
5972 int *akmlist;
5973#endif
5974 ENTER();
5975
5976 /* clear previous assocAddIE */
5977 pWextState->assocAddIE.length = 0;
5978 pWextState->roamProfile.bWPSAssociation = VOS_FALSE;
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -07005979 pWextState->roamProfile.bOSENAssociation = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07005980
5981 while (remLen >= 2)
5982 {
5983 v_U16_t eLen = 0;
5984 v_U8_t elementId;
5985 elementId = *genie++;
5986 eLen = *genie++;
5987 remLen -= 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305988
Arif Hussain6d2a3322013-11-17 19:50:10 -08005989 hddLog(VOS_TRACE_LEVEL_INFO, "%s: IE[0x%X], LEN[%d]",
Jeff Johnson295189b2012-06-20 16:38:30 -07005990 __func__, elementId, eLen);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305991
5992 switch ( elementId )
Jeff Johnson295189b2012-06-20 16:38:30 -07005993 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305994 case DOT11F_EID_WPA:
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005995 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 -07005996 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305997 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07005998 "%s: Invalid WPA IE", __func__);
5999 return -EINVAL;
6000 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306001 else if (0 == memcmp(&genie[0], "\x00\x50\xf2\x04", 4))
Jeff Johnson295189b2012-06-20 16:38:30 -07006002 {
6003 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306004 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPS IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -07006005 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306006
Jeff Johnson295189b2012-06-20 16:38:30 -07006007 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
6008 {
Jeff Johnson902c9832012-12-10 14:28:09 -08006009 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE. "
6010 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -07006011 VOS_ASSERT(0);
6012 return -ENOMEM;
6013 }
6014 // WSC IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
6015 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
6016 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306017
Jeff Johnson295189b2012-06-20 16:38:30 -07006018 pWextState->roamProfile.bWPSAssociation = VOS_TRUE;
6019 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
6020 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
6021 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306022 else if (0 == memcmp(&genie[0], "\x00\x50\xf2", 3))
6023 {
Jeff Johnson295189b2012-06-20 16:38:30 -07006024 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPA IE (len %d)",__func__, eLen + 2);
6025 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
6026 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2) /*ie_len*/);
6027 pWextState->roamProfile.pWPAReqIE = pWextState->WPARSNIE;
6028 pWextState->roamProfile.nWPAReqIELength = eLen + 2;//ie_len;
6029 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306030 else if ( (0 == memcmp(&genie[0], P2P_OUI_TYPE,
Kiet Lam8da98992013-11-21 15:59:07 +05306031 P2P_OUI_TYPE_SIZE)))
Jeff Johnson295189b2012-06-20 16:38:30 -07006032 {
6033 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306034 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set P2P IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -07006035 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306036
Jeff Johnson295189b2012-06-20 16:38:30 -07006037 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
6038 {
Jeff Johnson902c9832012-12-10 14:28:09 -08006039 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
6040 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -07006041 VOS_ASSERT(0);
6042 return -ENOMEM;
6043 }
6044 // P2P IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
6045 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
6046 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306047
Jeff Johnson295189b2012-06-20 16:38:30 -07006048 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
6049 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
6050 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006051#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306052 else if ( (0 == memcmp(&genie[0], WFD_OUI_TYPE,
6053 WFD_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07006054 /*Consider WFD IE, only for P2P Client */
6055 && (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
6056 {
6057 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306058 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WFD IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -07006059 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306060
Jeff Johnson295189b2012-06-20 16:38:30 -07006061 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
6062 {
Jeff Johnson902c9832012-12-10 14:28:09 -08006063 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
6064 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -07006065 VOS_ASSERT(0);
6066 return -ENOMEM;
6067 }
6068 // WFD IE is saved to Additional IE ; it should be accumulated to handle
6069 // WPS IE + P2P IE + WFD IE
6070 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
6071 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306072
Jeff Johnson295189b2012-06-20 16:38:30 -07006073 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
6074 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
6075 }
6076#endif
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07006077 /* Appending HS 2.0 Indication Element in Assiciation Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306078 else if ( (0 == memcmp(&genie[0], HS20_OUI_TYPE,
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07006079 HS20_OUI_TYPE_SIZE)) )
6080 {
6081 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306082 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set HS20 IE(len %d)",
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07006083 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07006084
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07006085 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
6086 {
Jeff Johnson902c9832012-12-10 14:28:09 -08006087 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
6088 "Need bigger buffer space");
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07006089 VOS_ASSERT(0);
6090 return -ENOMEM;
6091 }
6092 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
6093 pWextState->assocAddIE.length += eLen + 2;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07006094
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07006095 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
6096 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
6097 }
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -07006098 /* Appending OSEN Information Element in Assiciation Request */
6099 else if ( (0 == memcmp(&genie[0], OSEN_OUI_TYPE,
6100 OSEN_OUI_TYPE_SIZE)) )
6101 {
6102 v_U16_t curAddIELen = pWextState->assocAddIE.length;
6103 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set OSEN IE(len %d)",
6104 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07006105
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -07006106 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
6107 {
6108 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
6109 "Need bigger buffer space");
6110 VOS_ASSERT(0);
6111 return -ENOMEM;
6112 }
6113 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
6114 pWextState->assocAddIE.length += eLen + 2;
6115
6116 pWextState->roamProfile.bOSENAssociation = VOS_TRUE;
6117 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
6118 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
6119 }
6120
6121 break;
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -07006122 if (WLAN_HDD_IBSS == pAdapter->device_mode) {
6123
6124 /* populating as ADDIE in beacon frames */
6125 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
6126 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, genie - 2, eLen + 2,
6127 NULL, eANI_BOOLEAN_FALSE)== eHAL_STATUS_SUCCESS)
6128 {
6129 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
6130 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
6131 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
6132 {
6133 hddLog(LOGE,
6134 "Coldn't pass "
6135 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
6136 }
6137 }/* ccmCfgSetStr(,WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, , )*/
6138 else
6139 hddLog(LOGE,
6140 "Could not pass on "
6141 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
6142
6143 /* IBSS mode doesn't contain params->proberesp_ies still
6144 beaconIE's need to be populated in probe response frames */
6145 if ( (NULL != (genie - 2)) && (0 != eLen + 2) )
6146 {
6147 u16 rem_probe_resp_ie_len = eLen + 2;
6148 u8 probe_rsp_ie_len[3] = {0};
6149 u8 counter = 0;
6150
6151 /* Check Probe Resp Length if it is greater then 255 then
6152 Store Probe Rsp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1
6153 & WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are
6154 not able Store More then 255 bytes into One Variable */
6155
6156 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
6157 {
6158 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
6159 {
6160 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
6161 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
6162 }
6163 else
6164 {
6165 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
6166 rem_probe_resp_ie_len = 0;
6167 }
6168 }
6169
6170 rem_probe_resp_ie_len = 0;
6171
6172 if (probe_rsp_ie_len[0] > 0)
6173 {
6174 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
6175 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
6176 (tANI_U8*)(genie - 2),
6177 probe_rsp_ie_len[0], NULL,
6178 eANI_BOOLEAN_FALSE)
6179 == eHAL_STATUS_FAILURE)
6180 {
6181 hddLog(LOGE,
6182 "Could not pass"
6183 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
6184 }
6185 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
6186 }
6187
6188 if (probe_rsp_ie_len[1] > 0)
6189 {
6190 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
6191 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
6192 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
6193 probe_rsp_ie_len[1], NULL,
6194 eANI_BOOLEAN_FALSE)
6195 == eHAL_STATUS_FAILURE)
6196 {
6197 hddLog(LOGE,
6198 "Could not pass"
6199 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
6200 }
6201 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
6202 }
6203
6204 if (probe_rsp_ie_len[2] > 0)
6205 {
6206 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
6207 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
6208 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
6209 probe_rsp_ie_len[2], NULL,
6210 eANI_BOOLEAN_FALSE)
6211 == eHAL_STATUS_FAILURE)
6212 {
6213 hddLog(LOGE,
6214 "Could not pass"
6215 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
6216 }
6217 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
6218 }
6219
6220 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
6221 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
6222 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
6223 {
6224 hddLog(LOGE,
6225 "Could not pass"
6226 "on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
6227 }
6228 }
6229 else
6230 {
6231 // Reset WNI_CFG_PROBE_RSP Flags
6232 wlan_hdd_reset_prob_rspies(pAdapter);
6233
6234 hddLog(VOS_TRACE_LEVEL_INFO,
6235 "%s: No Probe Response IE received in set beacon",
6236 __func__);
6237 }
6238 } /* end of if (WLAN_HDD_IBSS == pAdapter->device_mode) */
Jeff Johnson295189b2012-06-20 16:38:30 -07006239 break;
6240 case DOT11F_EID_RSN:
6241 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set RSN IE(len %d)",__func__, eLen + 2);
6242 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
6243 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2)/*ie_len*/);
6244 pWextState->roamProfile.pRSNReqIE = pWextState->WPARSNIE;
6245 pWextState->roamProfile.nRSNReqIELength = eLen + 2; //ie_len;
6246 break;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07006247 /* Appending Extended Capabilities with Interworking bit set in Assoc Req */
6248 case DOT11F_EID_EXTCAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306249 {
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07006250 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306251 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set Extended CAPS IE(len %d)",
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07006252 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306253
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07006254 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
6255 {
Jeff Johnson902c9832012-12-10 14:28:09 -08006256 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
6257 "Need bigger buffer space");
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07006258 VOS_ASSERT(0);
6259 return -ENOMEM;
6260 }
6261 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
6262 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306263
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07006264 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
6265 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
6266 break;
6267 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006268#ifdef FEATURE_WLAN_WAPI
6269 case WLAN_EID_WAPI:
6270 pAdapter->wapi_info.nWapiMode = 1; //Setting WAPI Mode to ON=1
Jeff Johnson0299d0a2013-10-30 12:37:43 -07006271 hddLog(VOS_TRACE_LEVEL_INFO, "WAPI MODE IS %u",
Jeff Johnson295189b2012-06-20 16:38:30 -07006272 pAdapter->wapi_info.nWapiMode);
6273 tmp = (u16 *)ie;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306274 tmp = tmp + 2; // Skip element Id and Len, Version
Jeff Johnson295189b2012-06-20 16:38:30 -07006275 akmsuiteCount = WPA_GET_LE16(tmp);
6276 tmp = tmp + 1;
6277 akmlist = (int *)(tmp);
6278 if(akmsuiteCount <= MAX_NUM_AKM_SUITES)
6279 {
6280 memcpy(akmsuite, akmlist, (4*akmsuiteCount));
6281 }
6282 else
6283 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08006284 hddLog(VOS_TRACE_LEVEL_FATAL, "Invalid akmSuite count");
Jeff Johnson295189b2012-06-20 16:38:30 -07006285 VOS_ASSERT(0);
6286 return -EINVAL;
6287 }
6288
6289 if (WAPI_PSK_AKM_SUITE == akmsuite[0])
6290 {
6291 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO PSK",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006292 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006293 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_PSK;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306294 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006295 if (WAPI_CERT_AKM_SUITE == akmsuite[0])
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306296 {
Jeff Johnson295189b2012-06-20 16:38:30 -07006297 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO CERTIFICATE",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006298 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006299 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_CERT;
6300 }
6301 break;
6302#endif
6303 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306304 hddLog (VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07006305 "%s Set UNKNOWN IE %X", __func__, elementId);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07006306 /* when Unknown IE is received we should break and continue
6307 * to the next IE in the buffer instead we were returning
6308 * so changing this to break */
6309 break;
Jeff Johnson295189b2012-06-20 16:38:30 -07006310 }
6311 genie += eLen;
6312 remLen -= eLen;
6313 }
6314 EXIT();
6315 return 0;
6316}
6317
6318/*
Gopichand Nakkala18f0c262013-05-07 23:25:08 +05306319 * FUNCTION: hdd_isWPAIEPresent
6320 * Parse the received IE to find the WPA IE
6321 *
6322 */
6323static bool hdd_isWPAIEPresent(u8 *ie, u8 ie_len)
6324{
6325 v_U8_t eLen = 0;
6326 v_U16_t remLen = ie_len;
6327 v_U8_t elementId = 0;
6328
6329 while (remLen >= 2)
6330 {
6331 elementId = *ie++;
6332 eLen = *ie++;
6333 remLen -= 2;
6334 if (eLen > remLen)
6335 {
6336 hddLog(VOS_TRACE_LEVEL_ERROR,
6337 "%s: IE length is wrong %d", __func__, eLen);
6338 return FALSE;
6339 }
6340 if ((elementId == DOT11F_EID_WPA) && (remLen > 5))
6341 {
6342 /* OUI - 0x00 0X50 0XF2
6343 WPA Information Element - 0x01
6344 WPA version - 0x01*/
6345 if (0 == memcmp(&ie[0], "\x00\x50\xf2\x01\x01", 5))
6346 return TRUE;
6347 }
6348 ie += eLen;
6349 remLen -= eLen;
6350 }
6351 return FALSE;
6352}
6353
6354/*
Jeff Johnson295189b2012-06-20 16:38:30 -07006355 * FUNCTION: wlan_hdd_cfg80211_set_privacy
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306356 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -07006357 * parameters during connect operation.
6358 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306359int wlan_hdd_cfg80211_set_privacy( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07006360 struct cfg80211_connect_params *req
6361 )
6362{
6363 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306364 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07006365 ENTER();
6366
6367 /*set wpa version*/
6368 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
6369
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306370 if (req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -07006371 {
Gopichand Nakkala781ded42013-06-28 12:10:45 +05306372 if (NL80211_WPA_VERSION_1 == req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -07006373 {
6374 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
6375 }
6376 else if (NL80211_WPA_VERSION_2 == req->crypto.wpa_versions)
6377 {
6378 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
6379 }
6380 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306381
6382 hddLog(VOS_TRACE_LEVEL_INFO, "%s: set wpa version to %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07006383 pWextState->wpaVersion);
6384
6385 /*set authentication type*/
6386 status = wlan_hdd_cfg80211_set_auth_type(pAdapter, req->auth_type);
6387
6388 if (0 > status)
6389 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306390 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07006391 "%s: failed to set authentication type ", __func__);
6392 return status;
6393 }
6394
6395 /*set key mgmt type*/
6396 if (req->crypto.n_akm_suites)
6397 {
6398 status = wlan_hdd_set_akm_suite(pAdapter, req->crypto.akm_suites[0]);
6399 if (0 > status)
6400 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306401 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set akm suite",
Jeff Johnson295189b2012-06-20 16:38:30 -07006402 __func__);
6403 return status;
6404 }
6405 }
6406
6407 /*set pairwise cipher type*/
6408 if (req->crypto.n_ciphers_pairwise)
6409 {
6410 status = wlan_hdd_cfg80211_set_cipher(pAdapter,
6411 req->crypto.ciphers_pairwise[0], true);
6412 if (0 > status)
6413 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306414 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07006415 "%s: failed to set unicast cipher type", __func__);
6416 return status;
6417 }
6418 }
6419 else
6420 {
6421 /*Reset previous cipher suite to none*/
6422 status = wlan_hdd_cfg80211_set_cipher(pAdapter, 0, true);
6423 if (0 > status)
6424 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306425 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07006426 "%s: failed to set unicast cipher type", __func__);
6427 return status;
6428 }
6429 }
6430
6431 /*set group cipher type*/
6432 status = wlan_hdd_cfg80211_set_cipher(pAdapter, req->crypto.cipher_group,
6433 false);
6434
6435 if (0 > status)
6436 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306437 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set mcast cipher type",
Jeff Johnson295189b2012-06-20 16:38:30 -07006438 __func__);
6439 return status;
6440 }
6441
Chet Lanctot186b5732013-03-18 10:26:30 -07006442#ifdef WLAN_FEATURE_11W
6443 pWextState->roamProfile.MFPEnabled = (req->mfp == NL80211_MFP_REQUIRED);
6444#endif
6445
Jeff Johnson295189b2012-06-20 16:38:30 -07006446 /*parse WPA/RSN IE, and set the correspoing fileds in Roam profile*/
6447 if (req->ie_len)
6448 {
6449 status = wlan_hdd_cfg80211_set_ie(pAdapter, req->ie, req->ie_len);
6450 if ( 0 > status)
6451 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306452 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse the WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -07006453 __func__);
6454 return status;
6455 }
6456 }
6457
6458 /*incase of WEP set default key information*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306459 if (req->key && req->key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -07006460 {
6461 if ( (WLAN_CIPHER_SUITE_WEP40 == req->crypto.ciphers_pairwise[0])
6462 || (WLAN_CIPHER_SUITE_WEP104 == req->crypto.ciphers_pairwise[0])
6463 )
6464 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306465 if ( IW_AUTH_KEY_MGMT_802_1X
Jeff Johnson295189b2012-06-20 16:38:30 -07006466 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X ))
6467 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306468 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Dynamic WEP not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -07006469 __func__);
6470 return -EOPNOTSUPP;
6471 }
6472 else
6473 {
6474 u8 key_len = req->key_len;
6475 u8 key_idx = req->key_idx;
6476
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306477 if ((eCSR_SECURITY_WEP_KEYSIZE_MAX_BYTES >= key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -07006478 && (CSR_MAX_NUM_KEY > key_idx)
6479 )
6480 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306481 hddLog(VOS_TRACE_LEVEL_INFO,
6482 "%s: setting default wep key, key_idx = %hu key_len %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07006483 __func__, key_idx, key_len);
6484 vos_mem_copy(
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306485 &pWextState->roamProfile.Keys.KeyMaterial[key_idx][0],
Jeff Johnson295189b2012-06-20 16:38:30 -07006486 req->key, key_len);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306487 pWextState->roamProfile.Keys.KeyLength[key_idx] =
Jeff Johnson295189b2012-06-20 16:38:30 -07006488 (u8)key_len;
6489 pWextState->roamProfile.Keys.defaultIndex = (u8)key_idx;
6490 }
6491 }
6492 }
6493 }
6494
6495 return status;
6496}
6497
6498/*
Vinay Krishna Eranna21042322014-01-08 19:21:39 +05306499 * FUNCTION: wlan_hdd_try_disconnect
6500 * This function is used to disconnect from previous
6501 * connection
6502 */
6503static int wlan_hdd_try_disconnect( hdd_adapter_t *pAdapter )
6504{
6505 long ret = 0;
6506 hdd_station_ctx_t *pHddStaCtx;
6507 eMib_dot11DesiredBssType connectedBssType;
6508
6509 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6510
6511 hdd_connGetConnectedBssType(pHddStaCtx,&connectedBssType );
6512
6513 if((eMib_dot11DesiredBssType_independent == connectedBssType) ||
6514 (eConnectionState_Associated == pHddStaCtx->conn_info.connState) ||
6515 (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState))
6516 {
6517 /* Issue disconnect to CSR */
6518 INIT_COMPLETION(pAdapter->disconnect_comp_var);
6519 if( eHAL_STATUS_SUCCESS ==
6520 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
6521 pAdapter->sessionId,
6522 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
6523 {
6524 ret = wait_for_completion_interruptible_timeout(
6525 &pAdapter->disconnect_comp_var,
6526 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
6527 if (0 >= ret)
6528 {
6529 hddLog(LOGE, FL("Failed to receive disconnect event"));
6530 return -EALREADY;
6531 }
6532 }
6533 }
6534 else if(eConnectionState_Disconnecting == pHddStaCtx->conn_info.connState)
6535 {
6536 ret = wait_for_completion_interruptible_timeout(
6537 &pAdapter->disconnect_comp_var,
6538 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
6539 if (0 >= ret)
6540 {
6541 hddLog(LOGE, FL("Failed to receive disconnect event"));
6542 return -EALREADY;
6543 }
6544 }
6545
6546 return 0;
6547}
6548
6549/*
Jeff Johnson295189b2012-06-20 16:38:30 -07006550 * FUNCTION: wlan_hdd_cfg80211_set_privacy
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306551 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -07006552 * parameters during connect operation.
6553 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306554static int wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07006555 struct net_device *ndev,
6556 struct cfg80211_connect_params *req
6557 )
6558{
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306559 int status;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306560 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -07006561 VOS_STATUS exitbmpsStatus = VOS_STATUS_E_INVAL;
Rajesh Chauhana0516c62014-01-30 16:11:18 -08006562 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07006563
6564 ENTER();
6565
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05306566 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
6567 TRACE_CODE_HDD_CFG80211_CONNECT,
6568 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306569 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006570 "%s: device_mode = %d",__func__,pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07006571
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306572 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -08006573 if (!pHddCtx)
6574 {
6575 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6576 "%s: HDD context is null", __func__);
6577 return VOS_STATUS_E_FAILURE;
6578 }
6579
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306580 status = wlan_hdd_validate_context(pHddCtx);
6581
6582 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -07006583 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306584 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6585 "%s: HDD context is not valid", __func__);
6586 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -07006587 }
6588
6589#ifdef WLAN_BTAMP_FEATURE
6590 //Infra connect not supported when AMP traffic is on.
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306591 if( VOS_TRUE == WLANBAP_AmpSessionOn() )
Jeff Johnson295189b2012-06-20 16:38:30 -07006592 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306593 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07006594 "%s: No connection when AMP is on", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08006595 return -ECONNREFUSED;
Jeff Johnson295189b2012-06-20 16:38:30 -07006596 }
6597#endif
Vinay Krishna Eranna21042322014-01-08 19:21:39 +05306598
6599 //If Device Mode is Station Concurrent Sessions Exit BMps
6600 //P2P Mode will be taken care in Open/close adapter
6601 if((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
6602 (vos_concurrent_sessions_running()))
6603 {
6604 exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
6605 }
6606
6607 /*Try disconnecting if already in connected state*/
6608 status = wlan_hdd_try_disconnect(pAdapter);
6609 if ( 0 > status)
6610 {
6611 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
6612 " connection"));
6613 return -EALREADY;
6614 }
6615
Jeff Johnson295189b2012-06-20 16:38:30 -07006616 /*initialise security parameters*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306617 status = wlan_hdd_cfg80211_set_privacy(pAdapter, req);
Jeff Johnson295189b2012-06-20 16:38:30 -07006618
6619 if ( 0 > status)
6620 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306621 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security params",
Jeff Johnson295189b2012-06-20 16:38:30 -07006622 __func__);
6623 return status;
6624 }
6625
Mohit Khanna765234a2012-09-11 15:08:35 -07006626 if ( req->channel )
6627 {
6628 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
6629 req->ssid_len, req->bssid,
6630 req->channel->hw_value);
6631 }
6632 else
6633 {
6634 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306635 req->ssid_len, req->bssid, 0);
Mohit Khanna765234a2012-09-11 15:08:35 -07006636 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006637
6638 if (0 > status)
6639 {
6640 //ReEnable BMPS if disabled
6641 if((VOS_STATUS_SUCCESS == exitbmpsStatus) &&
6642 (NULL != pHddCtx))
6643 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306644 if (pHddCtx->hdd_wlan_suspended)
6645 {
6646 hdd_set_pwrparams(pHddCtx);
6647 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006648 //ReEnable Bmps and Imps back
6649 hdd_enable_bmps_imps(pHddCtx);
6650 }
6651
6652 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: connect failed", __func__);
6653 return status;
6654 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306655 pHddCtx->isAmpAllowed = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07006656 EXIT();
6657 return status;
6658}
6659
6660
6661/*
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05306662 * FUNCTION: wlan_hdd_disconnect
6663 * This function is used to issue a disconnect request to SME
6664 */
6665int wlan_hdd_disconnect( hdd_adapter_t *pAdapter, u16 reason )
6666{
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306667 int status;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05306668 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306669 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
6670
6671 status = wlan_hdd_validate_context(pHddCtx);
6672
6673 if (0 != status)
6674 {
6675 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6676 "%s: HDD context is not valid", __func__);
6677 return status;
6678 }
6679
6680 pHddCtx->isAmpAllowed = VOS_TRUE;
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +05306681 pHddStaCtx->conn_info.connState = eConnectionState_Disconnecting;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05306682 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306683
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05306684 /*issue disconnect*/
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +05306685
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05306686 status = sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
6687 pAdapter->sessionId, reason);
6688
6689 if ( 0 != status )
6690 {
6691 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006692 "%s csrRoamDisconnect failure, returned %d",
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05306693 __func__, (int)status );
6694 return -EINVAL;
6695 }
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +05306696 status = wait_for_completion_interruptible_timeout(
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05306697 &pAdapter->disconnect_comp_var,
6698 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +05306699 if (!status)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306700 {
6701 hddLog(VOS_TRACE_LEVEL_ERROR,
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +05306702 "%s: Failed to disconnect, timed out", __func__);
6703 return -ETIMEDOUT;
6704 }
6705 else if (status == -ERESTARTSYS)
6706 {
6707 hddLog(VOS_TRACE_LEVEL_ERROR,
6708 "%s: Failed to disconnect, wait interrupted", __func__);
6709 return status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306710 }
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05306711 /*stop tx queues*/
6712 netif_tx_disable(pAdapter->dev);
6713 netif_carrier_off(pAdapter->dev);
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +05306714 return 0;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05306715}
6716
6717
6718/*
Jeff Johnson295189b2012-06-20 16:38:30 -07006719 * FUNCTION: wlan_hdd_cfg80211_disconnect
6720 * This function is used to issue a disconnect request to SME
6721 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306722static int wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07006723 struct net_device *dev,
6724 u16 reason
6725 )
6726{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306727 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
6728 tCsrRoamProfile *pRoamProfile =
Jeff Johnson295189b2012-06-20 16:38:30 -07006729 &(WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter))->roamProfile;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306730 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07006731 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkala4327a152013-03-04 23:22:42 -08006732 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaaa353782013-05-17 20:36:22 +05306733#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08006734 tANI_U8 staIdx;
6735#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306736
Jeff Johnson295189b2012-06-20 16:38:30 -07006737 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306738
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05306739 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
6740 TRACE_CODE_HDD_CFG80211_DISCONNECT,
6741 pAdapter->sessionId, reason));
6742 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",
Jeff Johnson295189b2012-06-20 16:38:30 -07006743 __func__,pAdapter->device_mode);
6744
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306745 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Disconnect called with reason code %d",
6746 __func__, reason);
Jeff Johnson295189b2012-06-20 16:38:30 -07006747
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306748 status = wlan_hdd_validate_context(pHddCtx);
6749
6750 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -07006751 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306752 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6753 "%s: HDD context is not valid", __func__);
6754 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -07006755 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306756
Jeff Johnson295189b2012-06-20 16:38:30 -07006757 if (NULL != pRoamProfile)
6758 {
6759 /*issue disconnect request to SME, if station is in connected state*/
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +05306760 if ((pHddStaCtx->conn_info.connState == eConnectionState_Associated) ||
6761 (pHddStaCtx->conn_info.connState == eConnectionState_Connecting))
Jeff Johnson295189b2012-06-20 16:38:30 -07006762 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306763 eCsrRoamDisconnectReason reasonCode =
Jeff Johnson295189b2012-06-20 16:38:30 -07006764 eCSR_DISCONNECT_REASON_UNSPECIFIED;
Gopichand Nakkalaaa353782013-05-17 20:36:22 +05306765 hdd_scaninfo_t *pScanInfo;
Jeff Johnson295189b2012-06-20 16:38:30 -07006766 switch(reason)
6767 {
6768 case WLAN_REASON_MIC_FAILURE:
6769 reasonCode = eCSR_DISCONNECT_REASON_MIC_ERROR;
6770 break;
6771
6772 case WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY:
6773 case WLAN_REASON_DISASSOC_AP_BUSY:
6774 case WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA:
6775 reasonCode = eCSR_DISCONNECT_REASON_DISASSOC;
6776 break;
6777
6778 case WLAN_REASON_PREV_AUTH_NOT_VALID:
6779 case WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA:
6780 reasonCode = eCSR_DISCONNECT_REASON_DEAUTH;
6781 break;
6782
6783 case WLAN_REASON_DEAUTH_LEAVING:
6784 default:
6785 reasonCode = eCSR_DISCONNECT_REASON_UNSPECIFIED;
6786 break;
6787 }
Gopichand Nakkalaaa353782013-05-17 20:36:22 +05306788 pScanInfo = &pHddCtx->scan_info;
6789 if (pScanInfo->mScanPending)
6790 {
Srinivas, Dasari138af4f2014-02-07 11:13:45 +05306791 hddLog(VOS_TRACE_LEVEL_INFO, "Disconnect is in progress, "
Gopichand Nakkalaaa353782013-05-17 20:36:22 +05306792 "Aborting Scan");
Srinivas, Dasari138af4f2014-02-07 11:13:45 +05306793 hdd_abort_mac_scan(pHddCtx, pAdapter->sessionId,
6794 eCSR_SCAN_ABORT_DEFAULT);
Gopichand Nakkalaaa353782013-05-17 20:36:22 +05306795 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006796
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08006797#ifdef FEATURE_WLAN_TDLS
6798 /* First clean up the tdls peers if any */
Gopichand Nakkala4327a152013-03-04 23:22:42 -08006799 for (staIdx = 0 ; staIdx < HDD_MAX_NUM_TDLS_STA; staIdx++)
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08006800 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -08006801 if ((pHddCtx->tdlsConnInfo[staIdx].sessionId == pAdapter->sessionId) &&
6802 (pHddCtx->tdlsConnInfo[staIdx].staId))
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08006803 {
Hoonki Lee11f7dda2013-02-14 16:55:44 -08006804 uint8 *mac;
Gopichand Nakkala4327a152013-03-04 23:22:42 -08006805 mac = pHddCtx->tdlsConnInfo[staIdx].peerMac.bytes;
Hoonki Lee11f7dda2013-02-14 16:55:44 -08006806 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07006807 "%s: call sme_DeleteTdlsPeerSta staId %d sessionId %d " MAC_ADDRESS_STR,
Gopichand Nakkala4327a152013-03-04 23:22:42 -08006808 __func__, pHddCtx->tdlsConnInfo[staIdx].staId, pAdapter->sessionId,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07006809 MAC_ADDR_ARRAY(mac));
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08006810 sme_DeleteTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala4327a152013-03-04 23:22:42 -08006811 pAdapter->sessionId,
6812 mac);
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08006813 }
6814 }
6815#endif
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +05306816 hddLog(LOG1, FL("Disconnecting with reasoncode:%u"), reasonCode);
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05306817 status = wlan_hdd_disconnect(pAdapter, reasonCode);
6818 if ( 0 != status )
Jeff Johnson295189b2012-06-20 16:38:30 -07006819 {
6820 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006821 "%s wlan_hdd_disconnect failure, returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07006822 __func__, (int)status );
6823 return -EINVAL;
6824 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006825 }
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +05306826 else
6827 {
6828 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unexpected cfg disconnect API"
6829 "called while in %d state", __func__,
6830 pHddStaCtx->conn_info.connState);
6831 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006832 }
6833 else
6834 {
6835 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid roam profile", __func__);
6836 }
6837
6838 return status;
6839}
6840
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05306841
Jeff Johnson295189b2012-06-20 16:38:30 -07006842/*
6843 * FUNCTION: wlan_hdd_cfg80211_set_privacy_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306844 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -07006845 * settings in IBSS mode.
6846 */
6847static int wlan_hdd_cfg80211_set_privacy_ibss(
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306848 hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07006849 struct cfg80211_ibss_params *params
6850 )
6851{
6852 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306853 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07006854 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
6855 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306856
Jeff Johnson295189b2012-06-20 16:38:30 -07006857 ENTER();
6858
6859 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
Ravi Joshib58ca0d2013-10-29 09:50:23 -07006860 vos_mem_zero(&pHddStaCtx->ibss_enc_key, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -07006861
6862 if (params->ie_len && ( NULL != params->ie) )
6863 {
Shailender Karmuchi67edd312013-06-18 16:30:48 -07006864 if (wlan_hdd_cfg80211_get_ie_ptr (params->ie,
6865 params->ie_len, WLAN_EID_RSN ))
Jeff Johnson295189b2012-06-20 16:38:30 -07006866 {
6867 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
6868 encryptionType = eCSR_ENCRYPT_TYPE_AES;
6869 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -07006870 else if ( hdd_isWPAIEPresent (params->ie, params->ie_len ))
Jeff Johnson295189b2012-06-20 16:38:30 -07006871 {
Shailender Karmuchi642e9812013-05-30 14:34:49 -07006872 tDot11fIEWPA dot11WPAIE;
6873 tHalHandle halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
Shailender Karmuchi67edd312013-06-18 16:30:48 -07006874 u8 *ie;
Shailender Karmuchi642e9812013-05-30 14:34:49 -07006875
Wilson Yang00256342013-10-10 23:13:38 -07006876 memset(&dot11WPAIE, 0, sizeof(dot11WPAIE));
Shailender Karmuchi67edd312013-06-18 16:30:48 -07006877 ie = wlan_hdd_cfg80211_get_ie_ptr (params->ie,
6878 params->ie_len, DOT11F_EID_WPA);
6879 if ( NULL != ie )
6880 {
6881 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
6882 // Unpack the WPA IE
6883 //Skip past the EID byte and length byte - and four byte WiFi OUI
6884 dot11fUnpackIeWPA((tpAniSirGlobal) halHandle,
6885 &ie[2+4],
6886 ie[1] - 4,
6887 &dot11WPAIE);
6888 /*Extract the multicast cipher, the encType for unicast
6889 cipher for wpa-none is none*/
6890 encryptionType =
6891 hdd_TranslateWPAToCsrEncryptionType(dot11WPAIE.multicast_cipher);
6892 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006893 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -07006894
Jeff Johnson295189b2012-06-20 16:38:30 -07006895 status = wlan_hdd_cfg80211_set_ie(pAdapter, params->ie, params->ie_len);
6896
6897 if (0 > status)
6898 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306899 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -07006900 __func__);
6901 return status;
6902 }
6903 }
6904
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306905 pWextState->roamProfile.AuthType.authType[0] =
6906 pHddStaCtx->conn_info.authType =
Jeff Johnson295189b2012-06-20 16:38:30 -07006907 eCSR_AUTH_TYPE_OPEN_SYSTEM;
6908
6909 if (params->privacy)
6910 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306911 /* Security enabled IBSS, At this time there is no information available
6912 * about the security paramters, so initialise the encryption type to
Jeff Johnson295189b2012-06-20 16:38:30 -07006913 * eCSR_ENCRYPT_TYPE_WEP40_STATICKEY.
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306914 * The correct security parameters will be updated later in
Jeff Johnson295189b2012-06-20 16:38:30 -07006915 * wlan_hdd_cfg80211_add_key */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306916 /* Hal expects encryption type to be set inorder
Jeff Johnson295189b2012-06-20 16:38:30 -07006917 *enable privacy bit in beacons */
6918
6919 encryptionType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
6920 }
Shailender Karmuchi642e9812013-05-30 14:34:49 -07006921 VOS_TRACE (VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
6922 "encryptionType=%d", encryptionType);
Jeff Johnson295189b2012-06-20 16:38:30 -07006923 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
6924 pWextState->roamProfile.EncryptionType.numEntries = 1;
6925 pWextState->roamProfile.EncryptionType.encryptionType[0] = encryptionType;
Jeff Johnson295189b2012-06-20 16:38:30 -07006926 return status;
6927}
6928
6929/*
6930 * FUNCTION: wlan_hdd_cfg80211_join_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306931 * This function is used to create/join an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -07006932 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306933static int wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07006934 struct net_device *dev,
6935 struct cfg80211_ibss_params *params
6936 )
6937{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306938 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Jeff Johnson295189b2012-06-20 16:38:30 -07006939 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
6940 tCsrRoamProfile *pRoamProfile;
6941 int status;
krunal sonie9002db2013-11-25 14:24:17 -08006942 bool alloc_bssid = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07006943 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306944 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07006945
6946 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306947
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05306948 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
6949 TRACE_CODE_HDD_CFG80211_JOIN_IBSS,
6950 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306951 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006952 "%s: device_mode = %d",__func__,pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07006953
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306954 status = wlan_hdd_validate_context(pHddCtx);
6955
6956 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -07006957 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306958 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6959 "%s: HDD context is not valid", __func__);
6960 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -07006961 }
6962
6963 if (NULL == pWextState)
6964 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08006965 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -07006966 __func__);
6967 return -EIO;
6968 }
6969
Vinay Krishna Eranna21042322014-01-08 19:21:39 +05306970 /*Try disconnecting if already in connected state*/
6971 status = wlan_hdd_try_disconnect(pAdapter);
6972 if ( 0 > status)
6973 {
6974 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
6975 " IBSS connection"));
6976 return -EALREADY;
6977 }
6978
Jeff Johnson295189b2012-06-20 16:38:30 -07006979 pRoamProfile = &pWextState->roamProfile;
6980
6981 if ( eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType )
6982 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306983 hddLog (VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006984 "%s Interface type is not set to IBSS", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006985 return -EINVAL;
6986 }
6987
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -07006988 /* BSSID is provided by upper layers hence no need to AUTO generate */
6989 if (NULL != params->bssid) {
6990 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
6991 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) {
6992 hddLog (VOS_TRACE_LEVEL_ERROR,
6993 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
6994 return -EIO;
6995 }
6996 }
krunal sonie9002db2013-11-25 14:24:17 -08006997 else if(pHddCtx->cfg_ini->isCoalesingInIBSSAllowed == 0)
6998 {
6999 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
7000 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
7001 {
7002 hddLog (VOS_TRACE_LEVEL_ERROR,
7003 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
7004 return -EIO;
7005 }
7006 params->bssid = vos_mem_malloc(sizeof(VOS_MAC_ADDR_SIZE));
7007 if (!params->bssid)
7008 {
7009 hddLog (VOS_TRACE_LEVEL_ERROR,
7010 "%s:Failed memory allocation", __func__);
7011 return -EIO;
7012 }
7013 vos_mem_copy((v_U8_t *)params->bssid,
7014 (v_U8_t *)&pHddCtx->cfg_ini->IbssBssid.bytes[0],
7015 VOS_MAC_ADDR_SIZE);
7016 alloc_bssid = VOS_TRUE;
7017 }
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -07007018
Jeff Johnson295189b2012-06-20 16:38:30 -07007019 /* Set Channel */
Yue Maf49ba872013-08-19 12:04:25 -07007020 if (NULL !=
7021#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
7022 params->chandef.chan)
7023#else
7024 params->channel)
7025#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007026 {
7027 u8 channelNum;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07007028 v_U32_t numChans = WNI_CFG_VALID_CHANNEL_LIST_LEN;
7029 v_U8_t validChan[WNI_CFG_VALID_CHANNEL_LIST_LEN];
7030 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
7031 int indx;
Jeff Johnson295189b2012-06-20 16:38:30 -07007032
7033 /* Get channel number */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307034 channelNum =
Yue Maf49ba872013-08-19 12:04:25 -07007035 ieee80211_frequency_to_channel(
7036#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
7037 params->chandef.chan->center_freq);
7038#else
7039 params->channel->center_freq);
7040#endif
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07007041
7042 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
7043 validChan, &numChans))
Jeff Johnson295189b2012-06-20 16:38:30 -07007044 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07007045 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid channel list",
7046 __func__);
7047 return -EOPNOTSUPP;
Jeff Johnson295189b2012-06-20 16:38:30 -07007048 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07007049
7050 for (indx = 0; indx < numChans; indx++)
Jeff Johnson295189b2012-06-20 16:38:30 -07007051 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07007052 if (channelNum == validChan[indx])
7053 {
7054 break;
7055 }
7056 }
7057 if (indx >= numChans)
7058 {
7059 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Not valid Channel %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07007060 __func__, channelNum);
7061 return -EINVAL;
7062 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07007063 /* Set the Operational Channel */
7064 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: set channel %d", __func__,
7065 channelNum);
7066 pRoamProfile->ChannelInfo.numOfChannels = 1;
7067 pHddStaCtx->conn_info.operationChannel = channelNum;
7068 pRoamProfile->ChannelInfo.ChannelList =
7069 &pHddStaCtx->conn_info.operationChannel;
Jeff Johnson295189b2012-06-20 16:38:30 -07007070 }
7071
7072 /* Initialize security parameters */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307073 status = wlan_hdd_cfg80211_set_privacy_ibss(pAdapter, params);
Jeff Johnson295189b2012-06-20 16:38:30 -07007074 if (status < 0)
7075 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307076 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security parameters",
Jeff Johnson295189b2012-06-20 16:38:30 -07007077 __func__);
7078 return status;
7079 }
7080
7081 /* Issue connect start */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307082 status = wlan_hdd_cfg80211_connect_start(pAdapter, params->ssid,
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07007083 params->ssid_len, params->bssid,
7084 pHddStaCtx->conn_info.operationChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -07007085
7086 if (0 > status)
7087 {
7088 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: connect failed", __func__);
7089 return status;
7090 }
7091
krunal sonie9002db2013-11-25 14:24:17 -08007092 if (NULL != params->bssid &&
7093 pHddCtx->cfg_ini->isCoalesingInIBSSAllowed == 0 &&
7094 alloc_bssid == VOS_TRUE)
7095 {
7096 vos_mem_free(params->bssid);
7097 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007098 return 0;
7099}
7100
7101/*
7102 * FUNCTION: wlan_hdd_cfg80211_leave_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307103 * This function is used to leave an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -07007104 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307105static int wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07007106 struct net_device *dev
7107 )
7108{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307109 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Jeff Johnson295189b2012-06-20 16:38:30 -07007110 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
7111 tCsrRoamProfile *pRoamProfile;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307112 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7113 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07007114
7115 ENTER();
7116
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307117 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7118 TRACE_CODE_HDD_CFG80211_LEAVE_IBSS,
7119 pAdapter->sessionId, eCSR_DISCONNECT_REASON_IBSS_LEAVE));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307120 status = wlan_hdd_validate_context(pHddCtx);
7121
7122 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007123 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307124 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7125 "%s: HDD context is not valid", __func__);
7126 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007127 }
7128
Arif Hussain6d2a3322013-11-17 19:50:10 -08007129 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",__func__,pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07007130 if (NULL == pWextState)
7131 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08007132 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -07007133 __func__);
7134 return -EIO;
7135 }
7136
7137 pRoamProfile = &pWextState->roamProfile;
7138
7139 /* Issue disconnect only if interface type is set to IBSS */
7140 if (eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType)
7141 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307142 hddLog (VOS_TRACE_LEVEL_ERROR, "%s: BSS Type is not set to IBSS",
Jeff Johnson295189b2012-06-20 16:38:30 -07007143 __func__);
7144 return -EINVAL;
7145 }
7146
7147 /* Issue Disconnect request */
7148 INIT_COMPLETION(pAdapter->disconnect_comp_var);
7149 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
7150 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
7151
7152 return 0;
7153}
7154
7155/*
7156 * FUNCTION: wlan_hdd_cfg80211_set_wiphy_params
7157 * This function is used to set the phy parameters
7158 * (RTS Threshold/FRAG Threshold/Retry Count etc ...)
7159 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307160static int wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07007161 u32 changed)
7162{
7163 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
7164 tHalHandle hHal = pHddCtx->hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307165 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07007166
7167 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307168 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7169 TRACE_CODE_HDD_CFG80211_SET_WIPHY_PARAMS,
7170 NO_SESSION, wiphy->rts_threshold));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307171 status = wlan_hdd_validate_context(pHddCtx);
7172
7173 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007174 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307175 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7176 "%s: HDD context is not valid", __func__);
7177 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007178 }
7179
Jeff Johnson295189b2012-06-20 16:38:30 -07007180 if (changed & WIPHY_PARAM_RTS_THRESHOLD)
7181 {
7182 u16 rts_threshold = (wiphy->rts_threshold == -1) ?
7183 WNI_CFG_RTS_THRESHOLD_STAMAX :
7184 wiphy->rts_threshold;
7185
7186 if ((WNI_CFG_RTS_THRESHOLD_STAMIN > rts_threshold) ||
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307187 (WNI_CFG_RTS_THRESHOLD_STAMAX < rts_threshold))
Jeff Johnson295189b2012-06-20 16:38:30 -07007188 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307189 hddLog(VOS_TRACE_LEVEL_ERROR,
7190 "%s: Invalid RTS Threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07007191 __func__, rts_threshold);
7192 return -EINVAL;
7193 }
7194
7195 if (0 != ccmCfgSetInt(hHal, WNI_CFG_RTS_THRESHOLD,
7196 rts_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307197 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -07007198 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307199 hddLog(VOS_TRACE_LEVEL_ERROR,
7200 "%s: ccmCfgSetInt failed for rts_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07007201 __func__, rts_threshold);
7202 return -EIO;
7203 }
7204
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307205 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set rts threshold %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07007206 rts_threshold);
7207 }
7208
7209 if (changed & WIPHY_PARAM_FRAG_THRESHOLD)
7210 {
7211 u16 frag_threshold = (wiphy->frag_threshold == -1) ?
7212 WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX :
7213 wiphy->frag_threshold;
7214
7215 if ((WNI_CFG_FRAGMENTATION_THRESHOLD_STAMIN > frag_threshold)||
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307216 (WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX < frag_threshold) )
Jeff Johnson295189b2012-06-20 16:38:30 -07007217 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307218 hddLog(VOS_TRACE_LEVEL_ERROR,
7219 "%s: Invalid frag_threshold value %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07007220 frag_threshold);
7221 return -EINVAL;
7222 }
7223
7224 if (0 != ccmCfgSetInt(hHal, WNI_CFG_FRAGMENTATION_THRESHOLD,
7225 frag_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307226 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -07007227 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307228 hddLog(VOS_TRACE_LEVEL_ERROR,
7229 "%s: ccmCfgSetInt failed for frag_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07007230 __func__, frag_threshold);
7231 return -EIO;
7232 }
7233
7234 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set frag threshold %hu", __func__,
7235 frag_threshold);
7236 }
7237
7238 if ((changed & WIPHY_PARAM_RETRY_SHORT)
7239 || (changed & WIPHY_PARAM_RETRY_LONG))
7240 {
7241 u8 retry_value = (changed & WIPHY_PARAM_RETRY_SHORT) ?
7242 wiphy->retry_short :
7243 wiphy->retry_long;
7244
7245 if ((WNI_CFG_LONG_RETRY_LIMIT_STAMIN > retry_value) ||
7246 (WNI_CFG_LONG_RETRY_LIMIT_STAMAX < retry_value))
7247 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307248 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07007249 __func__, retry_value);
7250 return -EINVAL;
7251 }
7252
7253 if (changed & WIPHY_PARAM_RETRY_SHORT)
7254 {
7255 if (0 != ccmCfgSetInt(hHal, WNI_CFG_LONG_RETRY_LIMIT,
7256 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307257 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -07007258 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307259 hddLog(VOS_TRACE_LEVEL_ERROR,
7260 "%s: ccmCfgSetInt failed for long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07007261 __func__, retry_value);
7262 return -EIO;
7263 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307264 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07007265 __func__, retry_value);
7266 }
7267 else if (changed & WIPHY_PARAM_RETRY_SHORT)
7268 {
7269 if (0 != ccmCfgSetInt(hHal, WNI_CFG_SHORT_RETRY_LIMIT,
7270 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307271 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -07007272 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307273 hddLog(VOS_TRACE_LEVEL_ERROR,
7274 "%s: ccmCfgSetInt failed for short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07007275 __func__, retry_value);
7276 return -EIO;
7277 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307278 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07007279 __func__, retry_value);
7280 }
7281 }
7282
7283 return 0;
7284}
7285
7286/*
7287 * FUNCTION: wlan_hdd_cfg80211_set_txpower
7288 * This function is used to set the txpower
7289 */
7290static int wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
Yue Maf49ba872013-08-19 12:04:25 -07007291#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
7292 struct wireless_dev *wdev,
7293#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007294#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307295 enum tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -07007296#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307297 enum nl80211_tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -07007298#endif
7299 int dbm)
7300{
7301 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307302 tHalHandle hHal = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07007303 tSirMacAddr bssid = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
7304 tSirMacAddr selfMac = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307305 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07007306
7307 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307308 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7309 TRACE_CODE_HDD_CFG80211_SET_TXPOWER,
7310 NO_SESSION, type ));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307311 status = wlan_hdd_validate_context(pHddCtx);
7312
7313 if (0 != status)
7314 {
7315 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7316 "%s: HDD context is not valid", __func__);
7317 return status;
7318 }
7319
7320 hHal = pHddCtx->hHal;
7321
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307322 if (0 != ccmCfgSetInt(hHal, WNI_CFG_CURRENT_TX_POWER_LEVEL,
7323 dbm, ccmCfgSetCallback,
7324 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -07007325 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307326 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07007327 "%s: ccmCfgSetInt failed for tx power %hu", __func__, dbm);
7328 return -EIO;
7329 }
7330
7331 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set tx power level %d dbm", __func__,
7332 dbm);
7333
7334 switch(type)
7335 {
7336 case NL80211_TX_POWER_AUTOMATIC: /*automatically determine transmit power*/
7337 /* Fall through */
7338 case NL80211_TX_POWER_LIMITED: /*limit TX power by the mBm parameter*/
7339 if( sme_SetMaxTxPower(hHal, bssid, selfMac, dbm) != eHAL_STATUS_SUCCESS )
7340 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307341 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Setting maximum tx power failed",
7342 __func__);
7343 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -07007344 }
7345 break;
7346 case NL80211_TX_POWER_FIXED: /*fix TX power to the mBm parameter*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307347 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: NL80211_TX_POWER_FIXED not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -07007348 __func__);
7349 return -EOPNOTSUPP;
7350 break;
7351 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307352 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid power setting type %d",
7353 __func__, type);
Jeff Johnson295189b2012-06-20 16:38:30 -07007354 return -EIO;
7355 }
7356
7357 return 0;
7358}
7359
7360/*
7361 * FUNCTION: wlan_hdd_cfg80211_get_txpower
7362 * This function is used to read the txpower
7363 */
Yue Maf49ba872013-08-19 12:04:25 -07007364static int wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy,
7365#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
7366 struct wireless_dev *wdev,
7367#endif
7368 int *dbm)
Jeff Johnson295189b2012-06-20 16:38:30 -07007369{
7370
7371 hdd_adapter_t *pAdapter;
7372 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307373 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07007374
Jeff Johnsone7245742012-09-05 17:12:55 -07007375 ENTER();
7376
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307377 status = wlan_hdd_validate_context(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07007378
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307379 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007380 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307381 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7382 "%s: HDD context is not valid", __func__);
7383 *dbm = 0;
7384 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007385 }
7386
Jeff Johnson295189b2012-06-20 16:38:30 -07007387 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
7388 if (NULL == pAdapter)
7389 {
7390 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Not in station context " ,__func__);
7391 return -ENOENT;
7392 }
7393
7394 wlan_hdd_get_classAstats(pAdapter);
7395 *dbm = pAdapter->hdd_stats.ClassA_stat.max_pwr;
7396
Jeff Johnsone7245742012-09-05 17:12:55 -07007397 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07007398 return 0;
7399}
7400
7401static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
7402 u8* mac, struct station_info *sinfo)
7403{
7404 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
7405 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7406 int ssidlen = pHddStaCtx->conn_info.SSID.SSID.length;
7407 tANI_U8 rate_flags;
7408
7409 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
7410 hdd_config_t *pCfg = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -07007411
7412 tANI_U8 OperationalRates[CSR_DOT11_SUPPORTED_RATES_MAX];
7413 tANI_U32 ORLeng = CSR_DOT11_SUPPORTED_RATES_MAX;
7414 tANI_U8 ExtendedRates[CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX];
7415 tANI_U32 ERLeng = CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX;
7416 tANI_U8 MCSRates[SIZE_OF_BASIC_MCS_SET];
7417 tANI_U32 MCSLeng = SIZE_OF_BASIC_MCS_SET;
7418 tANI_U16 maxRate = 0;
7419 tANI_U16 myRate;
7420 tANI_U16 currentRate = 0;
7421 tANI_U8 maxSpeedMCS = 0;
7422 tANI_U8 maxMCSIdx = 0;
7423 tANI_U8 rateFlag = 1;
7424 tANI_U8 i, j, rssidx;
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07007425 tANI_U16 temp;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307426 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07007427
Leo Chang6f8870f2013-03-26 18:11:36 -07007428#ifdef WLAN_FEATURE_11AC
7429 tANI_U32 vht_mcs_map;
7430 eDataRate11ACMaxMcs vhtMaxMcs;
7431#endif /* WLAN_FEATURE_11AC */
7432
Jeff Johnsone7245742012-09-05 17:12:55 -07007433 ENTER();
7434
Jeff Johnson295189b2012-06-20 16:38:30 -07007435 if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) ||
7436 (0 == ssidlen))
7437 {
7438 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Not associated or"
7439 " Invalid ssidlen, %d", __func__, ssidlen);
7440 /*To keep GUI happy*/
7441 return 0;
7442 }
7443
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307444 status = wlan_hdd_validate_context(pHddCtx);
7445
7446 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007447 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307448 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7449 "%s: HDD context is not valid", __func__);
7450 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007451 }
7452
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -07007453 wlan_hdd_get_station_stats(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07007454 rate_flags = pAdapter->hdd_stats.ClassA_stat.tx_rate_flags;
7455
Kiet Lam3b17fc82013-09-27 05:24:08 +05307456 wlan_hdd_get_rssi(pAdapter, &sinfo->signal);
7457 sinfo->filled |= STATION_INFO_SIGNAL;
7458
Jeff Johnson295189b2012-06-20 16:38:30 -07007459 //convert to the UI units of 100kbps
7460 myRate = pAdapter->hdd_stats.ClassA_stat.tx_rate * 5;
7461
7462#ifdef LINKSPEED_DEBUG_ENABLED
Leo Chang6f8870f2013-03-26 18:11:36 -07007463 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 -07007464 sinfo->signal,
7465 pCfg->reportMaxLinkSpeed,
7466 myRate,
7467 (int) pCfg->linkSpeedRssiHigh,
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07007468 (int) pCfg->linkSpeedRssiMid,
7469 (int) pCfg->linkSpeedRssiLow,
Leo Chang6f8870f2013-03-26 18:11:36 -07007470 (int) rate_flags,
7471 (int) pAdapter->hdd_stats.ClassA_stat.mcs_index);
Jeff Johnson295189b2012-06-20 16:38:30 -07007472#endif //LINKSPEED_DEBUG_ENABLED
7473
7474 if (eHDD_LINK_SPEED_REPORT_ACTUAL != pCfg->reportMaxLinkSpeed)
7475 {
7476 // we do not want to necessarily report the current speed
7477 if (eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed)
7478 {
7479 // report the max possible speed
7480 rssidx = 0;
7481 }
7482 else if (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed)
7483 {
7484 // report the max possible speed with RSSI scaling
7485 if (sinfo->signal >= pCfg->linkSpeedRssiHigh)
7486 {
7487 // report the max possible speed
7488 rssidx = 0;
7489 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07007490 else if (sinfo->signal >= pCfg->linkSpeedRssiMid)
Jeff Johnson295189b2012-06-20 16:38:30 -07007491 {
7492 // report middle speed
7493 rssidx = 1;
7494 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07007495 else if (sinfo->signal >= pCfg->linkSpeedRssiLow)
7496 {
7497 // report middle speed
7498 rssidx = 2;
7499 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007500 else
7501 {
7502 // report actual speed
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07007503 rssidx = 3;
Jeff Johnson295189b2012-06-20 16:38:30 -07007504 }
7505 }
7506 else
7507 {
7508 // unknown, treat as eHDD_LINK_SPEED_REPORT_MAX
7509 hddLog(VOS_TRACE_LEVEL_ERROR,
7510 "%s: Invalid value for reportMaxLinkSpeed: %u",
7511 __func__, pCfg->reportMaxLinkSpeed);
7512 rssidx = 0;
7513 }
7514
7515 maxRate = 0;
7516
7517 /* Get Basic Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +05307518 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_OPERATIONAL_RATE_SET,
7519 OperationalRates, &ORLeng))
7520 {
7521 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
7522 /*To keep GUI happy*/
7523 return 0;
7524 }
7525
Jeff Johnson295189b2012-06-20 16:38:30 -07007526 for (i = 0; i < ORLeng; i++)
7527 {
Jeff Johnsone7245742012-09-05 17:12:55 -07007528 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -07007529 {
7530 /* Validate Rate Set */
7531 if (supported_data_rate[j].beacon_rate_index == (OperationalRates[i] & 0x7F))
7532 {
7533 currentRate = supported_data_rate[j].supported_rate[rssidx];
7534 break;
7535 }
7536 }
7537 /* Update MAX rate */
7538 maxRate = (currentRate > maxRate)?currentRate:maxRate;
7539 }
7540
7541 /* Get Extended Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +05307542 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET,
7543 ExtendedRates, &ERLeng))
7544 {
7545 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
7546 /*To keep GUI happy*/
7547 return 0;
7548 }
7549
Jeff Johnson295189b2012-06-20 16:38:30 -07007550 for (i = 0; i < ERLeng; i++)
7551 {
Jeff Johnsone7245742012-09-05 17:12:55 -07007552 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -07007553 {
7554 if (supported_data_rate[j].beacon_rate_index == (ExtendedRates[i] & 0x7F))
7555 {
7556 currentRate = supported_data_rate[j].supported_rate[rssidx];
7557 break;
7558 }
7559 }
7560 /* Update MAX rate */
7561 maxRate = (currentRate > maxRate)?currentRate:maxRate;
7562 }
Kiet Lamb69f8dc2013-11-15 15:34:27 +05307563 /* Get MCS Rate Set --
Kaushik, Sushantdc304d82014-01-22 10:58:37 +05307564 Only if we are always reporting max speed (or)
Kiet Lamb69f8dc2013-11-15 15:34:27 +05307565 if we have good rssi */
Kaushik, Sushantdc304d82014-01-22 10:58:37 +05307566 if ((0 == rssidx) ||
Kiet Lamb69f8dc2013-11-15 15:34:27 +05307567 (eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed))
Jeff Johnson295189b2012-06-20 16:38:30 -07007568 {
Gopichand Nakkala05ab1322013-02-15 11:28:38 +05307569 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_CURRENT_MCS_SET,
7570 MCSRates, &MCSLeng))
7571 {
7572 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
7573 /*To keep GUI happy*/
7574 return 0;
7575 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007576 rateFlag = 0;
Leo Chang6f8870f2013-03-26 18:11:36 -07007577#ifdef WLAN_FEATURE_11AC
7578 /* VHT80 rate has seperate rate table */
Gopichand Nakkala4c705372013-04-24 13:20:33 +05307579 if (rate_flags & (eHAL_TX_RATE_VHT20|eHAL_TX_RATE_VHT40|eHAL_TX_RATE_VHT80))
Jeff Johnson295189b2012-06-20 16:38:30 -07007580 {
Leo Chang6f8870f2013-03-26 18:11:36 -07007581 ccmCfgGetInt(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_VHT_TX_MCS_MAP, &vht_mcs_map);
Gopichand Nakkala4c705372013-04-24 13:20:33 +05307582 vhtMaxMcs = (eDataRate11ACMaxMcs)(vht_mcs_map & DATA_RATE_11AC_MCS_MASK );
Leo Chang6f8870f2013-03-26 18:11:36 -07007583 if (rate_flags & eHAL_TX_RATE_SGI)
Jeff Johnson295189b2012-06-20 16:38:30 -07007584 {
Leo Chang6f8870f2013-03-26 18:11:36 -07007585 rateFlag |= 1;
Jeff Johnson295189b2012-06-20 16:38:30 -07007586 }
Leo Chang6f8870f2013-03-26 18:11:36 -07007587 if (DATA_RATE_11AC_MAX_MCS_7 == vhtMaxMcs)
Jeff Johnson295189b2012-06-20 16:38:30 -07007588 {
Leo Chang6f8870f2013-03-26 18:11:36 -07007589 maxMCSIdx = 7;
7590 }
7591 else if (DATA_RATE_11AC_MAX_MCS_8 == vhtMaxMcs)
7592 {
7593 maxMCSIdx = 8;
7594 }
7595 else if (DATA_RATE_11AC_MAX_MCS_9 == vhtMaxMcs)
7596 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +05307597 //VHT20 is supporting 0~8
7598 if (rate_flags & eHAL_TX_RATE_VHT20)
7599 maxMCSIdx = 8;
7600 else
7601 maxMCSIdx = 9;
Leo Chang6f8870f2013-03-26 18:11:36 -07007602 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +05307603
7604 if (rate_flags & eHAL_TX_RATE_VHT80)
7605 {
7606 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT80_rate[rateFlag];
7607 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT80_rate[rateFlag];
7608 }
7609 else if (rate_flags & eHAL_TX_RATE_VHT40)
7610 {
7611 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT40_rate[rateFlag];
7612 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT40_rate[rateFlag];
7613 }
7614 else if (rate_flags & eHAL_TX_RATE_VHT20)
7615 {
7616 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT20_rate[rateFlag];
7617 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT20_rate[rateFlag];
7618 }
7619
Leo Chang6f8870f2013-03-26 18:11:36 -07007620 maxSpeedMCS = 1;
7621 if (currentRate > maxRate)
7622 {
7623 maxRate = currentRate;
7624 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +05307625
Leo Chang6f8870f2013-03-26 18:11:36 -07007626 }
7627 else
7628#endif /* WLAN_FEATURE_11AC */
7629 {
7630 if (rate_flags & eHAL_TX_RATE_HT40)
7631 {
7632 rateFlag |= 1;
7633 }
7634 if (rate_flags & eHAL_TX_RATE_SGI)
7635 {
7636 rateFlag |= 2;
7637 }
7638
7639 for (i = 0; i < MCSLeng; i++)
7640 {
7641 temp = sizeof(supported_mcs_rate) / sizeof(supported_mcs_rate[0]);
7642 for (j = 0; j < temp; j++)
7643 {
7644 if (supported_mcs_rate[j].beacon_rate_index == MCSRates[i])
7645 {
7646 currentRate = supported_mcs_rate[j].supported_rate[rateFlag];
7647 break;
7648 }
7649 }
7650 if ((j < temp) && (currentRate > maxRate))
7651 {
7652 maxRate = currentRate;
7653 maxSpeedMCS = 1;
7654 maxMCSIdx = supported_mcs_rate[j].beacon_rate_index;
7655 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007656 }
7657 }
7658 }
7659
Gopichand Nakkala4c705372013-04-24 13:20:33 +05307660 else if (!(rate_flags & eHAL_TX_RATE_LEGACY))
7661 {
7662 maxRate = myRate;
7663 maxSpeedMCS = 1;
7664 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
7665 }
7666
Jeff Johnson295189b2012-06-20 16:38:30 -07007667 // make sure we report a value at least as big as our current rate
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07007668 if (((maxRate < myRate) && (0 == rssidx)) ||
7669 (0 == maxRate))
Jeff Johnson295189b2012-06-20 16:38:30 -07007670 {
7671 maxRate = myRate;
7672 if (rate_flags & eHAL_TX_RATE_LEGACY)
7673 {
7674 maxSpeedMCS = 0;
7675 }
7676 else
7677 {
7678 maxSpeedMCS = 1;
7679 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
7680 }
7681 }
7682
Gopichand Nakkala4c705372013-04-24 13:20:33 +05307683 if (rate_flags & eHAL_TX_RATE_LEGACY)
Jeff Johnson295189b2012-06-20 16:38:30 -07007684 {
7685 sinfo->txrate.legacy = maxRate;
7686#ifdef LINKSPEED_DEBUG_ENABLED
7687 pr_info("Reporting legacy rate %d\n", sinfo->txrate.legacy);
7688#endif //LINKSPEED_DEBUG_ENABLED
7689 }
7690 else
7691 {
7692 sinfo->txrate.mcs = maxMCSIdx;
Leo Chang6f8870f2013-03-26 18:11:36 -07007693#ifdef WLAN_FEATURE_11AC
7694 sinfo->txrate.nss = 1;
7695 if (rate_flags & eHAL_TX_RATE_VHT80)
7696 {
7697 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
Gopichand Nakkala4c705372013-04-24 13:20:33 +05307698 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
Leo Chang6f8870f2013-03-26 18:11:36 -07007699 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +05307700 else if (rate_flags & eHAL_TX_RATE_VHT40)
Leo Chang6f8870f2013-03-26 18:11:36 -07007701 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +05307702 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
7703 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
7704 }
7705 else if (rate_flags & eHAL_TX_RATE_VHT20)
7706 {
7707 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
7708 }
7709#endif /* WLAN_FEATURE_11AC */
7710 if (rate_flags & (eHAL_TX_RATE_HT20 | eHAL_TX_RATE_HT40))
7711 {
7712 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
7713 if (rate_flags & eHAL_TX_RATE_HT40)
7714 {
7715 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
7716 }
Leo Chang6f8870f2013-03-26 18:11:36 -07007717 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007718 if (rate_flags & eHAL_TX_RATE_SGI)
7719 {
7720 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
7721 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +05307722
Jeff Johnson295189b2012-06-20 16:38:30 -07007723#ifdef LINKSPEED_DEBUG_ENABLED
7724 pr_info("Reporting MCS rate %d flags %x\n",
7725 sinfo->txrate.mcs,
7726 sinfo->txrate.flags );
7727#endif //LINKSPEED_DEBUG_ENABLED
7728 }
7729 }
7730 else
7731 {
7732 // report current rate instead of max rate
7733
7734 if (rate_flags & eHAL_TX_RATE_LEGACY)
7735 {
7736 //provide to the UI in units of 100kbps
7737 sinfo->txrate.legacy = myRate;
7738#ifdef LINKSPEED_DEBUG_ENABLED
7739 pr_info("Reporting actual legacy rate %d\n", sinfo->txrate.legacy);
7740#endif //LINKSPEED_DEBUG_ENABLED
7741 }
7742 else
7743 {
7744 //must be MCS
7745 sinfo->txrate.mcs = pAdapter->hdd_stats.ClassA_stat.mcs_index;
Leo Chang6f8870f2013-03-26 18:11:36 -07007746#ifdef WLAN_FEATURE_11AC
7747 sinfo->txrate.nss = 1;
7748 if (rate_flags & eHAL_TX_RATE_VHT80)
7749 {
7750 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
7751 }
7752 else
7753#endif /* WLAN_FEATURE_11AC */
7754 {
7755 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
7756 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007757 if (rate_flags & eHAL_TX_RATE_SGI)
7758 {
7759 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
7760 }
7761 if (rate_flags & eHAL_TX_RATE_HT40)
7762 {
7763 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
7764 }
Leo Chang6f8870f2013-03-26 18:11:36 -07007765#ifdef WLAN_FEATURE_11AC
7766 else if (rate_flags & eHAL_TX_RATE_VHT80)
7767 {
7768 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
7769 }
7770#endif /* WLAN_FEATURE_11AC */
Jeff Johnson295189b2012-06-20 16:38:30 -07007771#ifdef LINKSPEED_DEBUG_ENABLED
7772 pr_info("Reporting actual MCS rate %d flags %x\n",
7773 sinfo->txrate.mcs,
7774 sinfo->txrate.flags );
7775#endif //LINKSPEED_DEBUG_ENABLED
7776 }
7777 }
7778 sinfo->filled |= STATION_INFO_TX_BITRATE;
7779
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -07007780 sinfo->tx_packets =
7781 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[0] +
7782 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[1] +
7783 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[2] +
7784 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[3];
7785
7786 sinfo->tx_retries =
7787 pAdapter->hdd_stats.summary_stat.retry_cnt[0] +
7788 pAdapter->hdd_stats.summary_stat.retry_cnt[1] +
7789 pAdapter->hdd_stats.summary_stat.retry_cnt[2] +
7790 pAdapter->hdd_stats.summary_stat.retry_cnt[3];
7791
7792 sinfo->tx_failed =
7793 pAdapter->hdd_stats.summary_stat.fail_cnt[0] +
7794 pAdapter->hdd_stats.summary_stat.fail_cnt[1] +
7795 pAdapter->hdd_stats.summary_stat.fail_cnt[2] +
7796 pAdapter->hdd_stats.summary_stat.fail_cnt[3];
7797
7798 sinfo->filled |=
7799 STATION_INFO_TX_PACKETS |
7800 STATION_INFO_TX_RETRIES |
7801 STATION_INFO_TX_FAILED;
7802
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307803 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7804 TRACE_CODE_HDD_CFG80211_GET_STA,
7805 pAdapter->sessionId, maxRate));
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -07007806 EXIT();
7807 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07007808}
7809
7810static int wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
Sameer Thalappilc9f26e92013-06-07 10:11:06 -07007811 struct net_device *dev, bool mode, int timeout)
Jeff Johnson295189b2012-06-20 16:38:30 -07007812{
7813 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +05307814 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07007815 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307816 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07007817
Jeff Johnsone7245742012-09-05 17:12:55 -07007818 ENTER();
7819
Jeff Johnson295189b2012-06-20 16:38:30 -07007820 if (NULL == pAdapter)
7821 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08007822 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007823 return -ENODEV;
7824 }
7825
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307826 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7827 TRACE_CODE_HDD_CFG80211_SET_POWER_MGMT,
7828 pAdapter->sessionId, timeout));
7829
Gopichand Nakkala20c4c042013-04-19 22:08:55 +05307830 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307831 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +05307832
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307833 if (0 != status)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307834 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307835 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7836 "%s: HDD context is not valid", __func__);
7837 return status;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307838 }
7839
Gopichand Nakkala20c4c042013-04-19 22:08:55 +05307840 if ((DRIVER_POWER_MODE_AUTO == !mode) &&
7841 (TRUE == pHddCtx->hdd_wlan_suspended) &&
7842 (pHddCtx->cfg_ini->fhostArpOffload) &&
7843 (eConnectionState_Associated ==
7844 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
7845 {
Amar Singhald53568e2013-09-26 11:03:45 -07007846
7847 hddLog(VOS_TRACE_LEVEL_INFO,
7848 "offload: in cfg80211_set_power_mgmt, calling arp offload");
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05307849 vos_status = hdd_conf_arp_offload(pAdapter, TRUE);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +05307850 if (!VOS_IS_STATUS_SUCCESS(vos_status))
7851 {
7852 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007853 "%s:Failed to enable ARPOFFLOAD Feature %d",
Gopichand Nakkala20c4c042013-04-19 22:08:55 +05307854 __func__, vos_status);
7855 }
7856 }
7857
Jeff Johnson295189b2012-06-20 16:38:30 -07007858 /**The get power cmd from the supplicant gets updated by the nl only
7859 *on successful execution of the function call
7860 *we are oppositely mapped w.r.t mode in the driver
7861 **/
7862 vos_status = wlan_hdd_enter_bmps(pAdapter, !mode);
7863
Jeff Johnsone7245742012-09-05 17:12:55 -07007864 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07007865 if (VOS_STATUS_E_FAILURE == vos_status)
7866 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307867 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7868 "%s: failed to enter bmps mode", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007869 return -EINVAL;
7870 }
7871 return 0;
7872}
7873
7874
7875#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
7876static int wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
7877 struct net_device *netdev,
7878 u8 key_index)
7879{
Jeff Johnsone7245742012-09-05 17:12:55 -07007880 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07007881 return 0;
7882}
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307883#endif //LINUX_VERSION_CODE
Jeff Johnson295189b2012-06-20 16:38:30 -07007884
7885#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
7886static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
7887 struct net_device *dev,
7888 struct ieee80211_txq_params *params)
7889{
Jeff Johnsone7245742012-09-05 17:12:55 -07007890 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07007891 return 0;
7892}
7893#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
7894static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
7895 struct ieee80211_txq_params *params)
7896{
Jeff Johnsone7245742012-09-05 17:12:55 -07007897 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07007898 return 0;
7899}
7900#endif //LINUX_VERSION_CODE
7901
7902static int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
7903 struct net_device *dev, u8 *mac)
7904{
7905 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307906 hdd_context_t *pHddCtx;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08007907 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307908 int status;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08007909 v_U8_t staId;
Jeff Johnson295189b2012-06-20 16:38:30 -07007910
Jeff Johnsone7245742012-09-05 17:12:55 -07007911 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307912
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307913 if ( NULL == pAdapter )
Jeff Johnson295189b2012-06-20 16:38:30 -07007914 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307915 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007916 return -EINVAL;
7917 }
7918
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307919 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7920 TRACE_CODE_HDD_CFG80211_DEL_STA,
7921 pAdapter->sessionId, pAdapter->device_mode));
7922
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307923 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7924 status = wlan_hdd_validate_context(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07007925
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307926 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007927 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307928 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7929 "%s: HDD context is not valid", __func__);
7930 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007931 }
7932
Jeff Johnson295189b2012-06-20 16:38:30 -07007933 if ( (WLAN_HDD_SOFTAP == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -07007934 || (WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -07007935 )
7936 {
7937 if( NULL == mac )
7938 {
7939 v_U16_t i;
7940 for(i = 0; i < WLAN_MAX_STA_COUNT; i++)
7941 {
Rajesh Chauhan18488fc2013-08-22 10:15:03 -07007942 if ((pAdapter->aStaInfo[i].isUsed) &&
7943 (!pAdapter->aStaInfo[i].isDeauthInProgress))
Jeff Johnson295189b2012-06-20 16:38:30 -07007944 {
7945 u8 *macAddr = pAdapter->aStaInfo[i].macAddrSTA.bytes;
7946 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -08007947 "%s: Delete STA with MAC::"
7948 MAC_ADDRESS_STR,
7949 __func__, MAC_ADDR_ARRAY(macAddr));
Rajesh Chauhan18488fc2013-08-22 10:15:03 -07007950 vos_status = hdd_softap_sta_deauth(pAdapter, macAddr);
7951 if (VOS_IS_STATUS_SUCCESS(vos_status))
7952 pAdapter->aStaInfo[i].isDeauthInProgress = TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -07007953 }
7954 }
7955 }
7956 else
7957 {
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08007958
7959 vos_status = hdd_softap_GetStaId(pAdapter,(v_MACADDR_t *)mac, &staId);
7960 if (!VOS_IS_STATUS_SUCCESS(vos_status))
7961 {
7962 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -08007963 "%s: Skip this DEL STA as this is not used::"
7964 MAC_ADDRESS_STR,
7965 __func__, MAC_ADDR_ARRAY(mac));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08007966 return -ENOENT;
7967 }
7968
7969 if( pAdapter->aStaInfo[staId].isDeauthInProgress == TRUE)
7970 {
7971 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -08007972 "%s: Skip this DEL STA as deauth is in progress::"
7973 MAC_ADDRESS_STR,
7974 __func__, MAC_ADDR_ARRAY(mac));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08007975 return -ENOENT;
7976 }
7977
7978 pAdapter->aStaInfo[staId].isDeauthInProgress = TRUE;
7979
Jeff Johnson295189b2012-06-20 16:38:30 -07007980 hddLog(VOS_TRACE_LEVEL_INFO,
7981 "%s: Delete STA with MAC::"
Arif Hussain24bafea2013-11-15 15:10:03 -08007982 MAC_ADDRESS_STR,
Jeff Johnson295189b2012-06-20 16:38:30 -07007983 __func__,
Arif Hussain24bafea2013-11-15 15:10:03 -08007984 MAC_ADDR_ARRAY(mac));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08007985
7986 vos_status = hdd_softap_sta_deauth(pAdapter, mac);
7987 if (!VOS_IS_STATUS_SUCCESS(vos_status))
7988 {
7989 pAdapter->aStaInfo[staId].isDeauthInProgress = FALSE;
7990 hddLog(VOS_TRACE_LEVEL_INFO,
7991 "%s: STA removal failed for ::"
Arif Hussain24bafea2013-11-15 15:10:03 -08007992 MAC_ADDRESS_STR,
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08007993 __func__,
Arif Hussain24bafea2013-11-15 15:10:03 -08007994 MAC_ADDR_ARRAY(mac));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08007995 return -ENOENT;
7996 }
7997
Jeff Johnson295189b2012-06-20 16:38:30 -07007998 }
7999 }
8000
8001 EXIT();
8002
8003 return 0;
8004}
8005
Hoonki Lee11f7dda2013-02-14 16:55:44 -08008006static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
8007 struct net_device *dev, u8 *mac, struct station_parameters *params)
8008{
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308009 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkalab977a972013-02-18 19:15:09 -08008010 int status = -EPERM;
Hoonki Lee11f7dda2013-02-14 16:55:44 -08008011#ifdef FEATURE_WLAN_TDLS
8012 u32 mask, set;
Hoonki Lee11f7dda2013-02-14 16:55:44 -08008013 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308014
8015 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
8016 TRACE_CODE_HDD_CFG80211_ADD_STA,
8017 pAdapter->sessionId, params->listen_interval));
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008018 mask = params->sta_flags_mask;
8019
8020 set = params->sta_flags_set;
8021
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07008022#ifdef WLAN_FEATURE_TDLS_DEBUG
8023 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8024 "%s: mask 0x%x set 0x%x " MAC_ADDRESS_STR,
8025 __func__, mask, set, MAC_ADDR_ARRAY(mac));
8026#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008027
8028 if (mask & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
8029 if (set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008030 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 0, NULL);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008031 }
8032 }
8033#endif
Gopichand Nakkalab977a972013-02-18 19:15:09 -08008034 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -07008035}
8036
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008037
8038#ifdef FEATURE_WLAN_LFR
Wilson Yang6507c4e2013-10-01 20:11:19 -07008039#define MAX_PMKSAIDS_IN_CACHE 8
8040
8041static tPmkidCacheInfo PMKIDCache[MAX_PMKSAIDS_IN_CACHE]; // HDD local cache
8042static tANI_U32 PMKIDCacheIndex; // HDD local Cache index
8043
8044
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008045static int wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
Jeff Johnsond13512a2012-07-17 11:42:19 -07008046 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008047{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308048 tANI_U32 j=0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008049 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
8050 tHalHandle halHandle;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308051 eHalStatus result;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308052 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008053 tANI_U8 BSSIDMatched = 0;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308054 hdd_context_t *pHddCtx;
Jeff Johnson0299d0a2013-10-30 12:37:43 -07008055 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: set PMKSA for " MAC_ADDRESS_STR,
8056 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
Jeff Johnsone7245742012-09-05 17:12:55 -07008057
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308058 // Validate pAdapter
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308059 if ( NULL == pAdapter )
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008060 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308061 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008062 return -EINVAL;
8063 }
8064
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308065 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8066 status = wlan_hdd_validate_context(pHddCtx);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008067
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308068 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008069 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308070 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8071 "%s: HDD context is not valid", __func__);
8072 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008073 }
8074
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308075 // Retrieve halHandle
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008076 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
8077
Wilson Yang6507c4e2013-10-01 20:11:19 -07008078 for (j = 0; j < PMKIDCacheIndex; j++)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008079 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308080 if(vos_mem_compare(PMKIDCache[j].BSSID,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008081 pmksa->bssid, WNI_CFG_BSSID_LEN))
8082 {
8083 /* BSSID matched previous entry. Overwrite it. */
8084 BSSIDMatched = 1;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308085 vos_mem_copy(PMKIDCache[j].BSSID,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008086 pmksa->bssid, WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308087 vos_mem_copy(PMKIDCache[j].PMKID,
8088 pmksa->pmkid,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008089 CSR_RSN_PMKID_SIZE);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308090 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Reusing cache entry %d.",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008091 __func__, j );
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008092 dump_bssid(pmksa->bssid);
8093 dump_pmkid(halHandle, pmksa->pmkid);
8094 break;
8095 }
8096 }
8097
Madan Mohan Koyyalamudic4b317d2012-10-18 19:43:08 -07008098 /* Check we compared all entries,if then take the first slot now */
Wilson Yang6507c4e2013-10-01 20:11:19 -07008099 if(j == MAX_PMKSAIDS_IN_CACHE) PMKIDCacheIndex=0;
Madan Mohan Koyyalamudic4b317d2012-10-18 19:43:08 -07008100
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008101 if (!BSSIDMatched)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308102 {
8103 // Now, we DON'T have a BSSID match, so take a new entry in the cache.
Wilson Yang6507c4e2013-10-01 20:11:19 -07008104 vos_mem_copy(PMKIDCache[PMKIDCacheIndex].BSSID,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308105 pmksa->bssid, ETHER_ADDR_LEN);
Wilson Yang6507c4e2013-10-01 20:11:19 -07008106 vos_mem_copy(PMKIDCache[PMKIDCacheIndex].PMKID,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308107 pmksa->pmkid,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008108 CSR_RSN_PMKID_SIZE);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308109 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Adding a new cache entry %d.",
Wilson Yang6507c4e2013-10-01 20:11:19 -07008110 __func__, PMKIDCacheIndex );
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008111 dump_bssid(pmksa->bssid);
8112 dump_pmkid(halHandle, pmksa->pmkid);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308113 // Increment the HDD Local Cache index
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008114 // The "i=0" doesn't work for the call to sme_RoamSetPMKIDCache() - LFR FIXME
Wilson Yang6507c4e2013-10-01 20:11:19 -07008115 if (PMKIDCacheIndex <= (MAX_PMKSAIDS_IN_CACHE-1)) PMKIDCacheIndex++; else PMKIDCacheIndex = 0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008116 }
8117
8118
8119 // Calling csrRoamSetPMKIDCache to configure the PMKIDs into the cache
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308120 //hddLog(LOG1, FL("%s: Calling csrRoamSetPMKIDCache with %d cache entries."),
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008121 // __func__, i );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308122 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Calling csrRoamSetPMKIDCache with %d cache entries.",
Wilson Yang6507c4e2013-10-01 20:11:19 -07008123 __func__, PMKIDCacheIndex );
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008124 // Finally set the PMKSA ID Cache in CSR
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308125 result = sme_RoamSetPMKIDCache(halHandle,pAdapter->sessionId,
8126 PMKIDCache,
Wilson Yang6507c4e2013-10-01 20:11:19 -07008127 PMKIDCacheIndex);
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308128 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
8129 TRACE_CODE_HDD_CFG80211_SET_PMKSA,
8130 pAdapter->sessionId, result));
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008131 return 0;
8132}
8133
8134
Wilson Yang6507c4e2013-10-01 20:11:19 -07008135
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008136static int wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
Wilson Yang6507c4e2013-10-01 20:11:19 -07008137 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008138{
Wilson Yang6507c4e2013-10-01 20:11:19 -07008139 tANI_U32 j=0;
8140 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
8141 tHalHandle halHandle;
Wilson Yang6507c4e2013-10-01 20:11:19 -07008142 tANI_U8 BSSIDMatched = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -07008143 hdd_context_t *pHddCtx;
Wilson Yangef657d32014-01-15 19:19:23 -08008144 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -07008145
Jeff Johnson0299d0a2013-10-30 12:37:43 -07008146 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: deleting PMKSA for " MAC_ADDRESS_STR,
8147 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
Wilson Yang6507c4e2013-10-01 20:11:19 -07008148
8149 /* Validate pAdapter */
8150 if (NULL == pAdapter)
8151 {
8152 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
8153 return -EINVAL;
8154 }
8155
8156 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8157 status = wlan_hdd_validate_context(pHddCtx);
8158
8159 if (0 != status)
8160 {
8161 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8162 "%s: HDD context is not valid", __func__);
8163 return status;
8164 }
8165
8166 /*Retrieve halHandle*/
8167 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
8168
8169 /*in case index is 0,no entry to delete*/
8170 if (0 == PMKIDCacheIndex)
8171 {
8172 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid entry to delete" ,
8173 __func__);
8174 return -EINVAL;
8175 }
8176
8177 /*find the matching PMKSA entry from j=0 to (index-1),
8178 * and delete the matched one
8179 */
8180 for (j = 0; j<PMKIDCacheIndex; j++)
8181 {
8182 if (vos_mem_compare(PMKIDCache[j].BSSID,
8183 pmksa->bssid,
8184 WNI_CFG_BSSID_LEN))
8185 {
8186 /* BSSID matched entry */
8187 BSSIDMatched = 1;
8188
8189 if (j<PMKIDCacheIndex-1)
8190 {
8191 /*replace the matching entry with the last entry in HDD local cache*/
8192 vos_mem_copy(PMKIDCache[j].BSSID,
8193 PMKIDCache[PMKIDCacheIndex-1].BSSID,
8194 WNI_CFG_BSSID_LEN);
8195 vos_mem_copy(PMKIDCache[j].PMKID,
8196 PMKIDCache[PMKIDCacheIndex-1].PMKID,
8197 CSR_RSN_PMKID_SIZE);
8198 }
8199
8200 /*clear the last entry in HDD cache ---[index-1]*/
Wilson Yang6507c4e2013-10-01 20:11:19 -07008201 vos_mem_zero(PMKIDCache[PMKIDCacheIndex-1].BSSID, WNI_CFG_BSSID_LEN);
8202 vos_mem_zero(PMKIDCache[PMKIDCacheIndex-1].PMKID, CSR_RSN_PMKID_SIZE);
8203
8204 /*reduce the PMKID array index*/
8205 PMKIDCacheIndex--;
8206
8207 /*delete the last PMKID cache in CSR*/
Wilson Yangef657d32014-01-15 19:19:23 -08008208 if (eHAL_STATUS_SUCCESS !=
8209 sme_RoamDelPMKIDfromCache(halHandle, pAdapter->sessionId, pmksa->bssid))
Wilson Yang6507c4e2013-10-01 20:11:19 -07008210 {
8211 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: cannot delete PMKSA %d CONTENT.",
8212 __func__,PMKIDCacheIndex);
Wilson Yangef657d32014-01-15 19:19:23 -08008213 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -07008214 }
8215
8216 dump_bssid(pmksa->bssid);
8217 dump_pmkid(halHandle,pmksa->pmkid);
8218
8219 break;
8220 }
8221 }
8222
8223 /* we compare all entries,but cannot find matching entry */
8224 if (j == MAX_PMKSAIDS_IN_CACHE && !BSSIDMatched)
8225 {
Jeff Johnson0299d0a2013-10-30 12:37:43 -07008226 hddLog(VOS_TRACE_LEVEL_FATAL,
8227 "%s: No such PMKSA entry existed " MAC_ADDRESS_STR,
8228 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
Wilson Yang6507c4e2013-10-01 20:11:19 -07008229 dump_bssid(pmksa->bssid);
8230 dump_pmkid(halHandle, pmksa->pmkid);
8231 return -EINVAL;
8232 }
Wilson Yangef657d32014-01-15 19:19:23 -08008233 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008234}
8235
Wilson Yang6507c4e2013-10-01 20:11:19 -07008236
8237
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008238static int wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
8239{
Wilson Yang6507c4e2013-10-01 20:11:19 -07008240 tANI_U32 j=0;
8241 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
8242 tHalHandle halHandle;
8243 hdd_context_t *pHddCtx;
8244 tANI_U8 *pBSSId;
Wilson Yangef657d32014-01-15 19:19:23 -08008245 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -07008246
8247 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: flushing PMKSA ",__func__);
8248
8249 /* Validate pAdapter */
8250 if (NULL == pAdapter)
8251 {
8252 hddLog(VOS_TRACE_LEVEL_ERROR,
8253 "%s: Invalid Adapter" ,__func__);
8254 return -EINVAL;
8255 }
8256
8257 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8258 status = wlan_hdd_validate_context(pHddCtx);
8259
8260 if (0 != status)
8261 {
8262 hddLog(VOS_TRACE_LEVEL_ERROR,
8263 "%s: HDD context is not valid", __func__);
8264 return status;
8265 }
8266
8267 /*Retrieve halHandle*/
8268 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
8269
8270 /*in case index is 0,no entry to delete*/
8271 if (0 == PMKIDCacheIndex)
8272 {
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +05308273 hddLog(VOS_TRACE_LEVEL_ERROR, FL("No entries to flush"));
Wilson Yang6507c4e2013-10-01 20:11:19 -07008274 return -EINVAL;
8275 }
8276
8277 /*delete all the PMKSA one by one */
8278 for (j = 0; j<PMKIDCacheIndex; j++)
8279 {
Wilson Yang6507c4e2013-10-01 20:11:19 -07008280 pBSSId =(tANI_U8 *)(PMKIDCache[j].BSSID);
Wilson Yang6507c4e2013-10-01 20:11:19 -07008281
8282 /*delete the PMKID in CSR*/
Wilson Yangef657d32014-01-15 19:19:23 -08008283 if (eHAL_STATUS_SUCCESS !=
8284 sme_RoamDelPMKIDfromCache(halHandle, pAdapter->sessionId, pBSSId))
Wilson Yang6507c4e2013-10-01 20:11:19 -07008285 {
8286 hddLog(VOS_TRACE_LEVEL_ERROR ,"%s cannot flush PMKIDCache %d.",
8287 __func__,j);
Wilson Yangef657d32014-01-15 19:19:23 -08008288 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -07008289 }
Kiet Lam8d21d5b2013-10-31 17:18:29 +05308290 /*clear the entry in HDD cache 0--index-1 */
8291 vos_mem_zero(PMKIDCache[j].BSSID, WNI_CFG_BSSID_LEN);
8292 vos_mem_zero(PMKIDCache[j].PMKID, CSR_RSN_PMKID_SIZE);
Wilson Yang6507c4e2013-10-01 20:11:19 -07008293 }
8294
8295 PMKIDCacheIndex = 0;
Wilson Yangef657d32014-01-15 19:19:23 -08008296 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008297}
8298#endif
8299
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07008300#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308301static int wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07008302 struct net_device *dev, struct cfg80211_update_ft_ies_params *ftie)
8303{
8304 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
8305 hdd_station_ctx_t *pHddStaCtx;
8306
8307 if (NULL == pAdapter)
8308 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08008309 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07008310 return -ENODEV;
8311 }
8312
8313 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
8314
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308315 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
8316 TRACE_CODE_HDD_CFG80211_UPDATE_FT_IES,
8317 pAdapter->sessionId, pHddStaCtx->conn_info.connState));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07008318 // Added for debug on reception of Re-assoc Req.
8319 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
8320 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08008321 hddLog(LOGE, FL("Called with Ie of length = %zu when not associated"),
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07008322 ftie->ie_len);
Arif Hussain6d2a3322013-11-17 19:50:10 -08008323 hddLog(LOGE, FL("Should be Re-assoc Req IEs"));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07008324 }
8325
8326#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG
Arif Hussain6d2a3322013-11-17 19:50:10 -08008327 hddLog(LOGE, FL("%s called with Ie of length = %zu"), __func__,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07008328 ftie->ie_len);
8329#endif
8330
8331 // Pass the received FT IEs to SME
Gopichand Nakkala356fb102013-03-06 12:34:04 +05308332 sme_SetFTIEs( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
8333 (const u8 *)ftie->ie,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07008334 ftie->ie_len);
8335 return 0;
8336}
8337#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008338
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308339#ifdef FEATURE_WLAN_SCAN_PNO
8340
8341void hdd_cfg80211_sched_scan_done_callback(void *callbackContext,
8342 tSirPrefNetworkFoundInd *pPrefNetworkFoundInd)
8343{
8344 int ret;
8345 hdd_adapter_t* pAdapter = (hdd_adapter_t*)callbackContext;
8346 hdd_context_t *pHddCtx;
8347
Nirav Shah80830bf2013-12-31 16:35:12 +05308348 ENTER();
8349
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308350 if (NULL == pAdapter)
8351 {
Agarwal Ashish971c2882013-10-30 20:11:12 +05308352 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308353 "%s: HDD adapter is Null", __func__);
8354 return ;
8355 }
8356
8357 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8358 if (NULL == pHddCtx)
8359 {
8360 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8361 "%s: HDD context is Null!!!", __func__);
8362 return ;
8363 }
8364
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05308365 spin_lock(&pHddCtx->schedScan_lock);
8366 if (TRUE == pHddCtx->isWiphySuspended)
8367 {
8368 pHddCtx->isSchedScanUpdatePending = TRUE;
8369 spin_unlock(&pHddCtx->schedScan_lock);
8370 hddLog(VOS_TRACE_LEVEL_INFO,
8371 "%s: Update cfg80211 scan database after it resume", __func__);
8372 return ;
8373 }
8374 spin_unlock(&pHddCtx->schedScan_lock);
8375
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308376 ret = wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter);
8377
8378 if (0 > ret)
8379 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
8380
8381 cfg80211_sched_scan_results(pHddCtx->wiphy);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05308382 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8383 "%s: cfg80211 scan result database updated", __func__);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308384}
8385
8386/*
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +05308387 * FUNCTION: wlan_hdd_is_pno_allowed
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +05308388 * Disallow pno if any session is active
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +05308389 */
8390static eHalStatus wlan_hdd_is_pno_allowed(hdd_adapter_t *pAdapter)
8391{
8392 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
8393 hdd_adapter_t *pTempAdapter = NULL;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +05308394 hdd_station_ctx_t *pStaCtx;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +05308395 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8396 int status = 0;
8397 status = hdd_get_front_adapter(pHddCtx, &pAdapterNode);
8398
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +05308399 /* The current firmware design does not allow PNO during any
8400 * active sessions. Hence, determine the active sessions
8401 * and return a failure.
8402 */
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +05308403 while ((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status))
8404 {
8405 pTempAdapter = pAdapterNode->pAdapter;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +05308406 pStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pTempAdapter);
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +05308407
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +05308408 if (((WLAN_HDD_INFRA_STATION == pTempAdapter->device_mode)
8409 && (eConnectionState_NotConnected != pStaCtx->conn_info.connState))
8410 || (WLAN_HDD_P2P_CLIENT == pTempAdapter->device_mode)
8411 || (WLAN_HDD_P2P_GO == pTempAdapter->device_mode)
8412 || (WLAN_HDD_SOFTAP == pTempAdapter->device_mode)
8413 )
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +05308414 {
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +05308415 return eHAL_STATUS_FAILURE;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +05308416 }
8417 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
8418 pAdapterNode = pNext;
8419 }
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +05308420 return eHAL_STATUS_SUCCESS;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +05308421}
8422
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +05308423void hdd_cfg80211_sched_scan_start_status_cb(void *callbackContext, VOS_STATUS status)
8424{
8425 hdd_adapter_t *pAdapter = callbackContext;
8426 hdd_context_t *pHddCtx;
8427
8428 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
8429 {
8430 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8431 FL("Invalid adapter or adapter has invalid magic"));
8432 return;
8433 }
8434
8435 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8436 if (0 != wlan_hdd_validate_context(pHddCtx))
8437 {
8438 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8439 FL("HDD context is not valid"));
8440 return;
8441 }
8442
8443 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8444 FL("PNO enable response status = %d"), status);
8445
8446 pAdapter->pno_req_status = (status == VOS_STATUS_SUCCESS) ? 0 : -EBUSY;
8447 complete(&pAdapter->pno_comp_var);
8448}
8449
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +05308450/*
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308451 * FUNCTION: wlan_hdd_cfg80211_sched_scan_start
8452 * NL interface to enable PNO
8453 */
8454static int wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
8455 struct net_device *dev, struct cfg80211_sched_scan_request *request)
8456{
8457 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
8458 tpSirPNOScanReq pPnoRequest = NULL;
8459 hdd_context_t *pHddCtx;
8460 tHalHandle hHal;
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +05308461 v_U32_t i, indx, num_ch, tempInterval;
Sushant Kaushikd62d9782014-02-19 15:39:40 +05308462 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
8463 u8 channels_allowed[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308464 v_U32_t num_channels_allowed = WNI_CFG_VALID_CHANNEL_LIST_LEN;
8465 eHalStatus status = eHAL_STATUS_FAILURE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308466 int ret = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308467
8468 if (NULL == pAdapter)
8469 {
8470 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
8471 "%s: HDD adapter is Null", __func__);
8472 return -ENODEV;
8473 }
8474
8475 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05308476 ret = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308477
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05308478 if (0 != ret)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308479 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05308480 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8481 "%s: HDD context is not valid", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308482 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308483 }
8484
8485 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
8486 if (NULL == hHal)
8487 {
8488 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8489 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05308490 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308491 }
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +05308492
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +05308493 if (eHAL_STATUS_SUCCESS != wlan_hdd_is_pno_allowed(pAdapter))
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +05308494 {
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +05308495 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +05308496 FL("Cannot handle sched_scan"));
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +05308497 return -EBUSY;
8498 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308499
c_hpothu37f21312014-04-09 21:49:54 +05308500 if (TRUE == pHddCtx->isPnoEnable)
8501 {
8502 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
8503 FL("already PNO is enabled"));
8504 return -EBUSY;
8505 }
8506 pHddCtx->isPnoEnable = TRUE;
8507
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308508 pPnoRequest = (tpSirPNOScanReq) vos_mem_malloc(sizeof (tSirPNOScanReq));
8509 if (NULL == pPnoRequest)
8510 {
8511 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
8512 "%s: vos_mem_malloc failed", __func__);
c_hpothu37f21312014-04-09 21:49:54 +05308513 pHddCtx->isPnoEnable = FALSE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308514 return -ENOMEM;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308515 }
8516
Madan Mohan Koyyalamudic3f04352013-09-26 19:21:48 +05308517 memset(pPnoRequest, 0, sizeof (tSirPNOScanReq));
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308518 pPnoRequest->enable = 1; /*Enable PNO */
8519 pPnoRequest->ucNetworksCount = request->n_match_sets;
8520
8521 if (( !pPnoRequest->ucNetworksCount ) ||
8522 ( pPnoRequest->ucNetworksCount > SIR_PNO_MAX_SUPP_NETWORKS ))
8523 {
8524 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +05308525 "%s: Network input is not correct %d",
8526 __func__, pPnoRequest->ucNetworksCount);
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308527 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308528 goto error;
8529 }
8530
8531 if ( SIR_PNO_MAX_NETW_CHANNELS_EX < request->n_channels )
8532 {
8533 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +05308534 "%s: Incorrect number of channels %d",
8535 __func__, request->n_channels);
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308536 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308537 goto error;
8538 }
8539
8540 /* Framework provides one set of channels(all)
8541 * common for all saved profile */
8542 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
8543 channels_allowed, &num_channels_allowed))
8544 {
8545 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8546 "%s: failed to get valid channel list", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308547 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308548 goto error;
8549 }
8550 /* Checking each channel against allowed channel list */
8551 num_ch = 0;
Nirav Shah80830bf2013-12-31 16:35:12 +05308552 if (request->n_channels)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308553 {
Nirav Shah80830bf2013-12-31 16:35:12 +05308554 char chList [(request->n_channels*5)+1];
8555 int len;
8556 for (i = 0, len = 0; i < request->n_channels; i++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308557 {
Nirav Shah80830bf2013-12-31 16:35:12 +05308558 for (indx = 0; indx < num_channels_allowed; indx++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308559 {
Nirav Shah80830bf2013-12-31 16:35:12 +05308560 if (request->channels[i]->hw_value == channels_allowed[indx])
8561 {
8562 valid_ch[num_ch++] = request->channels[i]->hw_value;
8563 len += snprintf(chList+len, 5, "%d ",
8564 request->channels[i]->hw_value);
8565 break ;
8566 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308567 }
8568 }
Nirav Shah80830bf2013-12-31 16:35:12 +05308569 hddLog(VOS_TRACE_LEVEL_INFO,"Channel-List: %s ", chList);
8570 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308571
8572 /* Filling per profile params */
8573 for (i = 0; i < pPnoRequest->ucNetworksCount; i++)
8574 {
8575 pPnoRequest->aNetworks[i].ssId.length =
8576 request->match_sets[i].ssid.ssid_len;
8577
8578 if (( 0 == pPnoRequest->aNetworks[i].ssId.length ) ||
8579 ( pPnoRequest->aNetworks[i].ssId.length > 32 ) )
8580 {
8581 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +05308582 "%s: SSID Len %d is not correct for network %d",
8583 __func__, pPnoRequest->aNetworks[i].ssId.length, i);
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308584 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308585 goto error;
8586 }
8587
8588 memcpy(pPnoRequest->aNetworks[i].ssId.ssId,
8589 request->match_sets[i].ssid.ssid,
8590 request->match_sets[i].ssid.ssid_len);
8591 pPnoRequest->aNetworks[i].authentication = 0; /*eAUTH_TYPE_ANY*/
8592 pPnoRequest->aNetworks[i].encryption = 0; /*eED_ANY*/
8593 pPnoRequest->aNetworks[i].bcastNetwType = 0; /*eBCAST_UNKNOWN*/
8594
8595 /*Copying list of valid channel into request */
8596 memcpy(pPnoRequest->aNetworks[i].aChannels, valid_ch, num_ch);
8597 pPnoRequest->aNetworks[i].ucChannelCount = num_ch;
8598
8599 pPnoRequest->aNetworks[i].rssiThreshold = 0; //Default value
8600 }
8601
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +05308602 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnson59a121e2013-11-30 09:46:08 -08008603 "request->ie_len = %zu", request->ie_len);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +05308604 if ((0 < request->ie_len) && (NULL != request->ie))
8605 {
8606 pPnoRequest->us24GProbeTemplateLen = request->ie_len;
8607 memcpy(&pPnoRequest->p24GProbeTemplate, request->ie,
8608 pPnoRequest->us24GProbeTemplateLen);
8609
8610 pPnoRequest->us5GProbeTemplateLen = request->ie_len;
8611 memcpy(&pPnoRequest->p5GProbeTemplate, request->ie,
8612 pPnoRequest->us5GProbeTemplateLen);
8613 }
8614
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +05308615 /* Driver gets only one time interval which is hardcoded in
8616 * supplicant for 10000ms. Taking power consumption into account 6 timers
8617 * will be used, Timervalue is increased exponentially i.e 10,20,40,
8618 * 80,160,320 secs. And number of scan cycle for each timer
8619 * is configurable through INI param gPNOScanTimerRepeatValue.
8620 * If it is set to 0 only one timer will be used and PNO scan cycle
8621 * will be repeated after each interval specified by supplicant
8622 * till PNO is disabled.
8623 */
8624 if (0 == pHddCtx->cfg_ini->configPNOScanTimerRepeatValue)
8625 pPnoRequest->scanTimers.ucScanTimersCount = HDD_PNO_SCAN_TIMERS_SET_ONE;
8626 else
8627 pPnoRequest->scanTimers.ucScanTimersCount =
8628 HDD_PNO_SCAN_TIMERS_SET_MULTIPLE;
8629
8630 tempInterval = (request->interval)/1000;
8631 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8632 "Base scan interval = %d PNOScanTimerRepeatValue = %d",
8633 tempInterval, pHddCtx->cfg_ini->configPNOScanTimerRepeatValue);
8634 for ( i = 0; i < pPnoRequest->scanTimers.ucScanTimersCount; i++)
8635 {
8636 pPnoRequest->scanTimers.aTimerValues[i].uTimerRepeat =
8637 pHddCtx->cfg_ini->configPNOScanTimerRepeatValue;
8638 pPnoRequest->scanTimers.aTimerValues[i].uTimerValue = tempInterval;
8639 tempInterval *= 2;
8640 }
8641 //Repeat last timer until pno disabled.
8642 pPnoRequest->scanTimers.aTimerValues[i-1].uTimerRepeat = 0;
8643
Madan Mohan Koyyalamudid206c7b2013-09-26 22:54:51 +05308644 pPnoRequest->modePNO = SIR_PNO_MODE_IMMEDIATE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308645
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +05308646 INIT_COMPLETION(pAdapter->pno_comp_var);
8647 pPnoRequest->statusCallback = hdd_cfg80211_sched_scan_start_status_cb;
8648 pPnoRequest->callbackContext = pAdapter;
8649 pAdapter->pno_req_status = 0;
8650
Nirav Shah80830bf2013-12-31 16:35:12 +05308651 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8652 "SessionId %d, enable %d, modePNO %d, ucScanTimersCount %d",
8653 pAdapter->sessionId, pPnoRequest->enable, pPnoRequest->modePNO,
8654 pPnoRequest->scanTimers.ucScanTimersCount);
8655
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308656 status = sme_SetPreferredNetworkList(WLAN_HDD_GET_HAL_CTX(pAdapter),
8657 pPnoRequest, pAdapter->sessionId,
8658 hdd_cfg80211_sched_scan_done_callback, pAdapter);
8659 if (eHAL_STATUS_SUCCESS != status)
8660 {
8661 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +05308662 "%s: Failed to enable PNO", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308663 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308664 goto error;
8665 }
8666
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +05308667 ret = wait_for_completion_timeout(
8668 &pAdapter->pno_comp_var,
8669 msecs_to_jiffies(WLAN_WAIT_TIME_PNO));
8670 if (0 >= ret)
8671 {
8672 // Did not receive the response for PNO enable in time.
8673 // Assuming the PNO enable was success.
8674 // Returning error from here, because we timeout, results
8675 // in side effect of Wifi (Wifi Setting) not to work.
8676 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8677 FL("Timed out waiting for PNO to be Enabled"));
8678 ret = 0;
8679 goto error;
8680 }
8681
8682 ret = pAdapter->pno_req_status;
c_hpothu37f21312014-04-09 21:49:54 +05308683 return ret;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05308684
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308685error:
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +05308686 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8687 FL("PNO scanRequest offloaded ret = %d"), ret);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308688 vos_mem_free(pPnoRequest);
c_hpothu37f21312014-04-09 21:49:54 +05308689 pHddCtx->isPnoEnable = FALSE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308690 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308691}
8692
8693/*
8694 * FUNCTION: wlan_hdd_cfg80211_sched_scan_stop
8695 * NL interface to disable PNO
8696 */
8697static int wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
8698 struct net_device *dev)
8699{
8700 eHalStatus status = eHAL_STATUS_FAILURE;
8701 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
8702 hdd_context_t *pHddCtx;
8703 tHalHandle hHal;
8704 tpSirPNOScanReq pPnoRequest = NULL;
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308705 int ret = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308706
8707 ENTER();
8708
8709 if (NULL == pAdapter)
8710 {
8711 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
8712 "%s: HDD adapter is Null", __func__);
8713 return -ENODEV;
8714 }
8715
8716 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308717
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308718 if (NULL == pHddCtx)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308719 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05308720 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308721 "%s: HDD context is Null", __func__);
8722 return -ENODEV;
8723 }
8724
8725 /* The return 0 is intentional when isLogpInProgress and
8726 * isLoadUnloadInProgress. We did observe a crash due to a return of
8727 * failure in sched_scan_stop , especially for a case where the unload
8728 * of the happens at the same time. The function __cfg80211_stop_sched_scan
8729 * was clearing rdev->sched_scan_req only when the sched_scan_stop returns
8730 * success. If it returns a failure , then its next invocation due to the
8731 * clean up of the second interface will have the dev pointer corresponding
8732 * to the first one leading to a crash.
8733 */
8734 if (pHddCtx->isLogpInProgress)
8735 {
8736 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8737 "%s: LOGP in Progress. Ignore!!!", __func__);
8738 return ret;
8739 }
8740
Mihir Shete18156292014-03-11 15:38:30 +05308741 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308742 {
8743 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8744 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
8745 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308746 }
8747
8748 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
8749 if (NULL == hHal)
8750 {
8751 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8752 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05308753 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308754 }
8755
8756 pPnoRequest = (tpSirPNOScanReq) vos_mem_malloc(sizeof (tSirPNOScanReq));
8757 if (NULL == pPnoRequest)
8758 {
8759 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
8760 "%s: vos_mem_malloc failed", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308761 return -ENOMEM;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308762 }
8763
8764 memset(pPnoRequest, 0, sizeof (tSirPNOScanReq));
8765 pPnoRequest->enable = 0; /* Disable PNO */
8766 pPnoRequest->ucNetworksCount = 0;
8767
8768 status = sme_SetPreferredNetworkList(hHal, pPnoRequest,
8769 pAdapter->sessionId,
8770 NULL, pAdapter);
8771 if (eHAL_STATUS_SUCCESS != status)
8772 {
8773 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8774 "Failed to disabled PNO");
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308775 ret = -EINVAL;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +05308776 goto error;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308777 }
c_hpothu37f21312014-04-09 21:49:54 +05308778 pHddCtx->isPnoEnable = FALSE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308779
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +05308780error:
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05308781 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +05308782 FL("PNO scan disabled ret = %d"), ret);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308783 vos_mem_free(pPnoRequest);
8784
8785 EXIT();
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308786 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308787}
8788
8789#endif /*FEATURE_WLAN_SCAN_PNO*/
8790
8791
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008792#ifdef FEATURE_WLAN_TDLS
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +05308793#if TDLS_MGMT_VERSION2
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008794static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
8795 u8 *peer, u8 action_code, u8 dialog_token,
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +05308796 u16 status_code, u32 peer_capability, const u8 *buf, size_t len)
8797#else
8798static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
8799 u8 *peer, u8 action_code, u8 dialog_token,
8800 u16 status_code, const u8 *buf, size_t len)
8801#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008802{
8803
8804 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
8805 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008806 u8 peerMac[6];
8807 VOS_STATUS status;
Gopichand Nakkala05922802013-03-14 12:23:19 -07008808 int max_sta_failed = 0;
Hoonki Leea34dd892013-02-05 22:56:02 -08008809 int responder;
Hoonki Leed37cbb32013-04-20 00:31:14 -07008810 long rc;
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +05308811#if !(TDLS_MGMT_VERSION2)
8812 u32 peer_capability = 0;
8813#endif
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05308814 tANI_U16 numCurrTdlsPeers;
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008815
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308816 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
8817 TRACE_CODE_HDD_CFG80211_TDLS_MGMT,
8818 pAdapter->sessionId, action_code));
Hoonki Lee11f7dda2013-02-14 16:55:44 -08008819 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008820 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308821 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008822 "Invalid arguments");
8823 return -EINVAL;
8824 }
8825
Sameer Thalappil75ea31a2013-02-21 19:38:16 -08008826 if (pHddCtx->isLogpInProgress)
8827 {
8828 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8829 "%s:LOGP in Progress. Ignore!!!", __func__);
Gopichand Nakkala05922802013-03-14 12:23:19 -07008830 wlan_hdd_tdls_set_link_status(pAdapter, peer, eTDLS_LINK_IDLE);
Sameer Thalappil75ea31a2013-02-21 19:38:16 -08008831 return -EBUSY;
8832 }
8833
Hoonki Lee27511902013-03-14 18:19:06 -07008834 if (eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode)
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008835 {
Hoonki Lee27511902013-03-14 18:19:06 -07008836 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
8837 "%s: TDLS mode is disabled OR not enabled in FW."
8838 MAC_ADDRESS_STR " action %d declined.",
8839 __func__, MAC_ADDR_ARRAY(peer), action_code);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008840 return -ENOTSUPP;
8841 }
Lee Hoonkic1262f22013-01-24 21:59:00 -08008842
Hoonki Lee27511902013-03-14 18:19:06 -07008843 /* other than teardown frame, other mgmt frames are not sent if disabled */
8844 if (SIR_MAC_TDLS_TEARDOWN != action_code)
8845 {
8846 /* if tdls_mode is disabled to respond to peer's request */
8847 if (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode)
8848 {
8849 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
8850 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07008851 " TDLS mode is disabled. action %d declined.",
8852 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee27511902013-03-14 18:19:06 -07008853
8854 return -ENOTSUPP;
8855 }
8856 }
8857
Gopichand Nakkalab977a972013-02-18 19:15:09 -08008858 if (WLAN_IS_TDLS_SETUP_ACTION(action_code))
8859 {
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308860 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, peer, TRUE))
Gopichand Nakkalab977a972013-02-18 19:15:09 -08008861 {
8862 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07008863 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07008864 " TDLS setup is ongoing. action %d declined.",
8865 __func__, MAC_ADDR_ARRAY(peer), action_code);
8866 return -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -08008867 }
8868 }
8869
Hoonki Lee11f7dda2013-02-14 16:55:44 -08008870 if (SIR_MAC_TDLS_SETUP_REQ == action_code ||
8871 SIR_MAC_TDLS_SETUP_RSP == action_code )
Lee Hoonkic1262f22013-01-24 21:59:00 -08008872 {
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05308873 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
8874 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Lee Hoonkic1262f22013-01-24 21:59:00 -08008875 {
8876 /* supplicant still sends tdls_mgmt(SETUP_REQ) even after
8877 we return error code at 'add_station()'. Hence we have this
8878 check again in addtion to add_station().
8879 Anyway, there is no hard to double-check. */
Hoonki Lee11f7dda2013-02-14 16:55:44 -08008880 if (SIR_MAC_TDLS_SETUP_REQ == action_code)
Lee Hoonkic1262f22013-01-24 21:59:00 -08008881 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07008882 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8883 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05308884 " TDLS Max peer already connected. action (%d) declined. Num of peers (%d), Max allowed (%d).",
8885 __func__, MAC_ADDR_ARRAY(peer), action_code,
8886 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Sunil Dutt388ac8f2013-11-28 18:06:52 +05308887 return -EINVAL;
Lee Hoonkic1262f22013-01-24 21:59:00 -08008888 }
8889 else
8890 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -08008891 /* maximum reached. tweak to send error code to peer and return
8892 error code to supplicant */
Lee Hoonkic1262f22013-01-24 21:59:00 -08008893 status_code = eSIR_MAC_UNSPEC_FAILURE_STATUS;
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07008894 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8895 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05308896 " TDLS Max peer already connected, send response status (%d). Num of peers (%d), Max allowed (%d).",
8897 __func__, MAC_ADDR_ARRAY(peer), status_code,
8898 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -07008899 max_sta_failed = -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -08008900 /* fall through to send setup resp with failure status
8901 code */
Lee Hoonkic1262f22013-01-24 21:59:00 -08008902 }
8903 }
Hoonki Lee11f7dda2013-02-14 16:55:44 -08008904 else
8905 {
8906 hddTdlsPeer_t *pTdlsPeer;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308907 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008908 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Hoonki Lee11f7dda2013-02-14 16:55:44 -08008909 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07008910 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07008911 "%s:" MAC_ADDRESS_STR " already connected. action %d declined.",
8912 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee11f7dda2013-02-14 16:55:44 -08008913 return -EPERM;
8914 }
8915 }
Lee Hoonkic1262f22013-01-24 21:59:00 -08008916 }
Hoonki Lee11f7dda2013-02-14 16:55:44 -08008917 vos_mem_copy(peerMac, peer, 6);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008918
Hoonki Lee1090c6a2013-01-16 17:40:54 -08008919#ifdef WLAN_FEATURE_TDLS_DEBUG
8920 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +05308921 "%s: " MAC_ADDRESS_STR " action %d, dialog_token %d status %d, len = %zu",
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07008922 "tdls_mgmt", MAC_ADDR_ARRAY(peer),
8923 action_code, dialog_token, status_code, len);
Hoonki Lee1090c6a2013-01-16 17:40:54 -08008924#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008925
Hoonki Leea34dd892013-02-05 22:56:02 -08008926 /*Except teardown responder will not be used so just make 0*/
8927 responder = 0;
Hoonki Lee11f7dda2013-02-14 16:55:44 -08008928 if (SIR_MAC_TDLS_TEARDOWN == action_code)
Hoonki Leea34dd892013-02-05 22:56:02 -08008929 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -07008930
8931 hddTdlsPeer_t *pTdlsPeer;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308932 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peerMac, TRUE);
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -07008933
8934 if(pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
8935 responder = pTdlsPeer->is_responder;
8936 else
Hoonki Leea34dd892013-02-05 22:56:02 -08008937 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -07008938 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +05308939 "%s: " MAC_ADDRESS_STR " peer doesn't exist or not connected %d dialog_token %d status %d, len = %zu",
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -07008940 __func__, MAC_ADDR_ARRAY(peer), (NULL == pTdlsPeer) ? -1 : pTdlsPeer->link_status,
8941 dialog_token, status_code, len);
8942 return -EPERM;
Hoonki Leea34dd892013-02-05 22:56:02 -08008943 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008944 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008945
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +05308946 /* For explicit trigger of DIS_REQ come out of BMPS for
8947 successfully receiving DIS_RSP from peer. */
Hoonki Lee14621352013-04-16 17:51:19 -07008948 if ((SIR_MAC_TDLS_SETUP_RSP == action_code) ||
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +05308949 (SIR_MAC_TDLS_DIS_RSP == action_code) ||
8950 (SIR_MAC_TDLS_DIS_REQ == action_code))
Hoonki Lee14621352013-04-16 17:51:19 -07008951 {
8952 if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter)))
8953 {
8954 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +05308955 "%s: Sending frame action_code %u.Disable BMPS", __func__, action_code);
Hoonki Lee14621352013-04-16 17:51:19 -07008956 hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
8957 }
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +05308958 if (SIR_MAC_TDLS_DIS_REQ != action_code)
8959 wlan_hdd_tdls_set_cap(pAdapter, peerMac, eTDLS_CAP_SUPPORTED);
Hoonki Lee14621352013-04-16 17:51:19 -07008960 }
8961
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008962 /* make sure doesn't call send_mgmt() while it is pending */
8963 if (TDLS_CTX_MAGIC == pAdapter->mgmtTxCompletionStatus)
8964 {
8965 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008966 "%s: " MAC_ADDRESS_STR " action %d couldn't sent, as one is pending. return EBUSY",
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008967 __func__, MAC_ADDR_ARRAY(peer), action_code);
8968 return -EBUSY;
8969 }
8970
8971 pAdapter->mgmtTxCompletionStatus = TDLS_CTX_MAGIC;
Gopichand Nakkalab977a972013-02-18 19:15:09 -08008972 INIT_COMPLETION(pAdapter->tdls_mgmt_comp);
8973
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008974 status = sme_SendTdlsMgmtFrame(WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
Pradeep Reddy POTTETIca171f82014-03-21 14:17:35 +05308975 peerMac, action_code, dialog_token, status_code, peer_capability, (tANI_U8 *)buf, len, responder);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008976
Gopichand Nakkalab977a972013-02-18 19:15:09 -08008977 if (VOS_STATUS_SUCCESS != status)
8978 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008979 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8980 "%s: sme_SendTdlsMgmtFrame failed!", __func__);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008981 pAdapter->mgmtTxCompletionStatus = FALSE;
Hoonki Lee14621352013-04-16 17:51:19 -07008982 wlan_hdd_tdls_check_bmps(pAdapter);
Sunil Dutt388ac8f2013-11-28 18:06:52 +05308983 return -EINVAL;
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008984 }
8985
Hoonki Leed37cbb32013-04-20 00:31:14 -07008986 rc = wait_for_completion_interruptible_timeout(&pAdapter->tdls_mgmt_comp,
8987 msecs_to_jiffies(WAIT_TIME_TDLS_MGMT));
8988
8989 if ((rc <= 0) || (TRUE != pAdapter->mgmtTxCompletionStatus))
Gopichand Nakkalab977a972013-02-18 19:15:09 -08008990 {
Hoonki Leed37cbb32013-04-20 00:31:14 -07008991 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07008992 "%s: Mgmt Tx Completion failed status %ld TxCompletion %u",
Hoonki Leed37cbb32013-04-20 00:31:14 -07008993 __func__, rc, pAdapter->mgmtTxCompletionStatus);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008994 pAdapter->mgmtTxCompletionStatus = FALSE;
Yue Ma4f55ef32014-01-23 16:45:33 -08008995
8996 if (pHddCtx->isLogpInProgress)
8997 {
8998 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8999 "%s: LOGP in Progress. Ignore!!!", __func__);
9000 return -EAGAIN;
9001 }
9002
Hoonki Leed37cbb32013-04-20 00:31:14 -07009003 wlan_hdd_tdls_check_bmps(pAdapter);
Sunil Dutt388ac8f2013-11-28 18:06:52 +05309004 return -EINVAL;
Gopichand Nakkalab977a972013-02-18 19:15:09 -08009005 }
9006
Gopichand Nakkala05922802013-03-14 12:23:19 -07009007 if (max_sta_failed)
Hoonki Lee14621352013-04-16 17:51:19 -07009008 {
9009 wlan_hdd_tdls_check_bmps(pAdapter);
Gopichand Nakkala05922802013-03-14 12:23:19 -07009010 return max_sta_failed;
Hoonki Lee14621352013-04-16 17:51:19 -07009011 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -08009012
Hoonki Leea34dd892013-02-05 22:56:02 -08009013 if (SIR_MAC_TDLS_SETUP_RSP == action_code)
9014 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -08009015 wlan_hdd_tdls_set_responder(pAdapter, peerMac, TRUE);
Hoonki Leea34dd892013-02-05 22:56:02 -08009016 }
9017 else if (SIR_MAC_TDLS_SETUP_CNF == action_code)
9018 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -08009019 wlan_hdd_tdls_set_responder(pAdapter, peerMac, FALSE);
Hoonki Leea34dd892013-02-05 22:56:02 -08009020 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009021
9022 return 0;
9023}
9024
9025static int wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
9026 u8 *peer, enum nl80211_tdls_operation oper)
9027{
9028 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
9029 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309030 int status;
Hoonki Lee5305c3a2013-04-29 23:28:59 -07009031 hddTdlsPeer_t *pTdlsPeer;
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009032
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309033 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
9034 TRACE_CODE_HDD_CFG80211_TDLS_OPER,
9035 pAdapter->sessionId, oper));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309036 if ( NULL == peer )
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009037 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -08009038 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chilam Ngc4244af2013-04-01 15:37:32 -07009039 "%s: Invalid arguments", __func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009040 return -EINVAL;
9041 }
Hoonki Lee1090c6a2013-01-16 17:40:54 -08009042
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309043 status = wlan_hdd_validate_context(pHddCtx);
9044
9045 if (0 != status)
Sameer Thalappil75ea31a2013-02-21 19:38:16 -08009046 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309047 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9048 "%s: HDD context is not valid", __func__);
9049 return status;
Sameer Thalappil75ea31a2013-02-21 19:38:16 -08009050 }
9051
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009052
9053 if( FALSE == pHddCtx->cfg_ini->fEnableTDLSSupport ||
Hoonki Lee1090c6a2013-01-16 17:40:54 -08009054 FALSE == sme_IsFeatureSupportedByFW(TDLS))
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009055 {
Hoonki Lee1090c6a2013-01-16 17:40:54 -08009056 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chilam Ngc4244af2013-04-01 15:37:32 -07009057 "TDLS Disabled in INI OR not enabled in FW. "
9058 "Cannot process TDLS commands");
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009059 return -ENOTSUPP;
9060 }
9061
9062 switch (oper) {
9063 case NL80211_TDLS_ENABLE_LINK:
9064 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009065 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309066 long ret;
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05309067 tCsrTdlsLinkEstablishParams tdlsLinkEstablishParams;
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009068
Sunil Dutt41de4e22013-11-14 18:09:02 +05309069 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
9070
9071 if ( NULL == pTdlsPeer ) {
9072 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
9073 " (oper %d) not exsting. ignored",
9074 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
9075 return -EINVAL;
9076 }
9077
9078 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9079 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
9080 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
9081 "NL80211_TDLS_ENABLE_LINK");
9082
Gopichand Nakkala2f4a2822013-04-17 11:22:01 -07009083 if (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
9084 {
9085 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Staion Index %u "
9086 MAC_ADDRESS_STR " failed",
9087 __func__, pTdlsPeer->staId, MAC_ADDR_ARRAY(peer));
9088 return -EINVAL;
9089 }
9090
Hoonki Lee5305c3a2013-04-29 23:28:59 -07009091 if (eTDLS_LINK_CONNECTED != pTdlsPeer->link_status)
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07009092 {
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +05309093 if (IS_ADVANCE_TDLS_ENABLE) {
Gopichand Nakkala24be5312013-07-02 16:47:12 +05309094
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +05309095 if (0 != wlan_hdd_tdls_get_link_establish_params(
9096 pAdapter, peer,&tdlsLinkEstablishParams)) {
9097 return -EINVAL;
9098 }
9099 INIT_COMPLETION(pAdapter->tdls_link_establish_req_comp);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05309100
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +05309101 sme_SendTdlsLinkEstablishParams(WLAN_HDD_GET_HAL_CTX(pAdapter),
9102 pAdapter->sessionId, peer, &tdlsLinkEstablishParams);
9103 /* Send TDLS peer UAPSD capabilities to the firmware and
9104 * register with the TL on after the response for this operation
9105 * is received .
9106 */
9107 ret = wait_for_completion_interruptible_timeout(
9108 &pAdapter->tdls_link_establish_req_comp,
9109 msecs_to_jiffies(WAIT_TIME_TDLS_LINK_ESTABLISH_REQ));
9110 if (ret <= 0)
9111 {
9112 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9113 "%s: Link Establish Request Faled Status %ld",
9114 __func__, ret);
9115 return -EINVAL;
9116 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05309117 }
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -07009118 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer, eTDLS_LINK_CONNECTED);
Gopichand Nakkala471708b2013-06-04 20:03:01 +05309119 /* Mark TDLS client Authenticated .*/
9120 status = WLANTL_ChangeSTAState( pHddCtx->pvosContext,
9121 pTdlsPeer->staId,
9122 WLANTL_STA_AUTHENTICATED);
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -07009123 if (VOS_STATUS_SUCCESS == status)
9124 {
Hoonki Lee14621352013-04-16 17:51:19 -07009125 if (pTdlsPeer->is_responder == 0)
9126 {
9127 v_U8_t staId = (v_U8_t)pTdlsPeer->staId;
9128
9129 wlan_hdd_tdls_timer_restart(pAdapter,
9130 &pTdlsPeer->initiatorWaitTimeoutTimer,
9131 WAIT_TIME_TDLS_INITIATOR);
9132 /* suspend initiator TX until it receives direct packet from the
9133 reponder or WAIT_TIME_TDLS_INITIATOR timer expires */
9134 WLANTL_SuspendDataTx( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
9135 &staId, NULL);
9136 }
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -07009137 wlan_hdd_tdls_increment_peer_count(pAdapter);
9138 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07009139 wlan_hdd_tdls_check_bmps(pAdapter);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05309140
9141 /* Update TL about the UAPSD masks , to route the packets to firmware */
Gopichand Nakkala574f6d12013-06-27 19:38:43 +05309142 if ((TRUE == pHddCtx->cfg_ini->fEnableTDLSBufferSta)
9143 || pHddCtx->cfg_ini->fTDLSUapsdMask )
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05309144 {
Gopichand Nakkala574f6d12013-06-27 19:38:43 +05309145 int ac;
9146 uint8 ucAc[4] = { WLANTL_AC_VO,
9147 WLANTL_AC_VI,
9148 WLANTL_AC_BK,
9149 WLANTL_AC_BE };
9150 uint8 tlTid[4] = { 7, 5, 2, 3 } ;
9151 for(ac=0; ac < 4; ac++)
9152 {
9153 status = WLANTL_EnableUAPSDForAC( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
9154 pTdlsPeer->staId, ucAc[ac],
9155 tlTid[ac], tlTid[ac], 0, 0,
9156 WLANTL_BI_DIR );
9157 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05309158 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07009159 }
9160
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009161 }
9162 break;
9163 case NL80211_TDLS_DISABLE_LINK:
Lee Hoonkic1262f22013-01-24 21:59:00 -08009164 {
Sunil Dutt41de4e22013-11-14 18:09:02 +05309165 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
9166
9167 if ( NULL == pTdlsPeer ) {
9168 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
9169 " (oper %d) not exsting. ignored",
9170 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
9171 return -EINVAL;
9172 }
9173
9174 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9175 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
9176 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
9177 "NL80211_TDLS_DISABLE_LINK");
9178
Hoonki Lee5305c3a2013-04-29 23:28:59 -07009179 if(TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
Lee Hoonkic1262f22013-01-24 21:59:00 -08009180 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009181 long status;
9182
9183 INIT_COMPLETION(pAdapter->tdls_del_station_comp);
9184
Lee Hoonkic1262f22013-01-24 21:59:00 -08009185 sme_DeleteTdlsPeerSta( WLAN_HDD_GET_HAL_CTX(pAdapter),
9186 pAdapter->sessionId, peer );
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009187
9188 status = wait_for_completion_interruptible_timeout(&pAdapter->tdls_del_station_comp,
9189 msecs_to_jiffies(WAIT_TIME_TDLS_DEL_STA));
9190 if (status <= 0)
9191 {
Hoonki Lee5305c3a2013-04-29 23:28:59 -07009192 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer, eTDLS_LINK_IDLE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009193 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9194 "%s: Del station failed status %ld",
9195 __func__, status);
9196 return -EPERM;
9197 }
Hoonki Lee5305c3a2013-04-29 23:28:59 -07009198 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer, eTDLS_LINK_IDLE);
Lee Hoonkic1262f22013-01-24 21:59:00 -08009199 }
9200 else
9201 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07009202 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9203 "%s: TDLS Peer Station doesn't exist.", __func__);
Lee Hoonkic1262f22013-01-24 21:59:00 -08009204 }
Lee Hoonkic1262f22013-01-24 21:59:00 -08009205 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07009206 break;
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009207 case NL80211_TDLS_TEARDOWN:
Sunil Dutt41de4e22013-11-14 18:09:02 +05309208 {
9209 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9210 " %s : NL80211_TDLS_TEARDOWN for " MAC_ADDRESS_STR,
9211 __func__, MAC_ADDR_ARRAY(peer));
9212
9213 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
9214 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
9215
9216 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9217 " %s TDLS External control and Implicit Trigger not enabled ",
9218 __func__);
9219 return -ENOTSUPP;
9220 }
9221
Sunil Dutt41de4e22013-11-14 18:09:02 +05309222
9223 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
9224
9225 if ( NULL == pTdlsPeer ) {
9226 hddLog(VOS_TRACE_LEVEL_INFO, "%s: " MAC_ADDRESS_STR
9227 " peer not exsting",
9228 __func__, MAC_ADDR_ARRAY(peer));
Naresh Jayaram937abdf2013-11-26 19:50:25 +05309229 return -EINVAL;
Sunil Dutt41de4e22013-11-14 18:09:02 +05309230 }
9231 else {
9232 wlan_hdd_tdls_indicate_teardown(pAdapter, pTdlsPeer,
9233 eSIR_MAC_TDLS_TEARDOWN_UNSPEC_REASON);
9234 }
Naresh Jayaram937abdf2013-11-26 19:50:25 +05309235
9236 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, FALSE) )
9237 return -EINVAL;
Sunil Dutt41de4e22013-11-14 18:09:02 +05309238 break;
9239 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009240 case NL80211_TDLS_SETUP:
Sunil Dutt41de4e22013-11-14 18:09:02 +05309241 {
Naresh Jayaramdb4514b2013-11-25 18:08:10 +05309242 hddTdlsPeer_t *pTdlsPeer;
Sunil Dutt41de4e22013-11-14 18:09:02 +05309243 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9244 " %s : NL80211_TDLS_SETUP for " MAC_ADDRESS_STR,
9245 __func__, MAC_ADDR_ARRAY(peer));
9246
9247 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
9248 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
9249
9250 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9251 " %s TDLS External control and Implicit Trigger not enabled ",
9252 __func__);
9253 return -ENOTSUPP;
9254 }
9255
Naresh Jayaramdb4514b2013-11-25 18:08:10 +05309256 /* To cater the requirement of establishing the TDLS link
9257 * irrespective of the data traffic , get an entry of TDLS peer.
9258 */
9259 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, peer);
9260 if (pTdlsPeer == NULL) {
9261 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9262 "%s: peer " MAC_ADDRESS_STR " not existing",
9263 __func__, MAC_ADDR_ARRAY(peer));
9264 return -EINVAL;
9265 }
Naresh Jayaram937abdf2013-11-26 19:50:25 +05309266
9267 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, TRUE) ) {
9268
9269 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9270 " %s TDLS Add Force Peer Failed",
9271 __func__);
9272 return -EINVAL;
9273 }
Naresh Jayaramdb4514b2013-11-25 18:08:10 +05309274 break;
Sunil Dutt41de4e22013-11-14 18:09:02 +05309275 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009276 case NL80211_TDLS_DISCOVERY_REQ:
9277 /* We don't support in-driver setup/teardown/discovery */
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309278 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
9279 "%s: We don't support in-driver setup/teardown/discovery "
9280 ,__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009281 return -ENOTSUPP;
9282 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309283 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9284 "%s: unsupported event",__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009285 return -ENOTSUPP;
9286 }
9287 return 0;
9288}
Chilam NG571c65a2013-01-19 12:27:36 +05309289
9290int wlan_hdd_cfg80211_send_tdls_discover_req(struct wiphy *wiphy,
9291 struct net_device *dev, u8 *peer)
9292{
Arif Hussaina7c8e412013-11-20 11:06:42 -08009293 hddLog(VOS_TRACE_LEVEL_INFO,
9294 "tdls send discover req: "MAC_ADDRESS_STR,
9295 MAC_ADDR_ARRAY(peer));
Chilam NG571c65a2013-01-19 12:27:36 +05309296
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +05309297#if TDLS_MGMT_VERSION2
9298 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
9299 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
9300#else
Chilam NG571c65a2013-01-19 12:27:36 +05309301 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
9302 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, NULL, 0);
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +05309303#endif
Chilam NG571c65a2013-01-19 12:27:36 +05309304}
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009305#endif
9306
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309307#ifdef WLAN_FEATURE_GTK_OFFLOAD
9308/*
9309 * FUNCTION: wlan_hdd_cfg80211_update_replayCounterCallback
9310 * Callback rountine called upon receiving response for
9311 * get offload info
9312 */
9313void wlan_hdd_cfg80211_update_replayCounterCallback(void *callbackContext,
9314 tpSirGtkOffloadGetInfoRspParams pGtkOffloadGetInfoRsp)
9315{
9316
9317 hdd_adapter_t *pAdapter = (hdd_adapter_t *)callbackContext;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05309318 tANI_U8 tempReplayCounter[8];
9319 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309320
9321 ENTER();
9322
9323 if (NULL == pAdapter)
9324 {
Agarwal Ashish971c2882013-10-30 20:11:12 +05309325 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309326 "%s: HDD adapter is Null", __func__);
9327 return ;
9328 }
9329
9330 if (NULL == pGtkOffloadGetInfoRsp)
9331 {
9332 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9333 "%s: pGtkOffloadGetInfoRsp is Null", __func__);
9334 return ;
9335 }
9336
9337 if (VOS_STATUS_SUCCESS != pGtkOffloadGetInfoRsp->ulStatus)
9338 {
9339 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9340 "%s: wlan Failed to get replay counter value",
9341 __func__);
9342 return ;
9343 }
9344
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05309345 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9346 /* Update replay counter */
9347 pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter =
9348 pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
9349
9350 {
9351 /* changing from little to big endian since supplicant
9352 * works on big endian format
9353 */
9354 int i;
9355 tANI_U8 *p = (tANI_U8 *)&pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
9356
9357 for (i = 0; i < 8; i++)
9358 {
9359 tempReplayCounter[7-i] = (tANI_U8)p[i];
9360 }
9361 }
9362
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309363 /* Update replay counter to NL */
9364 cfg80211_gtk_rekey_notify(pAdapter->dev, pGtkOffloadGetInfoRsp->bssId,
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05309365 tempReplayCounter, GFP_KERNEL);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309366}
9367
9368/*
9369 * FUNCTION: wlan_hdd_cfg80211_set_rekey_data
9370 * This function is used to offload GTK rekeying job to the firmware.
9371 */
9372int wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
9373 struct cfg80211_gtk_rekey_data *data)
9374{
9375 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
9376 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
9377 hdd_station_ctx_t *pHddStaCtx;
9378 tHalHandle hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309379 int result;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05309380 tSirGtkOffloadParams hddGtkOffloadReqParams;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309381 eHalStatus status = eHAL_STATUS_FAILURE;
9382
9383 ENTER();
9384
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309385
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309386 if (NULL == pAdapter)
9387 {
9388 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
9389 "%s: HDD adapter is Null", __func__);
9390 return -ENODEV;
9391 }
9392
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309393 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
9394 TRACE_CODE_HDD_CFG80211_SET_REKEY_DATA,
9395 pAdapter->sessionId, pAdapter->device_mode));
9396
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309397 result = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309398
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309399 if (0 != result)
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309400 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309401 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9402 "%s: HDD context is not valid", __func__);
9403 return result;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309404 }
9405
9406 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9407 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
9408 if (NULL == hHal)
9409 {
9410 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9411 "%s: HAL context is Null!!!", __func__);
9412 return -EAGAIN;
9413 }
9414
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05309415 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_ENABLE;
9416 memcpy(pHddStaCtx->gtkOffloadReqParams.aKCK, data->kck, NL80211_KCK_LEN);
9417 memcpy(pHddStaCtx->gtkOffloadReqParams.aKEK, data->kek, NL80211_KEK_LEN);
9418 memcpy(pHddStaCtx->gtkOffloadReqParams.bssId, &pHddStaCtx->conn_info.bssId,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309419 WNI_CFG_BSSID_LEN);
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05309420 {
9421 /* changing from big to little endian since driver
9422 * works on little endian format
9423 */
9424 tANI_U8 *p =
9425 (tANI_U8 *)&pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter;
9426 int i;
9427
9428 for (i = 0; i < 8; i++)
9429 {
9430 p[7-i] = data->replay_ctr[i];
9431 }
9432 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309433
9434 if (TRUE == pHddCtx->hdd_wlan_suspended)
9435 {
9436 /* if wlan is suspended, enable GTK offload directly from here */
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05309437 memcpy(&hddGtkOffloadReqParams, &pHddStaCtx->gtkOffloadReqParams,
9438 sizeof (tSirGtkOffloadParams));
9439 status = sme_SetGTKOffload(hHal, &hddGtkOffloadReqParams,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309440 pAdapter->sessionId);
9441
9442 if (eHAL_STATUS_SUCCESS != status)
9443 {
9444 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9445 "%s: sme_SetGTKOffload failed, returned %d",
9446 __func__, status);
9447 return status;
9448 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309449 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9450 "%s: sme_SetGTKOffload successfull", __func__);
9451 }
9452 else
9453 {
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309454 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9455 "%s: wlan not suspended GTKOffload request is stored",
9456 __func__);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309457 }
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05309458
9459 return eHAL_STATUS_SUCCESS;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309460}
9461#endif /*WLAN_FEATURE_GTK_OFFLOAD*/
9462
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05309463/*
9464 * FUNCTION: wlan_hdd_cfg80211_set_mac_acl
9465 * This function is used to set access control policy
9466 */
9467static int wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy,
9468 struct net_device *dev, const struct cfg80211_acl_data *params)
9469{
9470 int i;
9471 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
9472 hdd_hostapd_state_t *pHostapdState;
9473 tsap_Config_t *pConfig;
9474 v_CONTEXT_t pVosContext = NULL;
9475 hdd_context_t *pHddCtx;
9476 int status;
9477
9478 ENTER();
9479
9480 if (NULL == pAdapter)
9481 {
9482 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
9483 "%s: HDD adapter is Null", __func__);
9484 return -ENODEV;
9485 }
9486
9487 if (NULL == params)
9488 {
9489 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
9490 "%s: params is Null", __func__);
9491 return -EINVAL;
9492 }
9493
9494 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9495 status = wlan_hdd_validate_context(pHddCtx);
9496
9497 if (0 != status)
9498 {
9499 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9500 "%s: HDD context is not valid", __func__);
9501 return status;
9502 }
9503
9504 pVosContext = pHddCtx->pvosContext;
9505 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
9506
9507 if (NULL == pHostapdState)
9508 {
9509 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
9510 "%s: pHostapdState is Null", __func__);
9511 return -EINVAL;
9512 }
9513
9514 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"acl policy: = %d"
9515 "no acl entries = %d", params->acl_policy, params->n_acl_entries);
9516
9517 if (WLAN_HDD_SOFTAP == pAdapter->device_mode)
9518 {
9519 pConfig = &pAdapter->sessionCtx.ap.sapConfig;
9520
9521 /* default value */
9522 pConfig->num_accept_mac = 0;
9523 pConfig->num_deny_mac = 0;
9524
9525 /**
9526 * access control policy
9527 * @NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED: Deny stations which are
9528 * listed in hostapd.deny file.
9529 * @NL80211_ACL_POLICY_DENY_UNLESS_LISTED: Allow stations which are
9530 * listed in hostapd.accept file.
9531 */
9532 if (NL80211_ACL_POLICY_DENY_UNLESS_LISTED == params->acl_policy)
9533 {
9534 pConfig->SapMacaddr_acl = eSAP_DENY_UNLESS_ACCEPTED;
9535 }
9536 else if (NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED == params->acl_policy)
9537 {
9538 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
9539 }
9540 else
9541 {
9542 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9543 "%s:Acl Policy : %d is not supported",
9544 __func__, params->acl_policy);
9545 return -ENOTSUPP;
9546 }
9547
9548 if (eSAP_DENY_UNLESS_ACCEPTED == pConfig->SapMacaddr_acl)
9549 {
9550 pConfig->num_accept_mac = params->n_acl_entries;
9551 for (i = 0; i < params->n_acl_entries; i++)
9552 {
9553 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9554 "** Add ACL MAC entry %i in WhiletList :"
9555 MAC_ADDRESS_STR, i,
9556 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
9557
9558 vos_mem_copy(&pConfig->accept_mac[i], params->mac_addrs[i].addr,
9559 sizeof(qcmacaddr));
9560 }
9561 }
9562 else if (eSAP_ACCEPT_UNLESS_DENIED == pConfig->SapMacaddr_acl)
9563 {
9564 pConfig->num_deny_mac = params->n_acl_entries;
9565 for (i = 0; i < params->n_acl_entries; i++)
9566 {
9567 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9568 "** Add ACL MAC entry %i in BlackList :"
9569 MAC_ADDRESS_STR, i,
9570 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
9571
9572 vos_mem_copy(&pConfig->deny_mac[i], params->mac_addrs[i].addr,
9573 sizeof(qcmacaddr));
9574 }
9575 }
9576
9577 if (VOS_STATUS_SUCCESS != WLANSAP_SetMacACL(pVosContext, pConfig))
9578 {
9579 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9580 "%s: SAP Set Mac Acl fail", __func__);
9581 return -EINVAL;
9582 }
9583 }
9584 else
9585 {
9586 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9587 "%s: Invalid device_mode = %d",
9588 __func__, pAdapter->device_mode);
9589 return -EINVAL;
9590 }
9591
9592 return 0;
9593}
9594
Leo Chang9056f462013-08-01 19:21:11 -07009595#ifdef WLAN_NL80211_TESTMODE
9596#ifdef FEATURE_WLAN_LPHB
Leo Changd9df8aa2013-09-26 13:32:26 -07009597void wlan_hdd_cfg80211_lphb_ind_handler
Leo Chang9056f462013-08-01 19:21:11 -07009598(
9599 void *pAdapter,
9600 void *indCont
9601)
9602{
Leo Changd9df8aa2013-09-26 13:32:26 -07009603 tSirLPHBInd *lphbInd;
9604 struct sk_buff *skb;
c_hpothu73f35e62014-04-18 13:40:08 +05309605 hdd_context_t *pHddCtxt;
Leo Chang9056f462013-08-01 19:21:11 -07009606
9607 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -07009608 "LPHB indication arrived");
Leo Chang9056f462013-08-01 19:21:11 -07009609
c_hpothu73f35e62014-04-18 13:40:08 +05309610 if (pAdapter == NULL)
9611 {
9612 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9613 "%s: pAdapter is NULL\n",__func__);
9614 return;
9615 }
9616
Leo Chang9056f462013-08-01 19:21:11 -07009617 if (NULL == indCont)
9618 {
9619 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -07009620 "LPHB IND, invalid argument");
Leo Chang9056f462013-08-01 19:21:11 -07009621 return;
9622 }
9623
c_hpothu73f35e62014-04-18 13:40:08 +05309624 pHddCtxt = (hdd_context_t *)pAdapter;
Leo Changd9df8aa2013-09-26 13:32:26 -07009625 lphbInd = (tSirLPHBInd *)indCont;
Leo Chang9056f462013-08-01 19:21:11 -07009626 skb = cfg80211_testmode_alloc_event_skb(
c_hpothu73f35e62014-04-18 13:40:08 +05309627 pHddCtxt->wiphy,
Leo Changd9df8aa2013-09-26 13:32:26 -07009628 sizeof(tSirLPHBInd),
Leo Chang9056f462013-08-01 19:21:11 -07009629 GFP_ATOMIC);
9630 if (!skb)
9631 {
9632 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9633 "LPHB timeout, NL buffer alloc fail");
9634 return;
9635 }
9636
Leo Changac3ba772013-10-07 09:47:04 -07009637 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_CMD, WLAN_HDD_TM_CMD_WLAN_HB))
Leo Changd9df8aa2013-09-26 13:32:26 -07009638 {
9639 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9640 "WLAN_HDD_TM_ATTR_CMD put fail");
9641 goto nla_put_failure;
9642 }
Leo Changac3ba772013-10-07 09:47:04 -07009643 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_TYPE, lphbInd->protocolType))
Leo Changd9df8aa2013-09-26 13:32:26 -07009644 {
9645 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9646 "WLAN_HDD_TM_ATTR_TYPE put fail");
9647 goto nla_put_failure;
9648 }
Leo Changac3ba772013-10-07 09:47:04 -07009649 if(nla_put(skb, WLAN_HDD_TM_ATTR_DATA,
Leo Changd9df8aa2013-09-26 13:32:26 -07009650 sizeof(tSirLPHBInd), lphbInd))
9651 {
9652 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9653 "WLAN_HDD_TM_ATTR_DATA put fail");
9654 goto nla_put_failure;
9655 }
Leo Chang9056f462013-08-01 19:21:11 -07009656 cfg80211_testmode_event(skb, GFP_ATOMIC);
9657 return;
9658
9659nla_put_failure:
9660 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9661 "NLA Put fail");
9662 kfree_skb(skb);
9663
9664 return;
9665}
9666#endif /* FEATURE_WLAN_LPHB */
9667
9668static int wlan_hdd_cfg80211_testmode(struct wiphy *wiphy, void *data, int len)
9669{
9670 struct nlattr *tb[WLAN_HDD_TM_ATTR_MAX + 1];
9671 int err = 0;
9672#ifdef FEATURE_WLAN_LPHB
9673 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Leo Changd9df8aa2013-09-26 13:32:26 -07009674 eHalStatus smeStatus;
Leo Chang9056f462013-08-01 19:21:11 -07009675#endif /* FEATURE_WLAN_LPHB */
9676
9677 err = nla_parse(tb, WLAN_HDD_TM_ATTR_MAX, data, len, wlan_hdd_tm_policy);
9678 if (err)
9679 {
9680 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9681 "%s Testmode INV ATTR", __func__);
9682 return err;
9683 }
9684
9685 if (!tb[WLAN_HDD_TM_ATTR_CMD])
9686 {
9687 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9688 "%s Testmode INV CMD", __func__);
9689 return -EINVAL;
9690 }
9691
9692 switch (nla_get_u32(tb[WLAN_HDD_TM_ATTR_CMD]))
9693 {
9694#ifdef FEATURE_WLAN_LPHB
9695 /* Low Power Heartbeat configuration request */
9696 case WLAN_HDD_TM_CMD_WLAN_HB:
9697 {
9698 int buf_len;
9699 void *buf;
9700 tSirLPHBReq *hb_params = NULL;
Amar Singhal05852702014-02-04 14:40:00 -08009701 tSirLPHBReq *hb_params_temp = NULL;
Leo Chang9056f462013-08-01 19:21:11 -07009702
9703 if (!tb[WLAN_HDD_TM_ATTR_DATA])
9704 {
9705 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9706 "%s Testmode INV DATA", __func__);
9707 return -EINVAL;
9708 }
9709
9710 buf = nla_data(tb[WLAN_HDD_TM_ATTR_DATA]);
9711 buf_len = nla_len(tb[WLAN_HDD_TM_ATTR_DATA]);
Amar Singhal05852702014-02-04 14:40:00 -08009712
9713 hb_params_temp =(tSirLPHBReq *)buf;
9714 if ((hb_params_temp->cmd == LPHB_SET_TCP_PARAMS_INDID) &&
9715 (hb_params_temp->params.lphbTcpParamReq.timePeriodSec == 0))
9716 return -EINVAL;
9717
Leo Chang9056f462013-08-01 19:21:11 -07009718 hb_params = (tSirLPHBReq *)vos_mem_malloc(sizeof(tSirLPHBReq));
9719 if (NULL == hb_params)
9720 {
9721 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9722 "%s Request Buffer Alloc Fail", __func__);
9723 return -EINVAL;
9724 }
9725
9726 vos_mem_copy(hb_params, buf, buf_len);
Leo Changd9df8aa2013-09-26 13:32:26 -07009727 smeStatus = sme_LPHBConfigReq((tHalHandle)(pHddCtx->hHal),
9728 hb_params,
9729 wlan_hdd_cfg80211_lphb_ind_handler);
9730 if (eHAL_STATUS_SUCCESS != smeStatus)
Leo Chang9056f462013-08-01 19:21:11 -07009731 {
Leo Changd9df8aa2013-09-26 13:32:26 -07009732 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9733 "LPHB Config Fail, disable");
Leo Chang9056f462013-08-01 19:21:11 -07009734 vos_mem_free(hb_params);
9735 }
Leo Chang9056f462013-08-01 19:21:11 -07009736 return 0;
9737 }
9738#endif /* FEATURE_WLAN_LPHB */
9739 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309740 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9741 "%s: unsupported event",__func__);
Leo Chang9056f462013-08-01 19:21:11 -07009742 return -EOPNOTSUPP;
9743 }
9744
9745 return err;
9746}
9747#endif /* CONFIG_NL80211_TESTMODE */
9748
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +05309749static int wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
9750 struct net_device *dev,
9751 int idx, struct survey_info *survey)
9752{
9753 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
9754 hdd_context_t *pHddCtx;
Mihir Sheted9072e02013-08-21 17:02:29 +05309755 hdd_station_ctx_t *pHddStaCtx;
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +05309756 tHalHandle halHandle;
Mihir Sheted9072e02013-08-21 17:02:29 +05309757 v_U32_t channel = 0, freq = 0; /* Initialization Required */
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +05309758 v_S7_t snr,rssi;
9759 int status, i, j, filled = 0;
9760
9761 ENTER();
9762
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +05309763 if (NULL == pAdapter)
9764 {
9765 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
9766 "%s: HDD adapter is Null", __func__);
9767 return -ENODEV;
9768 }
9769
9770 if (NULL == wiphy)
9771 {
9772 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
9773 "%s: wiphy is Null", __func__);
9774 return -ENODEV;
9775 }
9776
9777 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9778 status = wlan_hdd_validate_context(pHddCtx);
9779
9780 if (0 != status)
9781 {
9782 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9783 "%s: HDD context is not valid", __func__);
9784 return status;
9785 }
9786
Mihir Sheted9072e02013-08-21 17:02:29 +05309787 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9788
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +05309789 if (0 == pHddCtx->cfg_ini->fEnableSNRMonitoring ||
Mihir Sheted9072e02013-08-21 17:02:29 +05309790 0 != pAdapter->survey_idx ||
9791 eConnectionState_Associated != pHddStaCtx->conn_info.connState)
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +05309792 {
9793 /* The survey dump ops when implemented completely is expected to
9794 * return a survey of all channels and the ops is called by the
9795 * kernel with incremental values of the argument 'idx' till it
9796 * returns -ENONET. But we can only support the survey for the
9797 * operating channel for now. survey_idx is used to track
9798 * that the ops is called only once and then return -ENONET for
9799 * the next iteration
9800 */
9801 pAdapter->survey_idx = 0;
9802 return -ENONET;
9803 }
9804
9805 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
9806
9807 wlan_hdd_get_snr(pAdapter, &snr);
9808 wlan_hdd_get_rssi(pAdapter, &rssi);
9809
9810 sme_GetOperationChannel(halHandle, &channel, pAdapter->sessionId);
9811 hdd_wlan_get_freq(channel, &freq);
9812
9813
9814 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
9815 {
9816 if (NULL == wiphy->bands[i])
9817 {
9818 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
9819 "%s: wiphy->bands[i] is NULL, i = %d", __func__, i);
9820 continue;
9821 }
9822
9823 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
9824 {
9825 struct ieee80211_supported_band *band = wiphy->bands[i];
9826
9827 if (band->channels[j].center_freq == (v_U16_t)freq)
9828 {
9829 survey->channel = &band->channels[j];
9830 /* The Rx BDs contain SNR values in dB for the received frames
9831 * while the supplicant expects noise. So we calculate and
9832 * return the value of noise (dBm)
9833 * SNR (dB) = RSSI (dBm) - NOISE (dBm)
9834 */
9835 survey->noise = rssi - snr;
9836 survey->filled = SURVEY_INFO_NOISE_DBM;
9837 filled = 1;
9838 }
9839 }
9840 }
9841
9842 if (filled)
9843 pAdapter->survey_idx = 1;
9844 else
9845 {
9846 pAdapter->survey_idx = 0;
9847 return -ENONET;
9848 }
9849
9850 return 0;
9851}
9852
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05309853/*
9854 * FUNCTION: wlan_hdd_cfg80211_resume_wlan
9855 * this is called when cfg80211 driver resume
9856 * driver updates latest sched_scan scan result(if any) to cfg80211 database
9857 */
9858int wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
9859{
9860 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
9861 hdd_adapter_t *pAdapter;
9862 hdd_adapter_list_node_t *pAdapterNode, *pNext;
9863 VOS_STATUS status = VOS_STATUS_SUCCESS;
9864
9865 ENTER();
9866
9867 if ( NULL == pHddCtx )
9868 {
9869 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
9870 "%s: HddCtx validation failed", __func__);
9871 return 0;
9872 }
9873
9874 if (pHddCtx->isLogpInProgress)
9875 {
9876 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9877 "%s: LOGP in Progress. Ignore!!!", __func__);
9878 return 0;
9879 }
9880
Mihir Shete18156292014-03-11 15:38:30 +05309881 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05309882 {
9883 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9884 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
9885 return 0;
9886 }
9887
9888 spin_lock(&pHddCtx->schedScan_lock);
9889 pHddCtx->isWiphySuspended = FALSE;
9890 if (TRUE != pHddCtx->isSchedScanUpdatePending)
9891 {
9892 spin_unlock(&pHddCtx->schedScan_lock);
9893 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9894 "%s: Return resume is not due to PNO indication", __func__);
9895 return 0;
9896 }
9897 // Reset flag to avoid updatating cfg80211 data old results again
9898 pHddCtx->isSchedScanUpdatePending = FALSE;
9899 spin_unlock(&pHddCtx->schedScan_lock);
9900
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +05309901
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05309902 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
9903
9904 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
9905 {
9906 pAdapter = pAdapterNode->pAdapter;
9907 if ( (NULL != pAdapter) &&
9908 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) )
9909 {
9910 if (0 != wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter))
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +05309911 {
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05309912 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
9913 "%s: NO SCAN result", __func__);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +05309914 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05309915 else
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +05309916 {
9917 /* Acquire wakelock to handle the case where APP's tries to
9918 * suspend immediately after updating the scan results. Whis
9919 * results in app's is in suspended state and not able to
9920 * process the connect request to AP
9921 */
9922 hdd_prevent_suspend_timeout(2000);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05309923 cfg80211_sched_scan_results(pHddCtx->wiphy);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +05309924 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05309925
9926 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9927 "%s : cfg80211 scan result database updated", __func__);
9928
9929 return 0;
9930
9931 }
9932 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
9933 pAdapterNode = pNext;
9934 }
9935
9936 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9937 "%s: Failed to find Adapter", __func__);
9938 return 0;
9939}
9940
9941/*
9942 * FUNCTION: wlan_hdd_cfg80211_suspend_wlan
9943 * this is called when cfg80211 driver suspends
9944 */
9945int wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
9946 struct cfg80211_wowlan *wow)
9947{
9948 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
9949
9950 ENTER();
9951 if (NULL == pHddCtx)
9952 {
9953 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
9954 "%s: HddCtx validation failed", __func__);
9955 return 0;
9956 }
9957
9958 pHddCtx->isWiphySuspended = TRUE;
9959
9960 EXIT();
9961
9962 return 0;
9963}
9964
Jeff Johnson295189b2012-06-20 16:38:30 -07009965/* cfg80211_ops */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309966static struct cfg80211_ops wlan_hdd_cfg80211_ops =
Jeff Johnson295189b2012-06-20 16:38:30 -07009967{
9968 .add_virtual_intf = wlan_hdd_add_virtual_intf,
9969 .del_virtual_intf = wlan_hdd_del_virtual_intf,
9970 .change_virtual_intf = wlan_hdd_cfg80211_change_iface,
9971 .change_station = wlan_hdd_change_station,
9972#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
9973 .add_beacon = wlan_hdd_cfg80211_add_beacon,
9974 .del_beacon = wlan_hdd_cfg80211_del_beacon,
9975 .set_beacon = wlan_hdd_cfg80211_set_beacon,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009976#else
9977 .start_ap = wlan_hdd_cfg80211_start_ap,
9978 .change_beacon = wlan_hdd_cfg80211_change_beacon,
9979 .stop_ap = wlan_hdd_cfg80211_stop_ap,
Jeff Johnson295189b2012-06-20 16:38:30 -07009980#endif
9981 .change_bss = wlan_hdd_cfg80211_change_bss,
9982 .add_key = wlan_hdd_cfg80211_add_key,
9983 .get_key = wlan_hdd_cfg80211_get_key,
9984 .del_key = wlan_hdd_cfg80211_del_key,
9985 .set_default_key = wlan_hdd_cfg80211_set_default_key,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -08009986#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07009987 .set_channel = wlan_hdd_cfg80211_set_channel,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -08009988#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009989 .scan = wlan_hdd_cfg80211_scan,
9990 .connect = wlan_hdd_cfg80211_connect,
9991 .disconnect = wlan_hdd_cfg80211_disconnect,
9992 .join_ibss = wlan_hdd_cfg80211_join_ibss,
9993 .leave_ibss = wlan_hdd_cfg80211_leave_ibss,
9994 .set_wiphy_params = wlan_hdd_cfg80211_set_wiphy_params,
9995 .set_tx_power = wlan_hdd_cfg80211_set_txpower,
9996 .get_tx_power = wlan_hdd_cfg80211_get_txpower,
Jeff Johnson295189b2012-06-20 16:38:30 -07009997 .remain_on_channel = wlan_hdd_cfg80211_remain_on_channel,
9998 .cancel_remain_on_channel = wlan_hdd_cfg80211_cancel_remain_on_channel,
DARAM SUDHA39eede62014-02-12 11:16:40 +05309999 .mgmt_tx = wlan_hdd_mgmt_tx,
Jeff Johnson295189b2012-06-20 16:38:30 -070010000#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
10001 .mgmt_tx_cancel_wait = wlan_hdd_cfg80211_mgmt_tx_cancel_wait,
10002 .set_default_mgmt_key = wlan_hdd_set_default_mgmt_key,
10003 .set_txq_params = wlan_hdd_set_txq_params,
10004#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010005 .get_station = wlan_hdd_cfg80211_get_station,
10006 .set_power_mgmt = wlan_hdd_cfg80211_set_power_mgmt,
10007 .del_station = wlan_hdd_cfg80211_del_station,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010008 .add_station = wlan_hdd_cfg80211_add_station,
10009#ifdef FEATURE_WLAN_LFR
10010 .set_pmksa = wlan_hdd_cfg80211_set_pmksa,
10011 .del_pmksa = wlan_hdd_cfg80211_del_pmksa,
10012 .flush_pmksa = wlan_hdd_cfg80211_flush_pmksa,
10013#endif
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070010014#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
10015 .update_ft_ies = wlan_hdd_cfg80211_update_ft_ies,
10016#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080010017#ifdef FEATURE_WLAN_TDLS
10018 .tdls_mgmt = wlan_hdd_cfg80211_tdls_mgmt,
10019 .tdls_oper = wlan_hdd_cfg80211_tdls_oper,
10020#endif
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053010021#ifdef WLAN_FEATURE_GTK_OFFLOAD
10022 .set_rekey_data = wlan_hdd_cfg80211_set_rekey_data,
10023#endif /* WLAN_FEATURE_GTK_OFFLOAD */
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053010024#ifdef FEATURE_WLAN_SCAN_PNO
10025 .sched_scan_start = wlan_hdd_cfg80211_sched_scan_start,
10026 .sched_scan_stop = wlan_hdd_cfg80211_sched_scan_stop,
10027#endif /*FEATURE_WLAN_SCAN_PNO */
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053010028 .resume = wlan_hdd_cfg80211_resume_wlan,
10029 .suspend = wlan_hdd_cfg80211_suspend_wlan,
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053010030 .set_mac_acl = wlan_hdd_cfg80211_set_mac_acl,
Leo Chang9056f462013-08-01 19:21:11 -070010031#ifdef WLAN_NL80211_TESTMODE
10032 .testmode_cmd = wlan_hdd_cfg80211_testmode,
10033#endif
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053010034 .dump_survey = wlan_hdd_cfg80211_dump_survey,
Jeff Johnson295189b2012-06-20 16:38:30 -070010035};
10036