blob: 0a45b277ee75c7e34fbcda679a9cdf9b12154415 [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/*
Rashmi Ramannab1429032014-04-26 14:59:09 +05305044 * FUNCTION: hdd_isConnectionInProgress
5045 * Go through each adapter and check if Connection is in progress
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08005046 *
5047 */
Rashmi Ramannab1429032014-04-26 14:59:09 +05305048v_BOOL_t hdd_isConnectionInProgress( hdd_context_t *pHddCtx )
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08005049{
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,
Rashmi Ramannab1429032014-04-26 14:59:09 +05305060 FL("BTCoex Mode operation in progress"));
5061 return VOS_TRUE;
c_hpothu9b781ba2013-12-30 20:57:45 +05305062 }
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);
Rashmi Ramannab1429032014-04-26 14:59:09 +05305075 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 (eConnectionState_Connecting ==
5079 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
5080 {
5081 hddLog(VOS_TRACE_LEVEL_ERROR,
5082 "%s: %p(%d) Connection is in progress", __func__,
5083 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
5084 return VOS_TRUE;
5085 }
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08005086 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
5087 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
5088 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
5089 {
5090 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
5091 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
5092 (VOS_FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
5093 {
5094 staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]);
5095 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain24bafea2013-11-15 15:10:03 -08005096 "%s: client " MAC_ADDRESS_STR
5097 " is in the middle of WPS/EAPOL exchange.", __func__,
5098 MAC_ADDR_ARRAY(staMac));
Rashmi Ramannab1429032014-04-26 14:59:09 +05305099 return VOS_TRUE;
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08005100 }
5101 }
5102 else if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) ||
5103 (WLAN_HDD_P2P_GO == pAdapter->device_mode))
5104 {
5105 for (staId = 0; staId < WLAN_MAX_STA_COUNT; staId++)
5106 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305107 if ((pAdapter->aStaInfo[staId].isUsed) &&
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08005108 (WLANTL_STA_CONNECTED == pAdapter->aStaInfo[staId].tlSTAState))
5109 {
5110 staMac = (v_U8_t *) &(pAdapter->aStaInfo[staId].macAddrSTA.bytes[0]);
5111
5112 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain24bafea2013-11-15 15:10:03 -08005113 "%s: client " MAC_ADDRESS_STR " of SoftAP/P2P-GO is in the "
5114 "middle of WPS/EAPOL exchange.", __func__,
5115 MAC_ADDR_ARRAY(staMac));
Rashmi Ramannab1429032014-04-26 14:59:09 +05305116 return VOS_TRUE;
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08005117 }
5118 }
5119 }
5120 }
5121 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
5122 pAdapterNode = pNext;
5123 }
Rashmi Ramannab1429032014-04-26 14:59:09 +05305124 return VOS_FALSE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305125}
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08005126
5127/*
Jeff Johnson295189b2012-06-20 16:38:30 -07005128 * FUNCTION: wlan_hdd_cfg80211_scan
5129 * this scan respond to scan trigger and update cfg80211 scan database
5130 * later, scan dump command can be used to recieve scan results
5131 */
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -08005132int wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
5133#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
5134 struct net_device *dev,
5135#endif
5136 struct cfg80211_scan_request *request)
5137{
5138#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
5139 struct net_device *dev = request->wdev->netdev;
5140#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305141 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Jeff Johnson295189b2012-06-20 16:38:30 -07005142 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
5143 hdd_wext_state_t *pwextBuf = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305144 hdd_config_t *cfg_param = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07005145 tCsrScanRequest scanRequest;
5146 tANI_U8 *channelList = NULL, i;
5147 v_U32_t scanId = 0;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305148 int status;
5149 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07005150 v_U8_t* pP2pIe = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07005151
5152 ENTER();
5153
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05305154 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
5155 TRACE_CODE_HDD_CFG80211_SCAN,
5156 pAdapter->sessionId, request->n_channels));
5157
Arif Hussain6d2a3322013-11-17 19:50:10 -08005158 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07005159 __func__,pAdapter->device_mode);
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08005160
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305161 status = wlan_hdd_validate_context(pHddCtx);
5162
5163 if (0 != status)
5164 {
5165 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5166 "%s: HDD context is not valid", __func__);
5167 return status;
5168 }
5169
5170 cfg_param = pHddCtx->cfg_ini;
5171 pScanInfo = &pHddCtx->scan_info;
5172
Jeff Johnson295189b2012-06-20 16:38:30 -07005173#ifdef WLAN_BTAMP_FEATURE
5174 //Scan not supported when AMP traffic is on.
Gopichand Nakkala681989c2013-03-06 22:27:48 -08005175 if (VOS_TRUE == WLANBAP_AmpSessionOn())
Jeff Johnson295189b2012-06-20 16:38:30 -07005176 {
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08005177 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07005178 "%s: No scanning when AMP is on", __func__);
5179 return -EOPNOTSUPP;
5180 }
5181#endif
5182 //Scan on any other interface is not supported.
Gopichand Nakkala681989c2013-03-06 22:27:48 -08005183 if (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07005184 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -08005185 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07005186 "%s: Not scanning on device_mode = %d",
5187 __func__, pAdapter->device_mode);
5188 return -EOPNOTSUPP;
5189 }
5190
5191 if (TRUE == pScanInfo->mScanPending)
5192 {
Kiet Lamac06e2c2013-10-23 16:25:07 +05305193 if ( MAX_PENDING_LOG > pScanInfo->mScanPendingCounter++ )
5194 {
5195 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: mScanPending is TRUE", __func__);
5196 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08005197 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -07005198 }
5199
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305200 //Don't Allow Scan and return busy if Remain On
Jeff Johnson32d95a32012-09-10 13:15:23 -07005201 //Channel and action frame is pending
5202 //Otherwise Cancel Remain On Channel and allow Scan
5203 //If no action frame pending
Gopichand Nakkala681989c2013-03-06 22:27:48 -08005204 if (0 != wlan_hdd_check_remain_on_channel(pAdapter))
Jeff Johnson32d95a32012-09-10 13:15:23 -07005205 {
Kiet Lamac06e2c2013-10-23 16:25:07 +05305206 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Remain On Channel Pending", __func__);
Jeff Johnson32d95a32012-09-10 13:15:23 -07005207 return -EBUSY;
5208 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08005209#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07005210 /* if tdls disagree scan right now, return immediately.
5211 tdls will schedule the scan when scan is allowed. (return SUCCESS)
5212 or will reject the scan if any TDLS is in progress. (return -EBUSY)
5213 */
5214 status = wlan_hdd_tdls_scan_callback (pAdapter,
5215 wiphy,
5216#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
5217 dev,
Gopichand Nakkalac3c42b92013-03-20 19:42:34 -07005218#endif
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07005219 request);
5220 if(status <= 0)
5221 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05305222 if(!status)
5223 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS in progress."
5224 "scan rejected %d", __func__, status);
5225 else
5226 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS teardown is ongoing %d",
5227 __func__, status);
5228
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07005229 return status;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08005230 }
5231#endif
Jeff Johnson32d95a32012-09-10 13:15:23 -07005232
Jeff Johnson295189b2012-06-20 16:38:30 -07005233 if (mutex_lock_interruptible(&pHddCtx->tmInfo.tmOperationLock))
5234 {
5235 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_ERROR,
Jeff Johnson1250df42012-12-10 14:31:52 -08005236 "%s: Acquire lock fail", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005237 return -EAGAIN;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305238 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005239 if (TRUE == pHddCtx->tmInfo.tmAction.enterImps)
5240 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05305241 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07005242 "%s: MAX TM Level Scan not allowed", __func__);
5243 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305244 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -07005245 }
5246 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
5247
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08005248 /* Check if scan is allowed at this point of time.
5249 */
Rashmi Ramannab1429032014-04-26 14:59:09 +05305250 if (hdd_isConnectionInProgress(pHddCtx))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08005251 {
5252 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Scan not allowed", __func__);
5253 return -EBUSY;
5254 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305255
Jeff Johnson295189b2012-06-20 16:38:30 -07005256 vos_mem_zero( &scanRequest, sizeof(scanRequest));
5257
5258 if (NULL != request)
5259 {
5260 hddLog(VOS_TRACE_LEVEL_INFO, "scan request for ssid = %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305261 (int)request->n_ssids);
Jeff Johnson295189b2012-06-20 16:38:30 -07005262
5263 /* Even though supplicant doesn't provide any SSIDs, n_ssids is set to 1.
5264 * Becasue of this, driver is assuming that this is not wildcard scan and so
5265 * is not aging out the scan results.
5266 */
Jeff Johnson32d95a32012-09-10 13:15:23 -07005267 if (request->ssids && '\0' == request->ssids->ssid[0])
Jeff Johnson295189b2012-06-20 16:38:30 -07005268 {
5269 request->n_ssids = 0;
5270 }
5271
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07005272 if ((request->ssids) && (0 < request->n_ssids))
Jeff Johnson295189b2012-06-20 16:38:30 -07005273 {
5274 tCsrSSIDInfo *SsidInfo;
5275 int j;
5276 scanRequest.SSIDs.numOfSSIDs = request->n_ssids;
5277 /* Allocate num_ssid tCsrSSIDInfo structure */
5278 SsidInfo = scanRequest.SSIDs.SSIDList =
5279 ( tCsrSSIDInfo *)vos_mem_malloc(
5280 request->n_ssids*sizeof(tCsrSSIDInfo));
5281
5282 if(NULL == scanRequest.SSIDs.SSIDList)
5283 {
5284 hddLog(VOS_TRACE_LEVEL_ERROR,
Nirav Shah20ac06f2013-12-12 18:14:06 +05305285 "%s: memory alloc failed SSIDInfo buffer", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005286 return -ENOMEM;
5287 }
5288
5289 /* copy all the ssid's and their length */
5290 for(j = 0; j < request->n_ssids; j++, SsidInfo++)
5291 {
5292 /* get the ssid length */
5293 SsidInfo->SSID.length = request->ssids[j].ssid_len;
5294 vos_mem_copy(SsidInfo->SSID.ssId, &request->ssids[j].ssid[0],
5295 SsidInfo->SSID.length);
5296 SsidInfo->SSID.ssId[SsidInfo->SSID.length] = '\0';
Nirav Shah20ac06f2013-12-12 18:14:06 +05305297 hddLog(VOS_TRACE_LEVEL_INFO, "SSID number %d: %s",
Jeff Johnson295189b2012-06-20 16:38:30 -07005298 j, SsidInfo->SSID.ssId);
5299 }
5300 /* set the scan type to active */
5301 scanRequest.scanType = eSIR_ACTIVE_SCAN;
5302 }
5303 else if(WLAN_HDD_P2P_GO == pAdapter->device_mode)
5304 {
5305 /* set the scan type to active */
5306 scanRequest.scanType = eSIR_ACTIVE_SCAN;
5307 }
5308 else
5309 {
5310 /*Set the scan type to default type, in this case it is ACTIVE*/
5311 scanRequest.scanType = pScanInfo->scan_mode;
5312 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305313 scanRequest.minChnTime = cfg_param->nActiveMinChnTime;
Jeff Johnson295189b2012-06-20 16:38:30 -07005314 scanRequest.maxChnTime = cfg_param->nActiveMaxChnTime;
5315 }
5316 else
5317 {
5318 /* set the scan type to active */
5319 scanRequest.scanType = eSIR_ACTIVE_SCAN;
5320 vos_mem_set( scanRequest.bssid, sizeof( tCsrBssid ), 0xff );
5321
5322 /* set min and max channel time to zero */
5323 scanRequest.minChnTime = 0;
5324 scanRequest.maxChnTime = 0;
5325 }
5326
5327 /* set BSSType to default type */
5328 scanRequest.BSSType = eCSR_BSS_TYPE_ANY;
5329
5330 /*TODO: scan the requested channels only*/
5331
5332 /*Right now scanning all the channels */
5333 if( request )
5334 {
c_hpothu53512302014-04-15 18:49:53 +05305335 if (MAX_CHANNEL < request->n_channels)
5336 {
5337 hddLog(VOS_TRACE_LEVEL_WARN,
5338 "No of Scan Channels exceeded limit: %d", request->n_channels);
5339 request->n_channels = MAX_CHANNEL;
5340 }
Nirav Shah20ac06f2013-12-12 18:14:06 +05305341 hddLog(VOS_TRACE_LEVEL_INFO,
5342 "No of Scan Channels: %d", request->n_channels);
c_hpothu53512302014-04-15 18:49:53 +05305343
Jeff Johnson295189b2012-06-20 16:38:30 -07005344 if( request->n_channels )
5345 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05305346 char chList [(request->n_channels*5)+1];
5347 int len;
Jeff Johnson295189b2012-06-20 16:38:30 -07005348 channelList = vos_mem_malloc( request->n_channels );
5349 if( NULL == channelList )
5350 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305351 hddLog(VOS_TRACE_LEVEL_ERROR,
Nirav Shah20ac06f2013-12-12 18:14:06 +05305352 "%s: memory alloc failed channelList", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005353 status = -ENOMEM;
5354 goto free_mem;
5355 }
5356
Nirav Shah20ac06f2013-12-12 18:14:06 +05305357 for( i = 0, len = 0; i < request->n_channels ; i++ )
5358 {
Jeff Johnson295189b2012-06-20 16:38:30 -07005359 channelList[i] = request->channels[i]->hw_value;
Nirav Shah20ac06f2013-12-12 18:14:06 +05305360 len += snprintf(chList+len, 5, "%d ", channelList[i]);
5361 }
5362
5363 hddLog(VOS_TRACE_LEVEL_INFO,
5364 "Channel-List: %s ", chList);
Jeff Johnson295189b2012-06-20 16:38:30 -07005365 }
5366
5367 scanRequest.ChannelInfo.numOfChannels = request->n_channels;
5368 scanRequest.ChannelInfo.ChannelList = channelList;
5369
5370 /* set requestType to full scan */
5371 scanRequest.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305372
5373 /* Flush the scan results(only p2p beacons) for STA scan and P2P
Madan Mohan Koyyalamudi8d50f312012-11-27 15:48:57 -08005374 * search (Flush on both full scan and social scan but not on single
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305375 * channel scan).P2P search happens on 3 social channels (1, 6, 11)
Madan Mohan Koyyalamudi8d50f312012-11-27 15:48:57 -08005376 */
5377
5378 /* Supplicant does single channel scan after 8-way handshake
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305379 * and in that case driver shoudnt flush scan results. If
5380 * driver flushes the scan results here and unfortunately if
5381 * the AP doesnt respond to our probe req then association
Madan Mohan Koyyalamudi8d50f312012-11-27 15:48:57 -08005382 * fails which is not desired
5383 */
5384
5385 if( request->n_channels != WLAN_HDD_P2P_SINGLE_CHANNEL_SCAN )
5386 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05305387 hddLog(VOS_TRACE_LEVEL_DEBUG, "Flushing P2P Results");
Madan Mohan Koyyalamudi8d50f312012-11-27 15:48:57 -08005388 sme_ScanFlushP2PResult( WLAN_HDD_GET_HAL_CTX(pAdapter),
5389 pAdapter->sessionId );
5390 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005391
5392 if( request->ie_len )
5393 {
5394 /* save this for future association (join requires this) */
Agarwal Ashish4f616132013-12-30 23:32:50 +05305395 /*TODO: Array needs to be converted to dynamic allocation,
5396 * as multiple ie.s can be sent in cfg80211_scan_request structure
5397 * CR 597966
5398 */
Jeff Johnson295189b2012-06-20 16:38:30 -07005399 memset( &pScanInfo->scanAddIE, 0, sizeof(pScanInfo->scanAddIE) );
5400 memcpy( pScanInfo->scanAddIE.addIEdata, request->ie, request->ie_len);
5401 pScanInfo->scanAddIE.length = request->ie_len;
5402
Agarwal Ashish4f616132013-12-30 23:32:50 +05305403 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Jeff Johnsone7245742012-09-05 17:12:55 -07005404 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
Agarwal Ashish4f616132013-12-30 23:32:50 +05305405 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -07005406 {
Agarwal Ashish4f616132013-12-30 23:32:50 +05305407 if ( request->ie_len <= SIR_MAC_MAX_IE_LENGTH)
5408 {
5409 pwextBuf->roamProfile.nAddIEScanLength = request->ie_len;
5410 memcpy( pwextBuf->roamProfile.addIEScan,
5411 request->ie, request->ie_len);
5412 }
5413 else
5414 {
5415 hddLog(VOS_TRACE_LEVEL_ERROR, "Scan Ie length is invalid:"
Arun Kumar Khandavalli75eeb122014-03-27 21:43:12 +05305416 "%zu", request->ie_len);
Agarwal Ashish4f616132013-12-30 23:32:50 +05305417 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005418
Agarwal Ashish4f616132013-12-30 23:32:50 +05305419 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005420 scanRequest.uIEFieldLen = pScanInfo->scanAddIE.length;
5421 scanRequest.pIEField = pScanInfo->scanAddIE.addIEdata;
5422
Jeff Johnson295189b2012-06-20 16:38:30 -07005423 pP2pIe = wlan_hdd_get_p2p_ie_ptr((v_U8_t*)request->ie,
5424 request->ie_len);
5425 if (pP2pIe != NULL)
5426 {
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07005427#ifdef WLAN_FEATURE_P2P_DEBUG
5428 if (((globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED) ||
5429 (globalP2PConnectionStatus == P2P_GO_NEG_PROCESS)) &&
5430 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
5431 {
5432 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_1;
5433 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
5434 "Go nego completed to Connection is started");
5435 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
5436 "for 8way Handshake");
5437 }
5438 else if((globalP2PConnectionStatus == P2P_CLIENT_DISCONNECTED_STATE) &&
5439 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
5440 {
5441 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_2;
5442 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
5443 "Disconnected state to Connection is started");
5444 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
5445 "for 4way Handshake");
5446 }
5447#endif
5448
Jeff Johnsone7245742012-09-05 17:12:55 -07005449 /* no_cck will be set during p2p find to disable 11b rates */
5450 if(TRUE == request->no_cck)
Jeff Johnson295189b2012-06-20 16:38:30 -07005451 {
Jeff Johnson295189b2012-06-20 16:38:30 -07005452 hddLog(VOS_TRACE_LEVEL_INFO,
5453 "%s: This is a P2P Search", __func__);
5454 scanRequest.p2pSearch = 1;
Jeff Johnsone7245742012-09-05 17:12:55 -07005455
Jeff Johnsone7245742012-09-05 17:12:55 -07005456 if( request->n_channels == WLAN_HDD_P2P_SOCIAL_CHANNELS )
5457 {
Madan Mohan Koyyalamudi1b1d9e82012-10-21 11:38:33 -07005458 /* set requestType to P2P Discovery */
5459 scanRequest.requestType = eCSR_SCAN_P2P_DISCOVERY;
Jeff Johnsone7245742012-09-05 17:12:55 -07005460 }
5461
5462 /*
5463 Skip Dfs Channel in case of P2P Search
5464 if it is set in ini file
5465 */
5466 if(cfg_param->skipDfsChnlInP2pSearch)
5467 {
5468 scanRequest.skipDfsChnlInP2pSearch = 1;
5469 }
5470 else
5471 {
5472 scanRequest.skipDfsChnlInP2pSearch = 0;
5473 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005474
Jeff Johnson295189b2012-06-20 16:38:30 -07005475 }
5476 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005477 }
5478 }
5479
5480 INIT_COMPLETION(pScanInfo->scan_req_completion_event);
5481
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07005482 /* acquire the wakelock to avoid the apps suspend during the scan. To
5483 * address the following issues.
5484 * 1) Disconnected scenario: we are not allowing the suspend as WLAN is not in
5485 * BMPS/IMPS this result in android trying to suspend aggressively and backing off
5486 * for long time, this result in apps running at full power for long time.
5487 * 2) Connected scenario: If we allow the suspend during the scan, RIVA will
5488 * be stuck in full power because of resume BMPS
5489 */
5490 hdd_prevent_suspend();
Jeff Johnsone7245742012-09-05 17:12:55 -07005491
Nirav Shah20ac06f2013-12-12 18:14:06 +05305492 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
5493 "requestType %d, scanType %d, minChnTime %d, maxChnTime %d,"
5494 "p2pSearch %d, skipDfsChnlInP2pSearch %d", scanRequest.requestType,
5495 scanRequest.scanType, scanRequest.minChnTime, scanRequest.maxChnTime,
5496 scanRequest.p2pSearch, scanRequest.skipDfsChnlInP2pSearch);
5497
Jeff Johnsone7245742012-09-05 17:12:55 -07005498 status = sme_ScanRequest( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07005499 pAdapter->sessionId, &scanRequest, &scanId,
5500 &hdd_cfg80211_scan_done_callback, dev );
Jeff Johnsone7245742012-09-05 17:12:55 -07005501
Jeff Johnson295189b2012-06-20 16:38:30 -07005502 if (eHAL_STATUS_SUCCESS != status)
5503 {
5504 hddLog(VOS_TRACE_LEVEL_ERROR,
5505 "%s: sme_ScanRequest returned error %d", __func__, status);
5506 complete(&pScanInfo->scan_req_completion_event);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -07005507 if(eHAL_STATUS_RESOURCES == status)
5508 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05305509 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: HO is in progress."
5510 "So defer the scan by informing busy",__func__);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -07005511 status = -EBUSY;
5512 } else {
5513 status = -EIO;
5514 }
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07005515 hdd_allow_suspend();
Jeff Johnson295189b2012-06-20 16:38:30 -07005516 goto free_mem;
5517 }
5518
5519 pScanInfo->mScanPending = TRUE;
5520 pAdapter->request = request;
5521 pScanInfo->scanId = scanId;
5522
5523 complete(&pScanInfo->scan_req_completion_event);
5524
5525free_mem:
5526 if( scanRequest.SSIDs.SSIDList )
5527 {
5528 vos_mem_free(scanRequest.SSIDs.SSIDList);
5529 }
5530
5531 if( channelList )
5532 vos_mem_free( channelList );
5533
5534 EXIT();
5535
5536 return status;
5537}
5538
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07005539
5540void hdd_select_cbmode( hdd_adapter_t *pAdapter,v_U8_t operationChannel)
5541{
5542 v_U8_t iniDot11Mode =
5543 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->dot11Mode;
5544 eHddDot11Mode hddDot11Mode = iniDot11Mode;
5545
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +05305546 hddLog(LOG1, FL("Channel Bonding Mode Selected is %u"),
5547 iniDot11Mode);
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07005548 switch ( iniDot11Mode )
5549 {
5550 case eHDD_DOT11_MODE_AUTO:
5551 case eHDD_DOT11_MODE_11ac:
5552 case eHDD_DOT11_MODE_11ac_ONLY:
5553#ifdef WLAN_FEATURE_11AC
5554 hddDot11Mode = eHDD_DOT11_MODE_11ac;
5555#else
5556 hddDot11Mode = eHDD_DOT11_MODE_11n;
5557#endif
5558 break;
5559 case eHDD_DOT11_MODE_11n:
5560 case eHDD_DOT11_MODE_11n_ONLY:
5561 hddDot11Mode = eHDD_DOT11_MODE_11n;
5562 break;
5563 default:
5564 hddDot11Mode = iniDot11Mode;
5565 break;
5566 }
5567 /* This call decides required channel bonding mode */
5568 sme_SelectCBMode((WLAN_HDD_GET_CTX(pAdapter)->hHal),
5569 hdd_cfg_xlate_to_csr_phy_mode(hddDot11Mode),
5570 operationChannel);
5571}
5572
Jeff Johnson295189b2012-06-20 16:38:30 -07005573/*
5574 * FUNCTION: wlan_hdd_cfg80211_connect_start
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305575 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -07005576 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305577int wlan_hdd_cfg80211_connect_start( hdd_adapter_t *pAdapter,
Jeff Johnson32d95a32012-09-10 13:15:23 -07005578 const u8 *ssid, size_t ssid_len, const u8 *bssid, u8 operatingChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -07005579{
5580 int status = 0;
5581 hdd_wext_state_t *pWextState;
Yue Mae36e3552014-03-05 17:06:20 -08005582 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07005583 v_U32_t roamId;
5584 tCsrRoamProfile *pRoamProfile;
Jeff Johnson295189b2012-06-20 16:38:30 -07005585 eCsrAuthType RSNAuthType;
5586
5587 ENTER();
5588
5589 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Yue Mae36e3552014-03-05 17:06:20 -08005590 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
5591
5592 status = wlan_hdd_validate_context(pHddCtx);
5593 if (status)
5594 {
5595 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5596 "%s: HDD context is not valid!", __func__);
5597 return status;
5598 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305599
Jeff Johnson295189b2012-06-20 16:38:30 -07005600 if (SIR_MAC_MAX_SSID_LENGTH < ssid_len)
5601 {
5602 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wrong SSID len", __func__);
5603 return -EINVAL;
5604 }
5605
5606 pRoamProfile = &pWextState->roamProfile;
5607
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305608 if (pRoamProfile)
Jeff Johnson295189b2012-06-20 16:38:30 -07005609 {
Jeff Johnsone7245742012-09-05 17:12:55 -07005610 hdd_station_ctx_t *pHddStaCtx;
5611 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07005612
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305613 if (HDD_WMM_USER_MODE_NO_QOS ==
Jeff Johnson295189b2012-06-20 16:38:30 -07005614 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->WmmMode)
5615 {
5616 /*QoS not enabled in cfg file*/
5617 pRoamProfile->uapsd_mask = 0;
5618 }
5619 else
5620 {
5621 /*QoS enabled, update uapsd mask from cfg file*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305622 pRoamProfile->uapsd_mask =
Jeff Johnson295189b2012-06-20 16:38:30 -07005623 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask;
5624 }
5625
5626 pRoamProfile->SSIDs.numOfSSIDs = 1;
5627 pRoamProfile->SSIDs.SSIDList->SSID.length = ssid_len;
5628 vos_mem_zero(pRoamProfile->SSIDs.SSIDList->SSID.ssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305629 sizeof(pRoamProfile->SSIDs.SSIDList->SSID.ssId));
Jeff Johnson295189b2012-06-20 16:38:30 -07005630 vos_mem_copy((void *)(pRoamProfile->SSIDs.SSIDList->SSID.ssId),
5631 ssid, ssid_len);
5632
5633 if (bssid)
5634 {
5635 pRoamProfile->BSSIDs.numOfBSSIDs = 1;
5636 vos_mem_copy((void *)(pRoamProfile->BSSIDs.bssid), bssid,
5637 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305638 /* Save BSSID in seperate variable as well, as RoamProfile
5639 BSSID is getting zeroed out in the association process. And in
Jeff Johnson295189b2012-06-20 16:38:30 -07005640 case of join failure we should send valid BSSID to supplicant
5641 */
5642 vos_mem_copy((void *)(pWextState->req_bssId), bssid,
5643 WNI_CFG_BSSID_LEN);
5644 }
Dhanashri Atre51981c62013-06-13 11:47:57 -07005645 else
5646 {
5647 vos_mem_zero((void *)(pRoamProfile->BSSIDs.bssid),WNI_CFG_BSSID_LEN);
5648 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005649
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +05305650 hddLog(LOG1, FL("Connect to SSID: %s opertating Channel: %u"),
5651 pRoamProfile->SSIDs.SSIDList->SSID.ssId, operatingChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -07005652 if ((IW_AUTH_WPA_VERSION_WPA == pWextState->wpaVersion) ||
5653 (IW_AUTH_WPA_VERSION_WPA2 == pWextState->wpaVersion))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305654 {
Jeff Johnson295189b2012-06-20 16:38:30 -07005655 /*set gen ie*/
5656 hdd_SetGENIEToCsr(pAdapter, &RSNAuthType);
5657 /*set auth*/
5658 hdd_set_csr_auth_type(pAdapter, RSNAuthType);
5659 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005660#ifdef FEATURE_WLAN_WAPI
5661 if (pAdapter->wapi_info.nWapiMode)
5662 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005663 hddLog(LOG1, "%s: Setting WAPI AUTH Type and Encryption Mode values", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005664 switch (pAdapter->wapi_info.wapiAuthMode)
5665 {
5666 case WAPI_AUTH_MODE_PSK:
5667 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005668 hddLog(LOG1, "%s: WAPI AUTH TYPE: PSK: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07005669 pAdapter->wapi_info.wapiAuthMode);
5670 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_PSK;
5671 break;
5672 }
5673 case WAPI_AUTH_MODE_CERT:
5674 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005675 hddLog(LOG1, "%s: WAPI AUTH TYPE: CERT: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07005676 pAdapter->wapi_info.wapiAuthMode);
5677 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE;
5678 break;
5679 }
5680 } // End of switch
5681 if ( pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_PSK ||
5682 pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_CERT)
5683 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005684 hddLog(LOG1, "%s: WAPI PAIRWISE/GROUP ENCRYPTION: WPI", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005685 pRoamProfile->AuthType.numEntries = 1;
5686 pRoamProfile->EncryptionType.numEntries = 1;
5687 pRoamProfile->EncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
5688 pRoamProfile->mcEncryptionType.numEntries = 1;
5689 pRoamProfile->mcEncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
5690 }
5691 }
5692#endif /* FEATURE_WLAN_WAPI */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05305693#ifdef WLAN_FEATURE_GTK_OFFLOAD
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05305694 /* Initializing gtkOffloadReqParams */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05305695 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
5696 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
5697 {
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05305698 memset(&pHddStaCtx->gtkOffloadReqParams, 0,
5699 sizeof (tSirGtkOffloadParams));
5700 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_DISABLE;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05305701 }
5702#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005703 pRoamProfile->csrPersona = pAdapter->device_mode;
5704
Jeff Johnson32d95a32012-09-10 13:15:23 -07005705 if( operatingChannel )
5706 {
5707 pRoamProfile->ChannelInfo.ChannelList = &operatingChannel;
5708 pRoamProfile->ChannelInfo.numOfChannels = 1;
5709 }
Chet Lanctot186b5732013-03-18 10:26:30 -07005710 else
5711 {
5712 pRoamProfile->ChannelInfo.ChannelList = NULL;
5713 pRoamProfile->ChannelInfo.numOfChannels = 0;
5714 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07005715 if ( (WLAN_HDD_IBSS == pAdapter->device_mode) && operatingChannel)
5716 {
5717 hdd_select_cbmode(pAdapter,operatingChannel);
5718 }
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +05305719
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08005720 /* change conn_state to connecting before sme_RoamConnect(), because sme_RoamConnect()
5721 * has a direct path to call hdd_smeRoamCallback(), which will change the conn_state
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305722 * If direct path, conn_state will be accordingly changed to NotConnected or Associated
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08005723 * by either hdd_AssociationCompletionHandler() or hdd_DisConnectHandler() in sme_RoamCallback()
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -08005724 * if sme_RomConnect is to be queued, Connecting state will remain until it is completed.
5725 */
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05305726 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
5727 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode)
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -08005728 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
5729 eConnectionState_Connecting);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305730
5731 status = sme_RoamConnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07005732 pAdapter->sessionId, pRoamProfile, &roamId);
5733
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05305734 if ((eHAL_STATUS_SUCCESS != status) &&
5735 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
5736 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +05305737
5738 {
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08005739 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: sme_RoamConnect (session %d) failed with "
5740 "status %d. -> NotConnected", __func__, pAdapter->sessionId, status);
5741 /* change back to NotAssociated */
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +05305742 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08005743 eConnectionState_NotConnected);
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +05305744 }
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -08005745
5746 pRoamProfile->ChannelInfo.ChannelList = NULL;
5747 pRoamProfile->ChannelInfo.numOfChannels = 0;
5748
Jeff Johnson295189b2012-06-20 16:38:30 -07005749 }
5750 else
5751 {
5752 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid Roam profile", __func__);
5753 return -EINVAL;
5754 }
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08005755 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07005756 return status;
5757}
5758
5759/*
5760 * FUNCTION: wlan_hdd_set_cfg80211_auth_type
5761 * This function is used to set the authentication type (OPEN/SHARED).
5762 *
5763 */
5764static int wlan_hdd_cfg80211_set_auth_type(hdd_adapter_t *pAdapter,
5765 enum nl80211_auth_type auth_type)
5766{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305767 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07005768 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
5769
5770 ENTER();
5771
5772 /*set authentication type*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305773 switch (auth_type)
Jeff Johnson295189b2012-06-20 16:38:30 -07005774 {
Jeff Johnson295189b2012-06-20 16:38:30 -07005775 case NL80211_AUTHTYPE_AUTOMATIC:
Gopichand Nakkala29149562013-05-10 21:43:41 +05305776 hddLog(VOS_TRACE_LEVEL_INFO,
5777 "%s: set authentication type to AUTOSWITCH", __func__);
5778 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_AUTOSWITCH;
5779 break;
5780
5781 case NL80211_AUTHTYPE_OPEN_SYSTEM:
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07005782#ifdef WLAN_FEATURE_VOWIFI_11R
5783 case NL80211_AUTHTYPE_FT:
5784#endif /* WLAN_FEATURE_VOWIFI_11R */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305785 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -07005786 "%s: set authentication type to OPEN", __func__);
5787 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
5788 break;
5789
5790 case NL80211_AUTHTYPE_SHARED_KEY:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305791 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -07005792 "%s: set authentication type to SHARED", __func__);
5793 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_SHARED_KEY;
5794 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005795#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -07005796 case NL80211_AUTHTYPE_NETWORK_EAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305797 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -07005798 "%s: set authentication type to CCKM WPA", __func__);
5799 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_CCKM_WPA;//eCSR_AUTH_TYPE_CCKM_RSN needs to be handled as well if required.
5800 break;
5801#endif
5802
5803
5804 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305805 hddLog(VOS_TRACE_LEVEL_ERROR,
5806 "%s: Unsupported authentication type %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07005807 auth_type);
5808 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_UNKNOWN;
5809 return -EINVAL;
5810 }
5811
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305812 pWextState->roamProfile.AuthType.authType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -07005813 pHddStaCtx->conn_info.authType;
5814 return 0;
5815}
5816
5817/*
5818 * FUNCTION: wlan_hdd_set_akm_suite
5819 * This function is used to set the key mgmt type(PSK/8021x).
5820 *
5821 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305822static int wlan_hdd_set_akm_suite( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07005823 u32 key_mgmt
5824 )
5825{
5826 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
5827 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305828
Jeff Johnson295189b2012-06-20 16:38:30 -07005829 /*set key mgmt type*/
5830 switch(key_mgmt)
5831 {
5832 case WLAN_AKM_SUITE_PSK:
Gopichand Nakkala356fb102013-03-06 12:34:04 +05305833#ifdef WLAN_FEATURE_VOWIFI_11R
5834 case WLAN_AKM_SUITE_FT_PSK:
5835#endif
5836 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to PSK",
Jeff Johnson295189b2012-06-20 16:38:30 -07005837 __func__);
5838 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_PSK;
5839 break;
5840
5841 case WLAN_AKM_SUITE_8021X:
Gopichand Nakkala356fb102013-03-06 12:34:04 +05305842#ifdef WLAN_FEATURE_VOWIFI_11R
5843 case WLAN_AKM_SUITE_FT_8021X:
5844#endif
5845 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to 8021x",
Jeff Johnson295189b2012-06-20 16:38:30 -07005846 __func__);
5847 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
5848 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005849#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -07005850#define WLAN_AKM_SUITE_CCKM 0x00409600 /* Should be in ieee802_11_defs.h */
5851#define IW_AUTH_KEY_MGMT_CCKM 8 /* Should be in linux/wireless.h */
5852 case WLAN_AKM_SUITE_CCKM:
5853 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to CCKM",
5854 __func__);
5855 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_CCKM;
5856 break;
5857#endif
5858
5859 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305860 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported key mgmt type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07005861 __func__, key_mgmt);
5862 return -EINVAL;
5863
5864 }
5865 return 0;
5866}
5867
5868/*
5869 * FUNCTION: wlan_hdd_cfg80211_set_cipher
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305870 * This function is used to set the encryption type
Jeff Johnson295189b2012-06-20 16:38:30 -07005871 * (NONE/WEP40/WEP104/TKIP/CCMP).
5872 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305873static int wlan_hdd_cfg80211_set_cipher( hdd_adapter_t *pAdapter,
5874 u32 cipher,
Jeff Johnson295189b2012-06-20 16:38:30 -07005875 bool ucast
5876 )
5877{
5878 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305879 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07005880 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
5881
5882 ENTER();
5883
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305884 if (!cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -07005885 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305886 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: received cipher %d - considering none",
Jeff Johnson295189b2012-06-20 16:38:30 -07005887 __func__, cipher);
5888 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
5889 }
5890 else
5891 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305892
Jeff Johnson295189b2012-06-20 16:38:30 -07005893 /*set encryption method*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305894 switch (cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -07005895 {
5896 case IW_AUTH_CIPHER_NONE:
5897 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
5898 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305899
Jeff Johnson295189b2012-06-20 16:38:30 -07005900 case WLAN_CIPHER_SUITE_WEP40:
Gopichand Nakkala29149562013-05-10 21:43:41 +05305901 encryptionType = eCSR_ENCRYPT_TYPE_WEP40;
Jeff Johnson295189b2012-06-20 16:38:30 -07005902 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305903
Jeff Johnson295189b2012-06-20 16:38:30 -07005904 case WLAN_CIPHER_SUITE_WEP104:
Gopichand Nakkala29149562013-05-10 21:43:41 +05305905 encryptionType = eCSR_ENCRYPT_TYPE_WEP104;
Jeff Johnson295189b2012-06-20 16:38:30 -07005906 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305907
Jeff Johnson295189b2012-06-20 16:38:30 -07005908 case WLAN_CIPHER_SUITE_TKIP:
5909 encryptionType = eCSR_ENCRYPT_TYPE_TKIP;
5910 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305911
Jeff Johnson295189b2012-06-20 16:38:30 -07005912 case WLAN_CIPHER_SUITE_CCMP:
5913 encryptionType = eCSR_ENCRYPT_TYPE_AES;
5914 break;
5915#ifdef FEATURE_WLAN_WAPI
5916 case WLAN_CIPHER_SUITE_SMS4:
5917 encryptionType = eCSR_ENCRYPT_TYPE_WPI;
5918 break;
5919#endif
5920
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005921#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -07005922 case WLAN_CIPHER_SUITE_KRK:
5923 encryptionType = eCSR_ENCRYPT_TYPE_KRK;
5924 break;
5925#endif
5926 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305927 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported cipher type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07005928 __func__, cipher);
5929 return -EOPNOTSUPP;
5930 }
5931 }
5932
5933 if (ucast)
5934 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305935 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting unicast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07005936 __func__, encryptionType);
5937 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
5938 pWextState->roamProfile.EncryptionType.numEntries = 1;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305939 pWextState->roamProfile.EncryptionType.encryptionType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -07005940 encryptionType;
5941 }
5942 else
5943 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305944 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting mcast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07005945 __func__, encryptionType);
5946 pHddStaCtx->conn_info.mcEncryptionType = encryptionType;
5947 pWextState->roamProfile.mcEncryptionType.numEntries = 1;
5948 pWextState->roamProfile.mcEncryptionType.encryptionType[0] = encryptionType;
5949 }
5950
5951 return 0;
5952}
5953
5954
5955/*
5956 * FUNCTION: wlan_hdd_cfg80211_set_ie
5957 * This function is used to parse WPA/RSN IE's.
5958 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305959int wlan_hdd_cfg80211_set_ie( hdd_adapter_t *pAdapter,
5960 u8 *ie,
Jeff Johnson295189b2012-06-20 16:38:30 -07005961 size_t ie_len
5962 )
5963{
5964 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
5965 u8 *genie = ie;
5966 v_U16_t remLen = ie_len;
5967#ifdef FEATURE_WLAN_WAPI
5968 v_U32_t akmsuite[MAX_NUM_AKM_SUITES];
5969 u16 *tmp;
5970 v_U16_t akmsuiteCount;
5971 int *akmlist;
5972#endif
5973 ENTER();
5974
5975 /* clear previous assocAddIE */
5976 pWextState->assocAddIE.length = 0;
5977 pWextState->roamProfile.bWPSAssociation = VOS_FALSE;
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -07005978 pWextState->roamProfile.bOSENAssociation = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07005979
5980 while (remLen >= 2)
5981 {
5982 v_U16_t eLen = 0;
5983 v_U8_t elementId;
5984 elementId = *genie++;
5985 eLen = *genie++;
5986 remLen -= 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305987
Arif Hussain6d2a3322013-11-17 19:50:10 -08005988 hddLog(VOS_TRACE_LEVEL_INFO, "%s: IE[0x%X], LEN[%d]",
Jeff Johnson295189b2012-06-20 16:38:30 -07005989 __func__, elementId, eLen);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305990
5991 switch ( elementId )
Jeff Johnson295189b2012-06-20 16:38:30 -07005992 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305993 case DOT11F_EID_WPA:
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005994 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 -07005995 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305996 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07005997 "%s: Invalid WPA IE", __func__);
5998 return -EINVAL;
5999 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306000 else if (0 == memcmp(&genie[0], "\x00\x50\xf2\x04", 4))
Jeff Johnson295189b2012-06-20 16:38:30 -07006001 {
6002 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306003 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPS IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -07006004 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306005
Jeff Johnson295189b2012-06-20 16:38:30 -07006006 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
6007 {
Jeff Johnson902c9832012-12-10 14:28:09 -08006008 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE. "
6009 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -07006010 VOS_ASSERT(0);
6011 return -ENOMEM;
6012 }
6013 // WSC IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
6014 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
6015 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306016
Jeff Johnson295189b2012-06-20 16:38:30 -07006017 pWextState->roamProfile.bWPSAssociation = VOS_TRUE;
6018 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
6019 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
6020 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306021 else if (0 == memcmp(&genie[0], "\x00\x50\xf2", 3))
6022 {
Jeff Johnson295189b2012-06-20 16:38:30 -07006023 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPA IE (len %d)",__func__, eLen + 2);
6024 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
6025 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2) /*ie_len*/);
6026 pWextState->roamProfile.pWPAReqIE = pWextState->WPARSNIE;
6027 pWextState->roamProfile.nWPAReqIELength = eLen + 2;//ie_len;
6028 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306029 else if ( (0 == memcmp(&genie[0], P2P_OUI_TYPE,
Kiet Lam8da98992013-11-21 15:59:07 +05306030 P2P_OUI_TYPE_SIZE)))
Jeff Johnson295189b2012-06-20 16:38:30 -07006031 {
6032 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306033 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set P2P IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -07006034 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306035
Jeff Johnson295189b2012-06-20 16:38:30 -07006036 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
6037 {
Jeff Johnson902c9832012-12-10 14:28:09 -08006038 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
6039 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -07006040 VOS_ASSERT(0);
6041 return -ENOMEM;
6042 }
6043 // P2P IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
6044 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
6045 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306046
Jeff Johnson295189b2012-06-20 16:38:30 -07006047 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
6048 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
6049 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006050#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306051 else if ( (0 == memcmp(&genie[0], WFD_OUI_TYPE,
6052 WFD_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07006053 /*Consider WFD IE, only for P2P Client */
6054 && (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
6055 {
6056 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306057 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WFD IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -07006058 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306059
Jeff Johnson295189b2012-06-20 16:38:30 -07006060 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
6061 {
Jeff Johnson902c9832012-12-10 14:28:09 -08006062 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
6063 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -07006064 VOS_ASSERT(0);
6065 return -ENOMEM;
6066 }
6067 // WFD IE is saved to Additional IE ; it should be accumulated to handle
6068 // WPS IE + P2P IE + WFD IE
6069 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
6070 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306071
Jeff Johnson295189b2012-06-20 16:38:30 -07006072 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
6073 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
6074 }
6075#endif
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07006076 /* Appending HS 2.0 Indication Element in Assiciation Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306077 else if ( (0 == memcmp(&genie[0], HS20_OUI_TYPE,
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07006078 HS20_OUI_TYPE_SIZE)) )
6079 {
6080 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306081 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set HS20 IE(len %d)",
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07006082 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07006083
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07006084 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
6085 {
Jeff Johnson902c9832012-12-10 14:28:09 -08006086 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
6087 "Need bigger buffer space");
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07006088 VOS_ASSERT(0);
6089 return -ENOMEM;
6090 }
6091 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
6092 pWextState->assocAddIE.length += eLen + 2;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07006093
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07006094 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
6095 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
6096 }
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -07006097 /* Appending OSEN Information Element in Assiciation Request */
6098 else if ( (0 == memcmp(&genie[0], OSEN_OUI_TYPE,
6099 OSEN_OUI_TYPE_SIZE)) )
6100 {
6101 v_U16_t curAddIELen = pWextState->assocAddIE.length;
6102 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set OSEN IE(len %d)",
6103 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07006104
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -07006105 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
6106 {
6107 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
6108 "Need bigger buffer space");
6109 VOS_ASSERT(0);
6110 return -ENOMEM;
6111 }
6112 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
6113 pWextState->assocAddIE.length += eLen + 2;
6114
6115 pWextState->roamProfile.bOSENAssociation = VOS_TRUE;
6116 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
6117 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
6118 }
6119
6120 break;
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -07006121 if (WLAN_HDD_IBSS == pAdapter->device_mode) {
6122
6123 /* populating as ADDIE in beacon frames */
6124 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
6125 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, genie - 2, eLen + 2,
6126 NULL, eANI_BOOLEAN_FALSE)== eHAL_STATUS_SUCCESS)
6127 {
6128 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
6129 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
6130 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
6131 {
6132 hddLog(LOGE,
6133 "Coldn't pass "
6134 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
6135 }
6136 }/* ccmCfgSetStr(,WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, , )*/
6137 else
6138 hddLog(LOGE,
6139 "Could not pass on "
6140 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
6141
6142 /* IBSS mode doesn't contain params->proberesp_ies still
6143 beaconIE's need to be populated in probe response frames */
6144 if ( (NULL != (genie - 2)) && (0 != eLen + 2) )
6145 {
6146 u16 rem_probe_resp_ie_len = eLen + 2;
6147 u8 probe_rsp_ie_len[3] = {0};
6148 u8 counter = 0;
6149
6150 /* Check Probe Resp Length if it is greater then 255 then
6151 Store Probe Rsp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1
6152 & WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are
6153 not able Store More then 255 bytes into One Variable */
6154
6155 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
6156 {
6157 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
6158 {
6159 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
6160 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
6161 }
6162 else
6163 {
6164 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
6165 rem_probe_resp_ie_len = 0;
6166 }
6167 }
6168
6169 rem_probe_resp_ie_len = 0;
6170
6171 if (probe_rsp_ie_len[0] > 0)
6172 {
6173 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
6174 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
6175 (tANI_U8*)(genie - 2),
6176 probe_rsp_ie_len[0], NULL,
6177 eANI_BOOLEAN_FALSE)
6178 == eHAL_STATUS_FAILURE)
6179 {
6180 hddLog(LOGE,
6181 "Could not pass"
6182 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
6183 }
6184 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
6185 }
6186
6187 if (probe_rsp_ie_len[1] > 0)
6188 {
6189 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
6190 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
6191 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
6192 probe_rsp_ie_len[1], NULL,
6193 eANI_BOOLEAN_FALSE)
6194 == eHAL_STATUS_FAILURE)
6195 {
6196 hddLog(LOGE,
6197 "Could not pass"
6198 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
6199 }
6200 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
6201 }
6202
6203 if (probe_rsp_ie_len[2] > 0)
6204 {
6205 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
6206 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
6207 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
6208 probe_rsp_ie_len[2], NULL,
6209 eANI_BOOLEAN_FALSE)
6210 == eHAL_STATUS_FAILURE)
6211 {
6212 hddLog(LOGE,
6213 "Could not pass"
6214 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
6215 }
6216 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
6217 }
6218
6219 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
6220 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
6221 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
6222 {
6223 hddLog(LOGE,
6224 "Could not pass"
6225 "on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
6226 }
6227 }
6228 else
6229 {
6230 // Reset WNI_CFG_PROBE_RSP Flags
6231 wlan_hdd_reset_prob_rspies(pAdapter);
6232
6233 hddLog(VOS_TRACE_LEVEL_INFO,
6234 "%s: No Probe Response IE received in set beacon",
6235 __func__);
6236 }
6237 } /* end of if (WLAN_HDD_IBSS == pAdapter->device_mode) */
Jeff Johnson295189b2012-06-20 16:38:30 -07006238 break;
6239 case DOT11F_EID_RSN:
6240 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set RSN IE(len %d)",__func__, eLen + 2);
6241 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
6242 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2)/*ie_len*/);
6243 pWextState->roamProfile.pRSNReqIE = pWextState->WPARSNIE;
6244 pWextState->roamProfile.nRSNReqIELength = eLen + 2; //ie_len;
6245 break;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07006246 /* Appending Extended Capabilities with Interworking bit set in Assoc Req */
6247 case DOT11F_EID_EXTCAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306248 {
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07006249 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306250 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set Extended CAPS IE(len %d)",
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07006251 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306252
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07006253 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
6254 {
Jeff Johnson902c9832012-12-10 14:28:09 -08006255 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
6256 "Need bigger buffer space");
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07006257 VOS_ASSERT(0);
6258 return -ENOMEM;
6259 }
6260 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
6261 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306262
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07006263 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
6264 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
6265 break;
6266 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006267#ifdef FEATURE_WLAN_WAPI
6268 case WLAN_EID_WAPI:
6269 pAdapter->wapi_info.nWapiMode = 1; //Setting WAPI Mode to ON=1
Jeff Johnson0299d0a2013-10-30 12:37:43 -07006270 hddLog(VOS_TRACE_LEVEL_INFO, "WAPI MODE IS %u",
Jeff Johnson295189b2012-06-20 16:38:30 -07006271 pAdapter->wapi_info.nWapiMode);
6272 tmp = (u16 *)ie;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306273 tmp = tmp + 2; // Skip element Id and Len, Version
Jeff Johnson295189b2012-06-20 16:38:30 -07006274 akmsuiteCount = WPA_GET_LE16(tmp);
6275 tmp = tmp + 1;
6276 akmlist = (int *)(tmp);
6277 if(akmsuiteCount <= MAX_NUM_AKM_SUITES)
6278 {
6279 memcpy(akmsuite, akmlist, (4*akmsuiteCount));
6280 }
6281 else
6282 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08006283 hddLog(VOS_TRACE_LEVEL_FATAL, "Invalid akmSuite count");
Jeff Johnson295189b2012-06-20 16:38:30 -07006284 VOS_ASSERT(0);
6285 return -EINVAL;
6286 }
6287
6288 if (WAPI_PSK_AKM_SUITE == akmsuite[0])
6289 {
6290 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO PSK",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006291 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006292 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_PSK;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306293 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006294 if (WAPI_CERT_AKM_SUITE == akmsuite[0])
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306295 {
Jeff Johnson295189b2012-06-20 16:38:30 -07006296 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO CERTIFICATE",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006297 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006298 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_CERT;
6299 }
6300 break;
6301#endif
6302 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306303 hddLog (VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07006304 "%s Set UNKNOWN IE %X", __func__, elementId);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07006305 /* when Unknown IE is received we should break and continue
6306 * to the next IE in the buffer instead we were returning
6307 * so changing this to break */
6308 break;
Jeff Johnson295189b2012-06-20 16:38:30 -07006309 }
6310 genie += eLen;
6311 remLen -= eLen;
6312 }
6313 EXIT();
6314 return 0;
6315}
6316
6317/*
Gopichand Nakkala18f0c262013-05-07 23:25:08 +05306318 * FUNCTION: hdd_isWPAIEPresent
6319 * Parse the received IE to find the WPA IE
6320 *
6321 */
6322static bool hdd_isWPAIEPresent(u8 *ie, u8 ie_len)
6323{
6324 v_U8_t eLen = 0;
6325 v_U16_t remLen = ie_len;
6326 v_U8_t elementId = 0;
6327
6328 while (remLen >= 2)
6329 {
6330 elementId = *ie++;
6331 eLen = *ie++;
6332 remLen -= 2;
6333 if (eLen > remLen)
6334 {
6335 hddLog(VOS_TRACE_LEVEL_ERROR,
6336 "%s: IE length is wrong %d", __func__, eLen);
6337 return FALSE;
6338 }
6339 if ((elementId == DOT11F_EID_WPA) && (remLen > 5))
6340 {
6341 /* OUI - 0x00 0X50 0XF2
6342 WPA Information Element - 0x01
6343 WPA version - 0x01*/
6344 if (0 == memcmp(&ie[0], "\x00\x50\xf2\x01\x01", 5))
6345 return TRUE;
6346 }
6347 ie += eLen;
6348 remLen -= eLen;
6349 }
6350 return FALSE;
6351}
6352
6353/*
Jeff Johnson295189b2012-06-20 16:38:30 -07006354 * FUNCTION: wlan_hdd_cfg80211_set_privacy
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306355 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -07006356 * parameters during connect operation.
6357 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306358int wlan_hdd_cfg80211_set_privacy( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07006359 struct cfg80211_connect_params *req
6360 )
6361{
6362 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306363 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07006364 ENTER();
6365
6366 /*set wpa version*/
6367 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
6368
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306369 if (req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -07006370 {
Gopichand Nakkala781ded42013-06-28 12:10:45 +05306371 if (NL80211_WPA_VERSION_1 == req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -07006372 {
6373 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
6374 }
6375 else if (NL80211_WPA_VERSION_2 == req->crypto.wpa_versions)
6376 {
6377 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
6378 }
6379 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306380
6381 hddLog(VOS_TRACE_LEVEL_INFO, "%s: set wpa version to %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07006382 pWextState->wpaVersion);
6383
6384 /*set authentication type*/
6385 status = wlan_hdd_cfg80211_set_auth_type(pAdapter, req->auth_type);
6386
6387 if (0 > status)
6388 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306389 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07006390 "%s: failed to set authentication type ", __func__);
6391 return status;
6392 }
6393
6394 /*set key mgmt type*/
6395 if (req->crypto.n_akm_suites)
6396 {
6397 status = wlan_hdd_set_akm_suite(pAdapter, req->crypto.akm_suites[0]);
6398 if (0 > status)
6399 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306400 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set akm suite",
Jeff Johnson295189b2012-06-20 16:38:30 -07006401 __func__);
6402 return status;
6403 }
6404 }
6405
6406 /*set pairwise cipher type*/
6407 if (req->crypto.n_ciphers_pairwise)
6408 {
6409 status = wlan_hdd_cfg80211_set_cipher(pAdapter,
6410 req->crypto.ciphers_pairwise[0], true);
6411 if (0 > status)
6412 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306413 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07006414 "%s: failed to set unicast cipher type", __func__);
6415 return status;
6416 }
6417 }
6418 else
6419 {
6420 /*Reset previous cipher suite to none*/
6421 status = wlan_hdd_cfg80211_set_cipher(pAdapter, 0, true);
6422 if (0 > status)
6423 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306424 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07006425 "%s: failed to set unicast cipher type", __func__);
6426 return status;
6427 }
6428 }
6429
6430 /*set group cipher type*/
6431 status = wlan_hdd_cfg80211_set_cipher(pAdapter, req->crypto.cipher_group,
6432 false);
6433
6434 if (0 > status)
6435 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306436 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set mcast cipher type",
Jeff Johnson295189b2012-06-20 16:38:30 -07006437 __func__);
6438 return status;
6439 }
6440
Chet Lanctot186b5732013-03-18 10:26:30 -07006441#ifdef WLAN_FEATURE_11W
6442 pWextState->roamProfile.MFPEnabled = (req->mfp == NL80211_MFP_REQUIRED);
6443#endif
6444
Jeff Johnson295189b2012-06-20 16:38:30 -07006445 /*parse WPA/RSN IE, and set the correspoing fileds in Roam profile*/
6446 if (req->ie_len)
6447 {
6448 status = wlan_hdd_cfg80211_set_ie(pAdapter, req->ie, req->ie_len);
6449 if ( 0 > status)
6450 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306451 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse the WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -07006452 __func__);
6453 return status;
6454 }
6455 }
6456
6457 /*incase of WEP set default key information*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306458 if (req->key && req->key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -07006459 {
6460 if ( (WLAN_CIPHER_SUITE_WEP40 == req->crypto.ciphers_pairwise[0])
6461 || (WLAN_CIPHER_SUITE_WEP104 == req->crypto.ciphers_pairwise[0])
6462 )
6463 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306464 if ( IW_AUTH_KEY_MGMT_802_1X
Jeff Johnson295189b2012-06-20 16:38:30 -07006465 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X ))
6466 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306467 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Dynamic WEP not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -07006468 __func__);
6469 return -EOPNOTSUPP;
6470 }
6471 else
6472 {
6473 u8 key_len = req->key_len;
6474 u8 key_idx = req->key_idx;
6475
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306476 if ((eCSR_SECURITY_WEP_KEYSIZE_MAX_BYTES >= key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -07006477 && (CSR_MAX_NUM_KEY > key_idx)
6478 )
6479 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306480 hddLog(VOS_TRACE_LEVEL_INFO,
6481 "%s: setting default wep key, key_idx = %hu key_len %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07006482 __func__, key_idx, key_len);
6483 vos_mem_copy(
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306484 &pWextState->roamProfile.Keys.KeyMaterial[key_idx][0],
Jeff Johnson295189b2012-06-20 16:38:30 -07006485 req->key, key_len);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306486 pWextState->roamProfile.Keys.KeyLength[key_idx] =
Jeff Johnson295189b2012-06-20 16:38:30 -07006487 (u8)key_len;
6488 pWextState->roamProfile.Keys.defaultIndex = (u8)key_idx;
6489 }
6490 }
6491 }
6492 }
6493
6494 return status;
6495}
6496
6497/*
Vinay Krishna Eranna21042322014-01-08 19:21:39 +05306498 * FUNCTION: wlan_hdd_try_disconnect
6499 * This function is used to disconnect from previous
6500 * connection
6501 */
6502static int wlan_hdd_try_disconnect( hdd_adapter_t *pAdapter )
6503{
6504 long ret = 0;
6505 hdd_station_ctx_t *pHddStaCtx;
6506 eMib_dot11DesiredBssType connectedBssType;
6507
6508 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6509
6510 hdd_connGetConnectedBssType(pHddStaCtx,&connectedBssType );
6511
6512 if((eMib_dot11DesiredBssType_independent == connectedBssType) ||
6513 (eConnectionState_Associated == pHddStaCtx->conn_info.connState) ||
6514 (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState))
6515 {
6516 /* Issue disconnect to CSR */
6517 INIT_COMPLETION(pAdapter->disconnect_comp_var);
6518 if( eHAL_STATUS_SUCCESS ==
6519 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
6520 pAdapter->sessionId,
6521 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
6522 {
6523 ret = wait_for_completion_interruptible_timeout(
6524 &pAdapter->disconnect_comp_var,
6525 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
6526 if (0 >= ret)
6527 {
6528 hddLog(LOGE, FL("Failed to receive disconnect event"));
6529 return -EALREADY;
6530 }
6531 }
6532 }
6533 else if(eConnectionState_Disconnecting == pHddStaCtx->conn_info.connState)
6534 {
6535 ret = wait_for_completion_interruptible_timeout(
6536 &pAdapter->disconnect_comp_var,
6537 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
6538 if (0 >= ret)
6539 {
6540 hddLog(LOGE, FL("Failed to receive disconnect event"));
6541 return -EALREADY;
6542 }
6543 }
6544
6545 return 0;
6546}
6547
6548/*
Jeff Johnson295189b2012-06-20 16:38:30 -07006549 * FUNCTION: wlan_hdd_cfg80211_set_privacy
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306550 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -07006551 * parameters during connect operation.
6552 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306553static int wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07006554 struct net_device *ndev,
6555 struct cfg80211_connect_params *req
6556 )
6557{
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306558 int status;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306559 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -07006560 VOS_STATUS exitbmpsStatus = VOS_STATUS_E_INVAL;
Rajesh Chauhana0516c62014-01-30 16:11:18 -08006561 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07006562
6563 ENTER();
6564
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05306565 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
6566 TRACE_CODE_HDD_CFG80211_CONNECT,
6567 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306568 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006569 "%s: device_mode = %d",__func__,pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07006570
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306571 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -08006572 if (!pHddCtx)
6573 {
6574 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6575 "%s: HDD context is null", __func__);
6576 return VOS_STATUS_E_FAILURE;
6577 }
6578
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306579 status = wlan_hdd_validate_context(pHddCtx);
6580
6581 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -07006582 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306583 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6584 "%s: HDD context is not valid", __func__);
6585 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -07006586 }
6587
6588#ifdef WLAN_BTAMP_FEATURE
6589 //Infra connect not supported when AMP traffic is on.
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306590 if( VOS_TRUE == WLANBAP_AmpSessionOn() )
Jeff Johnson295189b2012-06-20 16:38:30 -07006591 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306592 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07006593 "%s: No connection when AMP is on", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08006594 return -ECONNREFUSED;
Jeff Johnson295189b2012-06-20 16:38:30 -07006595 }
6596#endif
Vinay Krishna Eranna21042322014-01-08 19:21:39 +05306597
6598 //If Device Mode is Station Concurrent Sessions Exit BMps
6599 //P2P Mode will be taken care in Open/close adapter
6600 if((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
6601 (vos_concurrent_sessions_running()))
6602 {
6603 exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
6604 }
6605
6606 /*Try disconnecting if already in connected state*/
6607 status = wlan_hdd_try_disconnect(pAdapter);
6608 if ( 0 > status)
6609 {
6610 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
6611 " connection"));
6612 return -EALREADY;
6613 }
6614
Jeff Johnson295189b2012-06-20 16:38:30 -07006615 /*initialise security parameters*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306616 status = wlan_hdd_cfg80211_set_privacy(pAdapter, req);
Jeff Johnson295189b2012-06-20 16:38:30 -07006617
6618 if ( 0 > status)
6619 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306620 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security params",
Jeff Johnson295189b2012-06-20 16:38:30 -07006621 __func__);
6622 return status;
6623 }
6624
Mohit Khanna765234a2012-09-11 15:08:35 -07006625 if ( req->channel )
6626 {
6627 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
6628 req->ssid_len, req->bssid,
6629 req->channel->hw_value);
6630 }
6631 else
6632 {
6633 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306634 req->ssid_len, req->bssid, 0);
Mohit Khanna765234a2012-09-11 15:08:35 -07006635 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006636
6637 if (0 > status)
6638 {
6639 //ReEnable BMPS if disabled
6640 if((VOS_STATUS_SUCCESS == exitbmpsStatus) &&
6641 (NULL != pHddCtx))
6642 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306643 if (pHddCtx->hdd_wlan_suspended)
6644 {
6645 hdd_set_pwrparams(pHddCtx);
6646 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006647 //ReEnable Bmps and Imps back
6648 hdd_enable_bmps_imps(pHddCtx);
6649 }
6650
6651 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: connect failed", __func__);
6652 return status;
6653 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306654 pHddCtx->isAmpAllowed = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07006655 EXIT();
6656 return status;
6657}
6658
6659
6660/*
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05306661 * FUNCTION: wlan_hdd_disconnect
6662 * This function is used to issue a disconnect request to SME
6663 */
6664int wlan_hdd_disconnect( hdd_adapter_t *pAdapter, u16 reason )
6665{
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306666 int status;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05306667 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306668 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
6669
6670 status = wlan_hdd_validate_context(pHddCtx);
6671
6672 if (0 != status)
6673 {
6674 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6675 "%s: HDD context is not valid", __func__);
6676 return status;
6677 }
6678
6679 pHddCtx->isAmpAllowed = VOS_TRUE;
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +05306680 pHddStaCtx->conn_info.connState = eConnectionState_Disconnecting;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05306681 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306682
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05306683 /*issue disconnect*/
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +05306684
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05306685 status = sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
6686 pAdapter->sessionId, reason);
6687
6688 if ( 0 != status )
6689 {
6690 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006691 "%s csrRoamDisconnect failure, returned %d",
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05306692 __func__, (int)status );
6693 return -EINVAL;
6694 }
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +05306695 status = wait_for_completion_interruptible_timeout(
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05306696 &pAdapter->disconnect_comp_var,
6697 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +05306698 if (!status)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306699 {
6700 hddLog(VOS_TRACE_LEVEL_ERROR,
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +05306701 "%s: Failed to disconnect, timed out", __func__);
6702 return -ETIMEDOUT;
6703 }
6704 else if (status == -ERESTARTSYS)
6705 {
6706 hddLog(VOS_TRACE_LEVEL_ERROR,
6707 "%s: Failed to disconnect, wait interrupted", __func__);
6708 return status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306709 }
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05306710 /*stop tx queues*/
6711 netif_tx_disable(pAdapter->dev);
6712 netif_carrier_off(pAdapter->dev);
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +05306713 return 0;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05306714}
6715
6716
6717/*
Jeff Johnson295189b2012-06-20 16:38:30 -07006718 * FUNCTION: wlan_hdd_cfg80211_disconnect
6719 * This function is used to issue a disconnect request to SME
6720 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306721static int wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07006722 struct net_device *dev,
6723 u16 reason
6724 )
6725{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306726 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
6727 tCsrRoamProfile *pRoamProfile =
Jeff Johnson295189b2012-06-20 16:38:30 -07006728 &(WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter))->roamProfile;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306729 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07006730 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkala4327a152013-03-04 23:22:42 -08006731 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaaa353782013-05-17 20:36:22 +05306732#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08006733 tANI_U8 staIdx;
6734#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306735
Jeff Johnson295189b2012-06-20 16:38:30 -07006736 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306737
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05306738 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
6739 TRACE_CODE_HDD_CFG80211_DISCONNECT,
6740 pAdapter->sessionId, reason));
6741 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",
Jeff Johnson295189b2012-06-20 16:38:30 -07006742 __func__,pAdapter->device_mode);
6743
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306744 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Disconnect called with reason code %d",
6745 __func__, reason);
Jeff Johnson295189b2012-06-20 16:38:30 -07006746
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306747 status = wlan_hdd_validate_context(pHddCtx);
6748
6749 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -07006750 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306751 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6752 "%s: HDD context is not valid", __func__);
6753 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -07006754 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306755
Jeff Johnson295189b2012-06-20 16:38:30 -07006756 if (NULL != pRoamProfile)
6757 {
6758 /*issue disconnect request to SME, if station is in connected state*/
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +05306759 if ((pHddStaCtx->conn_info.connState == eConnectionState_Associated) ||
6760 (pHddStaCtx->conn_info.connState == eConnectionState_Connecting))
Jeff Johnson295189b2012-06-20 16:38:30 -07006761 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306762 eCsrRoamDisconnectReason reasonCode =
Jeff Johnson295189b2012-06-20 16:38:30 -07006763 eCSR_DISCONNECT_REASON_UNSPECIFIED;
Gopichand Nakkalaaa353782013-05-17 20:36:22 +05306764 hdd_scaninfo_t *pScanInfo;
Jeff Johnson295189b2012-06-20 16:38:30 -07006765 switch(reason)
6766 {
6767 case WLAN_REASON_MIC_FAILURE:
6768 reasonCode = eCSR_DISCONNECT_REASON_MIC_ERROR;
6769 break;
6770
6771 case WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY:
6772 case WLAN_REASON_DISASSOC_AP_BUSY:
6773 case WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA:
6774 reasonCode = eCSR_DISCONNECT_REASON_DISASSOC;
6775 break;
6776
6777 case WLAN_REASON_PREV_AUTH_NOT_VALID:
6778 case WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA:
6779 reasonCode = eCSR_DISCONNECT_REASON_DEAUTH;
6780 break;
6781
6782 case WLAN_REASON_DEAUTH_LEAVING:
6783 default:
6784 reasonCode = eCSR_DISCONNECT_REASON_UNSPECIFIED;
6785 break;
6786 }
Gopichand Nakkalaaa353782013-05-17 20:36:22 +05306787 pScanInfo = &pHddCtx->scan_info;
6788 if (pScanInfo->mScanPending)
6789 {
Srinivas, Dasari138af4f2014-02-07 11:13:45 +05306790 hddLog(VOS_TRACE_LEVEL_INFO, "Disconnect is in progress, "
Gopichand Nakkalaaa353782013-05-17 20:36:22 +05306791 "Aborting Scan");
Srinivas, Dasari138af4f2014-02-07 11:13:45 +05306792 hdd_abort_mac_scan(pHddCtx, pAdapter->sessionId,
6793 eCSR_SCAN_ABORT_DEFAULT);
Gopichand Nakkalaaa353782013-05-17 20:36:22 +05306794 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006795
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08006796#ifdef FEATURE_WLAN_TDLS
6797 /* First clean up the tdls peers if any */
Gopichand Nakkala4327a152013-03-04 23:22:42 -08006798 for (staIdx = 0 ; staIdx < HDD_MAX_NUM_TDLS_STA; staIdx++)
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08006799 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -08006800 if ((pHddCtx->tdlsConnInfo[staIdx].sessionId == pAdapter->sessionId) &&
6801 (pHddCtx->tdlsConnInfo[staIdx].staId))
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08006802 {
Hoonki Lee11f7dda2013-02-14 16:55:44 -08006803 uint8 *mac;
Gopichand Nakkala4327a152013-03-04 23:22:42 -08006804 mac = pHddCtx->tdlsConnInfo[staIdx].peerMac.bytes;
Hoonki Lee11f7dda2013-02-14 16:55:44 -08006805 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07006806 "%s: call sme_DeleteTdlsPeerSta staId %d sessionId %d " MAC_ADDRESS_STR,
Gopichand Nakkala4327a152013-03-04 23:22:42 -08006807 __func__, pHddCtx->tdlsConnInfo[staIdx].staId, pAdapter->sessionId,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07006808 MAC_ADDR_ARRAY(mac));
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08006809 sme_DeleteTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala4327a152013-03-04 23:22:42 -08006810 pAdapter->sessionId,
6811 mac);
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08006812 }
6813 }
6814#endif
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +05306815 hddLog(LOG1, FL("Disconnecting with reasoncode:%u"), reasonCode);
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05306816 status = wlan_hdd_disconnect(pAdapter, reasonCode);
6817 if ( 0 != status )
Jeff Johnson295189b2012-06-20 16:38:30 -07006818 {
6819 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006820 "%s wlan_hdd_disconnect failure, returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07006821 __func__, (int)status );
6822 return -EINVAL;
6823 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006824 }
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +05306825 else
6826 {
6827 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unexpected cfg disconnect API"
6828 "called while in %d state", __func__,
6829 pHddStaCtx->conn_info.connState);
6830 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006831 }
6832 else
6833 {
6834 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid roam profile", __func__);
6835 }
6836
6837 return status;
6838}
6839
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05306840
Jeff Johnson295189b2012-06-20 16:38:30 -07006841/*
6842 * FUNCTION: wlan_hdd_cfg80211_set_privacy_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306843 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -07006844 * settings in IBSS mode.
6845 */
6846static int wlan_hdd_cfg80211_set_privacy_ibss(
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306847 hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07006848 struct cfg80211_ibss_params *params
6849 )
6850{
6851 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306852 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07006853 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
6854 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306855
Jeff Johnson295189b2012-06-20 16:38:30 -07006856 ENTER();
6857
6858 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
Ravi Joshib58ca0d2013-10-29 09:50:23 -07006859 vos_mem_zero(&pHddStaCtx->ibss_enc_key, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -07006860
6861 if (params->ie_len && ( NULL != params->ie) )
6862 {
Shailender Karmuchi67edd312013-06-18 16:30:48 -07006863 if (wlan_hdd_cfg80211_get_ie_ptr (params->ie,
6864 params->ie_len, WLAN_EID_RSN ))
Jeff Johnson295189b2012-06-20 16:38:30 -07006865 {
6866 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
6867 encryptionType = eCSR_ENCRYPT_TYPE_AES;
6868 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -07006869 else if ( hdd_isWPAIEPresent (params->ie, params->ie_len ))
Jeff Johnson295189b2012-06-20 16:38:30 -07006870 {
Shailender Karmuchi642e9812013-05-30 14:34:49 -07006871 tDot11fIEWPA dot11WPAIE;
6872 tHalHandle halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
Shailender Karmuchi67edd312013-06-18 16:30:48 -07006873 u8 *ie;
Shailender Karmuchi642e9812013-05-30 14:34:49 -07006874
Wilson Yang00256342013-10-10 23:13:38 -07006875 memset(&dot11WPAIE, 0, sizeof(dot11WPAIE));
Shailender Karmuchi67edd312013-06-18 16:30:48 -07006876 ie = wlan_hdd_cfg80211_get_ie_ptr (params->ie,
6877 params->ie_len, DOT11F_EID_WPA);
6878 if ( NULL != ie )
6879 {
6880 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
6881 // Unpack the WPA IE
6882 //Skip past the EID byte and length byte - and four byte WiFi OUI
6883 dot11fUnpackIeWPA((tpAniSirGlobal) halHandle,
6884 &ie[2+4],
6885 ie[1] - 4,
6886 &dot11WPAIE);
6887 /*Extract the multicast cipher, the encType for unicast
6888 cipher for wpa-none is none*/
6889 encryptionType =
6890 hdd_TranslateWPAToCsrEncryptionType(dot11WPAIE.multicast_cipher);
6891 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006892 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -07006893
Jeff Johnson295189b2012-06-20 16:38:30 -07006894 status = wlan_hdd_cfg80211_set_ie(pAdapter, params->ie, params->ie_len);
6895
6896 if (0 > status)
6897 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306898 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -07006899 __func__);
6900 return status;
6901 }
6902 }
6903
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306904 pWextState->roamProfile.AuthType.authType[0] =
6905 pHddStaCtx->conn_info.authType =
Jeff Johnson295189b2012-06-20 16:38:30 -07006906 eCSR_AUTH_TYPE_OPEN_SYSTEM;
6907
6908 if (params->privacy)
6909 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306910 /* Security enabled IBSS, At this time there is no information available
6911 * about the security paramters, so initialise the encryption type to
Jeff Johnson295189b2012-06-20 16:38:30 -07006912 * eCSR_ENCRYPT_TYPE_WEP40_STATICKEY.
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306913 * The correct security parameters will be updated later in
Jeff Johnson295189b2012-06-20 16:38:30 -07006914 * wlan_hdd_cfg80211_add_key */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306915 /* Hal expects encryption type to be set inorder
Jeff Johnson295189b2012-06-20 16:38:30 -07006916 *enable privacy bit in beacons */
6917
6918 encryptionType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
6919 }
Shailender Karmuchi642e9812013-05-30 14:34:49 -07006920 VOS_TRACE (VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
6921 "encryptionType=%d", encryptionType);
Jeff Johnson295189b2012-06-20 16:38:30 -07006922 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
6923 pWextState->roamProfile.EncryptionType.numEntries = 1;
6924 pWextState->roamProfile.EncryptionType.encryptionType[0] = encryptionType;
Jeff Johnson295189b2012-06-20 16:38:30 -07006925 return status;
6926}
6927
6928/*
6929 * FUNCTION: wlan_hdd_cfg80211_join_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306930 * This function is used to create/join an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -07006931 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306932static int wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07006933 struct net_device *dev,
6934 struct cfg80211_ibss_params *params
6935 )
6936{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306937 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Jeff Johnson295189b2012-06-20 16:38:30 -07006938 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
6939 tCsrRoamProfile *pRoamProfile;
6940 int status;
krunal sonie9002db2013-11-25 14:24:17 -08006941 bool alloc_bssid = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07006942 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306943 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07006944
6945 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306946
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05306947 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
6948 TRACE_CODE_HDD_CFG80211_JOIN_IBSS,
6949 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306950 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006951 "%s: device_mode = %d",__func__,pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07006952
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306953 status = wlan_hdd_validate_context(pHddCtx);
6954
6955 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -07006956 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306957 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6958 "%s: HDD context is not valid", __func__);
6959 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -07006960 }
6961
6962 if (NULL == pWextState)
6963 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08006964 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -07006965 __func__);
6966 return -EIO;
6967 }
6968
Vinay Krishna Eranna21042322014-01-08 19:21:39 +05306969 /*Try disconnecting if already in connected state*/
6970 status = wlan_hdd_try_disconnect(pAdapter);
6971 if ( 0 > status)
6972 {
6973 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
6974 " IBSS connection"));
6975 return -EALREADY;
6976 }
6977
Jeff Johnson295189b2012-06-20 16:38:30 -07006978 pRoamProfile = &pWextState->roamProfile;
6979
6980 if ( eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType )
6981 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306982 hddLog (VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006983 "%s Interface type is not set to IBSS", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006984 return -EINVAL;
6985 }
6986
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -07006987 /* BSSID is provided by upper layers hence no need to AUTO generate */
6988 if (NULL != params->bssid) {
6989 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
6990 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) {
6991 hddLog (VOS_TRACE_LEVEL_ERROR,
6992 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
6993 return -EIO;
6994 }
6995 }
krunal sonie9002db2013-11-25 14:24:17 -08006996 else if(pHddCtx->cfg_ini->isCoalesingInIBSSAllowed == 0)
6997 {
6998 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
6999 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
7000 {
7001 hddLog (VOS_TRACE_LEVEL_ERROR,
7002 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
7003 return -EIO;
7004 }
7005 params->bssid = vos_mem_malloc(sizeof(VOS_MAC_ADDR_SIZE));
7006 if (!params->bssid)
7007 {
7008 hddLog (VOS_TRACE_LEVEL_ERROR,
7009 "%s:Failed memory allocation", __func__);
7010 return -EIO;
7011 }
7012 vos_mem_copy((v_U8_t *)params->bssid,
7013 (v_U8_t *)&pHddCtx->cfg_ini->IbssBssid.bytes[0],
7014 VOS_MAC_ADDR_SIZE);
7015 alloc_bssid = VOS_TRUE;
7016 }
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -07007017
Jeff Johnson295189b2012-06-20 16:38:30 -07007018 /* Set Channel */
Yue Maf49ba872013-08-19 12:04:25 -07007019 if (NULL !=
7020#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
7021 params->chandef.chan)
7022#else
7023 params->channel)
7024#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007025 {
7026 u8 channelNum;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07007027 v_U32_t numChans = WNI_CFG_VALID_CHANNEL_LIST_LEN;
7028 v_U8_t validChan[WNI_CFG_VALID_CHANNEL_LIST_LEN];
7029 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
7030 int indx;
Jeff Johnson295189b2012-06-20 16:38:30 -07007031
7032 /* Get channel number */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307033 channelNum =
Yue Maf49ba872013-08-19 12:04:25 -07007034 ieee80211_frequency_to_channel(
7035#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
7036 params->chandef.chan->center_freq);
7037#else
7038 params->channel->center_freq);
7039#endif
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07007040
7041 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
7042 validChan, &numChans))
Jeff Johnson295189b2012-06-20 16:38:30 -07007043 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07007044 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid channel list",
7045 __func__);
7046 return -EOPNOTSUPP;
Jeff Johnson295189b2012-06-20 16:38:30 -07007047 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07007048
7049 for (indx = 0; indx < numChans; indx++)
Jeff Johnson295189b2012-06-20 16:38:30 -07007050 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07007051 if (channelNum == validChan[indx])
7052 {
7053 break;
7054 }
7055 }
7056 if (indx >= numChans)
7057 {
7058 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Not valid Channel %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07007059 __func__, channelNum);
7060 return -EINVAL;
7061 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07007062 /* Set the Operational Channel */
7063 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: set channel %d", __func__,
7064 channelNum);
7065 pRoamProfile->ChannelInfo.numOfChannels = 1;
7066 pHddStaCtx->conn_info.operationChannel = channelNum;
7067 pRoamProfile->ChannelInfo.ChannelList =
7068 &pHddStaCtx->conn_info.operationChannel;
Jeff Johnson295189b2012-06-20 16:38:30 -07007069 }
7070
7071 /* Initialize security parameters */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307072 status = wlan_hdd_cfg80211_set_privacy_ibss(pAdapter, params);
Jeff Johnson295189b2012-06-20 16:38:30 -07007073 if (status < 0)
7074 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307075 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security parameters",
Jeff Johnson295189b2012-06-20 16:38:30 -07007076 __func__);
7077 return status;
7078 }
7079
7080 /* Issue connect start */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307081 status = wlan_hdd_cfg80211_connect_start(pAdapter, params->ssid,
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07007082 params->ssid_len, params->bssid,
7083 pHddStaCtx->conn_info.operationChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -07007084
7085 if (0 > status)
7086 {
7087 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: connect failed", __func__);
7088 return status;
7089 }
7090
krunal sonie9002db2013-11-25 14:24:17 -08007091 if (NULL != params->bssid &&
7092 pHddCtx->cfg_ini->isCoalesingInIBSSAllowed == 0 &&
7093 alloc_bssid == VOS_TRUE)
7094 {
7095 vos_mem_free(params->bssid);
7096 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007097 return 0;
7098}
7099
7100/*
7101 * FUNCTION: wlan_hdd_cfg80211_leave_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307102 * This function is used to leave an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -07007103 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307104static int wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07007105 struct net_device *dev
7106 )
7107{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307108 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Jeff Johnson295189b2012-06-20 16:38:30 -07007109 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
7110 tCsrRoamProfile *pRoamProfile;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307111 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7112 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07007113
7114 ENTER();
7115
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307116 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7117 TRACE_CODE_HDD_CFG80211_LEAVE_IBSS,
7118 pAdapter->sessionId, eCSR_DISCONNECT_REASON_IBSS_LEAVE));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307119 status = wlan_hdd_validate_context(pHddCtx);
7120
7121 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007122 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307123 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7124 "%s: HDD context is not valid", __func__);
7125 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007126 }
7127
Arif Hussain6d2a3322013-11-17 19:50:10 -08007128 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",__func__,pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07007129 if (NULL == pWextState)
7130 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08007131 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -07007132 __func__);
7133 return -EIO;
7134 }
7135
7136 pRoamProfile = &pWextState->roamProfile;
7137
7138 /* Issue disconnect only if interface type is set to IBSS */
7139 if (eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType)
7140 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307141 hddLog (VOS_TRACE_LEVEL_ERROR, "%s: BSS Type is not set to IBSS",
Jeff Johnson295189b2012-06-20 16:38:30 -07007142 __func__);
7143 return -EINVAL;
7144 }
7145
7146 /* Issue Disconnect request */
7147 INIT_COMPLETION(pAdapter->disconnect_comp_var);
7148 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
7149 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
7150
7151 return 0;
7152}
7153
7154/*
7155 * FUNCTION: wlan_hdd_cfg80211_set_wiphy_params
7156 * This function is used to set the phy parameters
7157 * (RTS Threshold/FRAG Threshold/Retry Count etc ...)
7158 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307159static int wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07007160 u32 changed)
7161{
7162 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
7163 tHalHandle hHal = pHddCtx->hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307164 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07007165
7166 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307167 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7168 TRACE_CODE_HDD_CFG80211_SET_WIPHY_PARAMS,
7169 NO_SESSION, wiphy->rts_threshold));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307170 status = wlan_hdd_validate_context(pHddCtx);
7171
7172 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007173 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307174 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7175 "%s: HDD context is not valid", __func__);
7176 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007177 }
7178
Jeff Johnson295189b2012-06-20 16:38:30 -07007179 if (changed & WIPHY_PARAM_RTS_THRESHOLD)
7180 {
7181 u16 rts_threshold = (wiphy->rts_threshold == -1) ?
7182 WNI_CFG_RTS_THRESHOLD_STAMAX :
7183 wiphy->rts_threshold;
7184
7185 if ((WNI_CFG_RTS_THRESHOLD_STAMIN > rts_threshold) ||
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307186 (WNI_CFG_RTS_THRESHOLD_STAMAX < rts_threshold))
Jeff Johnson295189b2012-06-20 16:38:30 -07007187 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307188 hddLog(VOS_TRACE_LEVEL_ERROR,
7189 "%s: Invalid RTS Threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07007190 __func__, rts_threshold);
7191 return -EINVAL;
7192 }
7193
7194 if (0 != ccmCfgSetInt(hHal, WNI_CFG_RTS_THRESHOLD,
7195 rts_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307196 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -07007197 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307198 hddLog(VOS_TRACE_LEVEL_ERROR,
7199 "%s: ccmCfgSetInt failed for rts_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07007200 __func__, rts_threshold);
7201 return -EIO;
7202 }
7203
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307204 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set rts threshold %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07007205 rts_threshold);
7206 }
7207
7208 if (changed & WIPHY_PARAM_FRAG_THRESHOLD)
7209 {
7210 u16 frag_threshold = (wiphy->frag_threshold == -1) ?
7211 WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX :
7212 wiphy->frag_threshold;
7213
7214 if ((WNI_CFG_FRAGMENTATION_THRESHOLD_STAMIN > frag_threshold)||
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307215 (WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX < frag_threshold) )
Jeff Johnson295189b2012-06-20 16:38:30 -07007216 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307217 hddLog(VOS_TRACE_LEVEL_ERROR,
7218 "%s: Invalid frag_threshold value %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07007219 frag_threshold);
7220 return -EINVAL;
7221 }
7222
7223 if (0 != ccmCfgSetInt(hHal, WNI_CFG_FRAGMENTATION_THRESHOLD,
7224 frag_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307225 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -07007226 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307227 hddLog(VOS_TRACE_LEVEL_ERROR,
7228 "%s: ccmCfgSetInt failed for frag_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07007229 __func__, frag_threshold);
7230 return -EIO;
7231 }
7232
7233 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set frag threshold %hu", __func__,
7234 frag_threshold);
7235 }
7236
7237 if ((changed & WIPHY_PARAM_RETRY_SHORT)
7238 || (changed & WIPHY_PARAM_RETRY_LONG))
7239 {
7240 u8 retry_value = (changed & WIPHY_PARAM_RETRY_SHORT) ?
7241 wiphy->retry_short :
7242 wiphy->retry_long;
7243
7244 if ((WNI_CFG_LONG_RETRY_LIMIT_STAMIN > retry_value) ||
7245 (WNI_CFG_LONG_RETRY_LIMIT_STAMAX < retry_value))
7246 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307247 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07007248 __func__, retry_value);
7249 return -EINVAL;
7250 }
7251
7252 if (changed & WIPHY_PARAM_RETRY_SHORT)
7253 {
7254 if (0 != ccmCfgSetInt(hHal, WNI_CFG_LONG_RETRY_LIMIT,
7255 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307256 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -07007257 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307258 hddLog(VOS_TRACE_LEVEL_ERROR,
7259 "%s: ccmCfgSetInt failed for long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07007260 __func__, retry_value);
7261 return -EIO;
7262 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307263 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07007264 __func__, retry_value);
7265 }
7266 else if (changed & WIPHY_PARAM_RETRY_SHORT)
7267 {
7268 if (0 != ccmCfgSetInt(hHal, WNI_CFG_SHORT_RETRY_LIMIT,
7269 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307270 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -07007271 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307272 hddLog(VOS_TRACE_LEVEL_ERROR,
7273 "%s: ccmCfgSetInt failed for short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07007274 __func__, retry_value);
7275 return -EIO;
7276 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307277 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07007278 __func__, retry_value);
7279 }
7280 }
7281
7282 return 0;
7283}
7284
7285/*
7286 * FUNCTION: wlan_hdd_cfg80211_set_txpower
7287 * This function is used to set the txpower
7288 */
7289static int wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
Yue Maf49ba872013-08-19 12:04:25 -07007290#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
7291 struct wireless_dev *wdev,
7292#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007293#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307294 enum tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -07007295#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307296 enum nl80211_tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -07007297#endif
7298 int dbm)
7299{
7300 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307301 tHalHandle hHal = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07007302 tSirMacAddr bssid = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
7303 tSirMacAddr selfMac = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307304 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07007305
7306 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307307 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7308 TRACE_CODE_HDD_CFG80211_SET_TXPOWER,
7309 NO_SESSION, type ));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307310 status = wlan_hdd_validate_context(pHddCtx);
7311
7312 if (0 != status)
7313 {
7314 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7315 "%s: HDD context is not valid", __func__);
7316 return status;
7317 }
7318
7319 hHal = pHddCtx->hHal;
7320
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307321 if (0 != ccmCfgSetInt(hHal, WNI_CFG_CURRENT_TX_POWER_LEVEL,
7322 dbm, ccmCfgSetCallback,
7323 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -07007324 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307325 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07007326 "%s: ccmCfgSetInt failed for tx power %hu", __func__, dbm);
7327 return -EIO;
7328 }
7329
7330 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set tx power level %d dbm", __func__,
7331 dbm);
7332
7333 switch(type)
7334 {
7335 case NL80211_TX_POWER_AUTOMATIC: /*automatically determine transmit power*/
7336 /* Fall through */
7337 case NL80211_TX_POWER_LIMITED: /*limit TX power by the mBm parameter*/
7338 if( sme_SetMaxTxPower(hHal, bssid, selfMac, dbm) != eHAL_STATUS_SUCCESS )
7339 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307340 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Setting maximum tx power failed",
7341 __func__);
7342 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -07007343 }
7344 break;
7345 case NL80211_TX_POWER_FIXED: /*fix TX power to the mBm parameter*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307346 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: NL80211_TX_POWER_FIXED not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -07007347 __func__);
7348 return -EOPNOTSUPP;
7349 break;
7350 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307351 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid power setting type %d",
7352 __func__, type);
Jeff Johnson295189b2012-06-20 16:38:30 -07007353 return -EIO;
7354 }
7355
7356 return 0;
7357}
7358
7359/*
7360 * FUNCTION: wlan_hdd_cfg80211_get_txpower
7361 * This function is used to read the txpower
7362 */
Yue Maf49ba872013-08-19 12:04:25 -07007363static int wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy,
7364#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
7365 struct wireless_dev *wdev,
7366#endif
7367 int *dbm)
Jeff Johnson295189b2012-06-20 16:38:30 -07007368{
7369
7370 hdd_adapter_t *pAdapter;
7371 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307372 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07007373
Jeff Johnsone7245742012-09-05 17:12:55 -07007374 ENTER();
7375
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307376 status = wlan_hdd_validate_context(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07007377
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307378 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007379 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307380 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7381 "%s: HDD context is not valid", __func__);
7382 *dbm = 0;
7383 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007384 }
7385
Jeff Johnson295189b2012-06-20 16:38:30 -07007386 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
7387 if (NULL == pAdapter)
7388 {
7389 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Not in station context " ,__func__);
7390 return -ENOENT;
7391 }
7392
7393 wlan_hdd_get_classAstats(pAdapter);
7394 *dbm = pAdapter->hdd_stats.ClassA_stat.max_pwr;
7395
Jeff Johnsone7245742012-09-05 17:12:55 -07007396 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07007397 return 0;
7398}
7399
7400static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
7401 u8* mac, struct station_info *sinfo)
7402{
7403 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
7404 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7405 int ssidlen = pHddStaCtx->conn_info.SSID.SSID.length;
7406 tANI_U8 rate_flags;
7407
7408 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
7409 hdd_config_t *pCfg = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -07007410
7411 tANI_U8 OperationalRates[CSR_DOT11_SUPPORTED_RATES_MAX];
7412 tANI_U32 ORLeng = CSR_DOT11_SUPPORTED_RATES_MAX;
7413 tANI_U8 ExtendedRates[CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX];
7414 tANI_U32 ERLeng = CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX;
7415 tANI_U8 MCSRates[SIZE_OF_BASIC_MCS_SET];
7416 tANI_U32 MCSLeng = SIZE_OF_BASIC_MCS_SET;
7417 tANI_U16 maxRate = 0;
7418 tANI_U16 myRate;
7419 tANI_U16 currentRate = 0;
7420 tANI_U8 maxSpeedMCS = 0;
7421 tANI_U8 maxMCSIdx = 0;
7422 tANI_U8 rateFlag = 1;
7423 tANI_U8 i, j, rssidx;
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07007424 tANI_U16 temp;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307425 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07007426
Leo Chang6f8870f2013-03-26 18:11:36 -07007427#ifdef WLAN_FEATURE_11AC
7428 tANI_U32 vht_mcs_map;
7429 eDataRate11ACMaxMcs vhtMaxMcs;
7430#endif /* WLAN_FEATURE_11AC */
7431
Jeff Johnsone7245742012-09-05 17:12:55 -07007432 ENTER();
7433
Jeff Johnson295189b2012-06-20 16:38:30 -07007434 if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) ||
7435 (0 == ssidlen))
7436 {
7437 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Not associated or"
7438 " Invalid ssidlen, %d", __func__, ssidlen);
7439 /*To keep GUI happy*/
7440 return 0;
7441 }
7442
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307443 status = wlan_hdd_validate_context(pHddCtx);
7444
7445 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007446 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307447 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7448 "%s: HDD context is not valid", __func__);
7449 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007450 }
7451
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -07007452 wlan_hdd_get_station_stats(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07007453 rate_flags = pAdapter->hdd_stats.ClassA_stat.tx_rate_flags;
7454
Kiet Lam3b17fc82013-09-27 05:24:08 +05307455 wlan_hdd_get_rssi(pAdapter, &sinfo->signal);
7456 sinfo->filled |= STATION_INFO_SIGNAL;
7457
Jeff Johnson295189b2012-06-20 16:38:30 -07007458 //convert to the UI units of 100kbps
7459 myRate = pAdapter->hdd_stats.ClassA_stat.tx_rate * 5;
7460
7461#ifdef LINKSPEED_DEBUG_ENABLED
Leo Chang6f8870f2013-03-26 18:11:36 -07007462 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 -07007463 sinfo->signal,
7464 pCfg->reportMaxLinkSpeed,
7465 myRate,
7466 (int) pCfg->linkSpeedRssiHigh,
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07007467 (int) pCfg->linkSpeedRssiMid,
7468 (int) pCfg->linkSpeedRssiLow,
Leo Chang6f8870f2013-03-26 18:11:36 -07007469 (int) rate_flags,
7470 (int) pAdapter->hdd_stats.ClassA_stat.mcs_index);
Jeff Johnson295189b2012-06-20 16:38:30 -07007471#endif //LINKSPEED_DEBUG_ENABLED
7472
7473 if (eHDD_LINK_SPEED_REPORT_ACTUAL != pCfg->reportMaxLinkSpeed)
7474 {
7475 // we do not want to necessarily report the current speed
7476 if (eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed)
7477 {
7478 // report the max possible speed
7479 rssidx = 0;
7480 }
7481 else if (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed)
7482 {
7483 // report the max possible speed with RSSI scaling
7484 if (sinfo->signal >= pCfg->linkSpeedRssiHigh)
7485 {
7486 // report the max possible speed
7487 rssidx = 0;
7488 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07007489 else if (sinfo->signal >= pCfg->linkSpeedRssiMid)
Jeff Johnson295189b2012-06-20 16:38:30 -07007490 {
7491 // report middle speed
7492 rssidx = 1;
7493 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07007494 else if (sinfo->signal >= pCfg->linkSpeedRssiLow)
7495 {
7496 // report middle speed
7497 rssidx = 2;
7498 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007499 else
7500 {
7501 // report actual speed
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07007502 rssidx = 3;
Jeff Johnson295189b2012-06-20 16:38:30 -07007503 }
7504 }
7505 else
7506 {
7507 // unknown, treat as eHDD_LINK_SPEED_REPORT_MAX
7508 hddLog(VOS_TRACE_LEVEL_ERROR,
7509 "%s: Invalid value for reportMaxLinkSpeed: %u",
7510 __func__, pCfg->reportMaxLinkSpeed);
7511 rssidx = 0;
7512 }
7513
7514 maxRate = 0;
7515
7516 /* Get Basic Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +05307517 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_OPERATIONAL_RATE_SET,
7518 OperationalRates, &ORLeng))
7519 {
7520 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
7521 /*To keep GUI happy*/
7522 return 0;
7523 }
7524
Jeff Johnson295189b2012-06-20 16:38:30 -07007525 for (i = 0; i < ORLeng; i++)
7526 {
Jeff Johnsone7245742012-09-05 17:12:55 -07007527 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -07007528 {
7529 /* Validate Rate Set */
7530 if (supported_data_rate[j].beacon_rate_index == (OperationalRates[i] & 0x7F))
7531 {
7532 currentRate = supported_data_rate[j].supported_rate[rssidx];
7533 break;
7534 }
7535 }
7536 /* Update MAX rate */
7537 maxRate = (currentRate > maxRate)?currentRate:maxRate;
7538 }
7539
7540 /* Get Extended Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +05307541 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET,
7542 ExtendedRates, &ERLeng))
7543 {
7544 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
7545 /*To keep GUI happy*/
7546 return 0;
7547 }
7548
Jeff Johnson295189b2012-06-20 16:38:30 -07007549 for (i = 0; i < ERLeng; i++)
7550 {
Jeff Johnsone7245742012-09-05 17:12:55 -07007551 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -07007552 {
7553 if (supported_data_rate[j].beacon_rate_index == (ExtendedRates[i] & 0x7F))
7554 {
7555 currentRate = supported_data_rate[j].supported_rate[rssidx];
7556 break;
7557 }
7558 }
7559 /* Update MAX rate */
7560 maxRate = (currentRate > maxRate)?currentRate:maxRate;
7561 }
Kiet Lamb69f8dc2013-11-15 15:34:27 +05307562 /* Get MCS Rate Set --
Kaushik, Sushantdc304d82014-01-22 10:58:37 +05307563 Only if we are always reporting max speed (or)
Kiet Lamb69f8dc2013-11-15 15:34:27 +05307564 if we have good rssi */
Kaushik, Sushantdc304d82014-01-22 10:58:37 +05307565 if ((0 == rssidx) ||
Kiet Lamb69f8dc2013-11-15 15:34:27 +05307566 (eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed))
Jeff Johnson295189b2012-06-20 16:38:30 -07007567 {
Gopichand Nakkala05ab1322013-02-15 11:28:38 +05307568 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_CURRENT_MCS_SET,
7569 MCSRates, &MCSLeng))
7570 {
7571 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
7572 /*To keep GUI happy*/
7573 return 0;
7574 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007575 rateFlag = 0;
Leo Chang6f8870f2013-03-26 18:11:36 -07007576#ifdef WLAN_FEATURE_11AC
7577 /* VHT80 rate has seperate rate table */
Gopichand Nakkala4c705372013-04-24 13:20:33 +05307578 if (rate_flags & (eHAL_TX_RATE_VHT20|eHAL_TX_RATE_VHT40|eHAL_TX_RATE_VHT80))
Jeff Johnson295189b2012-06-20 16:38:30 -07007579 {
Leo Chang6f8870f2013-03-26 18:11:36 -07007580 ccmCfgGetInt(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_VHT_TX_MCS_MAP, &vht_mcs_map);
Gopichand Nakkala4c705372013-04-24 13:20:33 +05307581 vhtMaxMcs = (eDataRate11ACMaxMcs)(vht_mcs_map & DATA_RATE_11AC_MCS_MASK );
Leo Chang6f8870f2013-03-26 18:11:36 -07007582 if (rate_flags & eHAL_TX_RATE_SGI)
Jeff Johnson295189b2012-06-20 16:38:30 -07007583 {
Leo Chang6f8870f2013-03-26 18:11:36 -07007584 rateFlag |= 1;
Jeff Johnson295189b2012-06-20 16:38:30 -07007585 }
Leo Chang6f8870f2013-03-26 18:11:36 -07007586 if (DATA_RATE_11AC_MAX_MCS_7 == vhtMaxMcs)
Jeff Johnson295189b2012-06-20 16:38:30 -07007587 {
Leo Chang6f8870f2013-03-26 18:11:36 -07007588 maxMCSIdx = 7;
7589 }
7590 else if (DATA_RATE_11AC_MAX_MCS_8 == vhtMaxMcs)
7591 {
7592 maxMCSIdx = 8;
7593 }
7594 else if (DATA_RATE_11AC_MAX_MCS_9 == vhtMaxMcs)
7595 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +05307596 //VHT20 is supporting 0~8
7597 if (rate_flags & eHAL_TX_RATE_VHT20)
7598 maxMCSIdx = 8;
7599 else
7600 maxMCSIdx = 9;
Leo Chang6f8870f2013-03-26 18:11:36 -07007601 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +05307602
7603 if (rate_flags & eHAL_TX_RATE_VHT80)
7604 {
7605 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT80_rate[rateFlag];
7606 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT80_rate[rateFlag];
7607 }
7608 else if (rate_flags & eHAL_TX_RATE_VHT40)
7609 {
7610 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT40_rate[rateFlag];
7611 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT40_rate[rateFlag];
7612 }
7613 else if (rate_flags & eHAL_TX_RATE_VHT20)
7614 {
7615 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT20_rate[rateFlag];
7616 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT20_rate[rateFlag];
7617 }
7618
Leo Chang6f8870f2013-03-26 18:11:36 -07007619 maxSpeedMCS = 1;
7620 if (currentRate > maxRate)
7621 {
7622 maxRate = currentRate;
7623 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +05307624
Leo Chang6f8870f2013-03-26 18:11:36 -07007625 }
7626 else
7627#endif /* WLAN_FEATURE_11AC */
7628 {
7629 if (rate_flags & eHAL_TX_RATE_HT40)
7630 {
7631 rateFlag |= 1;
7632 }
7633 if (rate_flags & eHAL_TX_RATE_SGI)
7634 {
7635 rateFlag |= 2;
7636 }
7637
7638 for (i = 0; i < MCSLeng; i++)
7639 {
7640 temp = sizeof(supported_mcs_rate) / sizeof(supported_mcs_rate[0]);
7641 for (j = 0; j < temp; j++)
7642 {
7643 if (supported_mcs_rate[j].beacon_rate_index == MCSRates[i])
7644 {
7645 currentRate = supported_mcs_rate[j].supported_rate[rateFlag];
7646 break;
7647 }
7648 }
7649 if ((j < temp) && (currentRate > maxRate))
7650 {
7651 maxRate = currentRate;
7652 maxSpeedMCS = 1;
7653 maxMCSIdx = supported_mcs_rate[j].beacon_rate_index;
7654 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007655 }
7656 }
7657 }
7658
Gopichand Nakkala4c705372013-04-24 13:20:33 +05307659 else if (!(rate_flags & eHAL_TX_RATE_LEGACY))
7660 {
7661 maxRate = myRate;
7662 maxSpeedMCS = 1;
7663 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
7664 }
7665
Jeff Johnson295189b2012-06-20 16:38:30 -07007666 // make sure we report a value at least as big as our current rate
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07007667 if (((maxRate < myRate) && (0 == rssidx)) ||
7668 (0 == maxRate))
Jeff Johnson295189b2012-06-20 16:38:30 -07007669 {
7670 maxRate = myRate;
7671 if (rate_flags & eHAL_TX_RATE_LEGACY)
7672 {
7673 maxSpeedMCS = 0;
7674 }
7675 else
7676 {
7677 maxSpeedMCS = 1;
7678 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
7679 }
7680 }
7681
Gopichand Nakkala4c705372013-04-24 13:20:33 +05307682 if (rate_flags & eHAL_TX_RATE_LEGACY)
Jeff Johnson295189b2012-06-20 16:38:30 -07007683 {
7684 sinfo->txrate.legacy = maxRate;
7685#ifdef LINKSPEED_DEBUG_ENABLED
7686 pr_info("Reporting legacy rate %d\n", sinfo->txrate.legacy);
7687#endif //LINKSPEED_DEBUG_ENABLED
7688 }
7689 else
7690 {
7691 sinfo->txrate.mcs = maxMCSIdx;
Leo Chang6f8870f2013-03-26 18:11:36 -07007692#ifdef WLAN_FEATURE_11AC
7693 sinfo->txrate.nss = 1;
7694 if (rate_flags & eHAL_TX_RATE_VHT80)
7695 {
7696 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
Gopichand Nakkala4c705372013-04-24 13:20:33 +05307697 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
Leo Chang6f8870f2013-03-26 18:11:36 -07007698 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +05307699 else if (rate_flags & eHAL_TX_RATE_VHT40)
Leo Chang6f8870f2013-03-26 18:11:36 -07007700 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +05307701 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
7702 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
7703 }
7704 else if (rate_flags & eHAL_TX_RATE_VHT20)
7705 {
7706 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
7707 }
7708#endif /* WLAN_FEATURE_11AC */
7709 if (rate_flags & (eHAL_TX_RATE_HT20 | eHAL_TX_RATE_HT40))
7710 {
7711 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
7712 if (rate_flags & eHAL_TX_RATE_HT40)
7713 {
7714 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
7715 }
Leo Chang6f8870f2013-03-26 18:11:36 -07007716 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007717 if (rate_flags & eHAL_TX_RATE_SGI)
7718 {
7719 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
7720 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +05307721
Jeff Johnson295189b2012-06-20 16:38:30 -07007722#ifdef LINKSPEED_DEBUG_ENABLED
7723 pr_info("Reporting MCS rate %d flags %x\n",
7724 sinfo->txrate.mcs,
7725 sinfo->txrate.flags );
7726#endif //LINKSPEED_DEBUG_ENABLED
7727 }
7728 }
7729 else
7730 {
7731 // report current rate instead of max rate
7732
7733 if (rate_flags & eHAL_TX_RATE_LEGACY)
7734 {
7735 //provide to the UI in units of 100kbps
7736 sinfo->txrate.legacy = myRate;
7737#ifdef LINKSPEED_DEBUG_ENABLED
7738 pr_info("Reporting actual legacy rate %d\n", sinfo->txrate.legacy);
7739#endif //LINKSPEED_DEBUG_ENABLED
7740 }
7741 else
7742 {
7743 //must be MCS
7744 sinfo->txrate.mcs = pAdapter->hdd_stats.ClassA_stat.mcs_index;
Leo Chang6f8870f2013-03-26 18:11:36 -07007745#ifdef WLAN_FEATURE_11AC
7746 sinfo->txrate.nss = 1;
7747 if (rate_flags & eHAL_TX_RATE_VHT80)
7748 {
7749 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
7750 }
7751 else
7752#endif /* WLAN_FEATURE_11AC */
7753 {
7754 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
7755 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007756 if (rate_flags & eHAL_TX_RATE_SGI)
7757 {
7758 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
7759 }
7760 if (rate_flags & eHAL_TX_RATE_HT40)
7761 {
7762 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
7763 }
Leo Chang6f8870f2013-03-26 18:11:36 -07007764#ifdef WLAN_FEATURE_11AC
7765 else if (rate_flags & eHAL_TX_RATE_VHT80)
7766 {
7767 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
7768 }
7769#endif /* WLAN_FEATURE_11AC */
Jeff Johnson295189b2012-06-20 16:38:30 -07007770#ifdef LINKSPEED_DEBUG_ENABLED
7771 pr_info("Reporting actual MCS rate %d flags %x\n",
7772 sinfo->txrate.mcs,
7773 sinfo->txrate.flags );
7774#endif //LINKSPEED_DEBUG_ENABLED
7775 }
7776 }
7777 sinfo->filled |= STATION_INFO_TX_BITRATE;
7778
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -07007779 sinfo->tx_packets =
7780 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[0] +
7781 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[1] +
7782 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[2] +
7783 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[3];
7784
7785 sinfo->tx_retries =
7786 pAdapter->hdd_stats.summary_stat.retry_cnt[0] +
7787 pAdapter->hdd_stats.summary_stat.retry_cnt[1] +
7788 pAdapter->hdd_stats.summary_stat.retry_cnt[2] +
7789 pAdapter->hdd_stats.summary_stat.retry_cnt[3];
7790
7791 sinfo->tx_failed =
7792 pAdapter->hdd_stats.summary_stat.fail_cnt[0] +
7793 pAdapter->hdd_stats.summary_stat.fail_cnt[1] +
7794 pAdapter->hdd_stats.summary_stat.fail_cnt[2] +
7795 pAdapter->hdd_stats.summary_stat.fail_cnt[3];
7796
7797 sinfo->filled |=
7798 STATION_INFO_TX_PACKETS |
7799 STATION_INFO_TX_RETRIES |
7800 STATION_INFO_TX_FAILED;
7801
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307802 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7803 TRACE_CODE_HDD_CFG80211_GET_STA,
7804 pAdapter->sessionId, maxRate));
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -07007805 EXIT();
7806 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07007807}
7808
7809static int wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
Sameer Thalappilc9f26e92013-06-07 10:11:06 -07007810 struct net_device *dev, bool mode, int timeout)
Jeff Johnson295189b2012-06-20 16:38:30 -07007811{
7812 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +05307813 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07007814 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307815 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07007816
Jeff Johnsone7245742012-09-05 17:12:55 -07007817 ENTER();
7818
Jeff Johnson295189b2012-06-20 16:38:30 -07007819 if (NULL == pAdapter)
7820 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08007821 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007822 return -ENODEV;
7823 }
7824
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307825 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7826 TRACE_CODE_HDD_CFG80211_SET_POWER_MGMT,
7827 pAdapter->sessionId, timeout));
7828
Gopichand Nakkala20c4c042013-04-19 22:08:55 +05307829 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307830 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +05307831
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307832 if (0 != status)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307833 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307834 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7835 "%s: HDD context is not valid", __func__);
7836 return status;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307837 }
7838
Gopichand Nakkala20c4c042013-04-19 22:08:55 +05307839 if ((DRIVER_POWER_MODE_AUTO == !mode) &&
7840 (TRUE == pHddCtx->hdd_wlan_suspended) &&
7841 (pHddCtx->cfg_ini->fhostArpOffload) &&
7842 (eConnectionState_Associated ==
7843 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
7844 {
Amar Singhald53568e2013-09-26 11:03:45 -07007845
7846 hddLog(VOS_TRACE_LEVEL_INFO,
7847 "offload: in cfg80211_set_power_mgmt, calling arp offload");
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05307848 vos_status = hdd_conf_arp_offload(pAdapter, TRUE);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +05307849 if (!VOS_IS_STATUS_SUCCESS(vos_status))
7850 {
7851 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007852 "%s:Failed to enable ARPOFFLOAD Feature %d",
Gopichand Nakkala20c4c042013-04-19 22:08:55 +05307853 __func__, vos_status);
7854 }
7855 }
7856
Jeff Johnson295189b2012-06-20 16:38:30 -07007857 /**The get power cmd from the supplicant gets updated by the nl only
7858 *on successful execution of the function call
7859 *we are oppositely mapped w.r.t mode in the driver
7860 **/
7861 vos_status = wlan_hdd_enter_bmps(pAdapter, !mode);
7862
Jeff Johnsone7245742012-09-05 17:12:55 -07007863 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07007864 if (VOS_STATUS_E_FAILURE == vos_status)
7865 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307866 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7867 "%s: failed to enter bmps mode", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007868 return -EINVAL;
7869 }
7870 return 0;
7871}
7872
7873
7874#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
7875static int wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
7876 struct net_device *netdev,
7877 u8 key_index)
7878{
Jeff Johnsone7245742012-09-05 17:12:55 -07007879 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07007880 return 0;
7881}
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307882#endif //LINUX_VERSION_CODE
Jeff Johnson295189b2012-06-20 16:38:30 -07007883
7884#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
7885static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
7886 struct net_device *dev,
7887 struct ieee80211_txq_params *params)
7888{
Jeff Johnsone7245742012-09-05 17:12:55 -07007889 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07007890 return 0;
7891}
7892#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
7893static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
7894 struct ieee80211_txq_params *params)
7895{
Jeff Johnsone7245742012-09-05 17:12:55 -07007896 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07007897 return 0;
7898}
7899#endif //LINUX_VERSION_CODE
7900
7901static int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
7902 struct net_device *dev, u8 *mac)
7903{
7904 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307905 hdd_context_t *pHddCtx;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08007906 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307907 int status;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08007908 v_U8_t staId;
Jeff Johnson295189b2012-06-20 16:38:30 -07007909
Jeff Johnsone7245742012-09-05 17:12:55 -07007910 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307911
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307912 if ( NULL == pAdapter )
Jeff Johnson295189b2012-06-20 16:38:30 -07007913 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307914 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007915 return -EINVAL;
7916 }
7917
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307918 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7919 TRACE_CODE_HDD_CFG80211_DEL_STA,
7920 pAdapter->sessionId, pAdapter->device_mode));
7921
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307922 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7923 status = wlan_hdd_validate_context(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07007924
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307925 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007926 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307927 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7928 "%s: HDD context is not valid", __func__);
7929 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007930 }
7931
Jeff Johnson295189b2012-06-20 16:38:30 -07007932 if ( (WLAN_HDD_SOFTAP == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -07007933 || (WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -07007934 )
7935 {
7936 if( NULL == mac )
7937 {
7938 v_U16_t i;
7939 for(i = 0; i < WLAN_MAX_STA_COUNT; i++)
7940 {
Rajesh Chauhan18488fc2013-08-22 10:15:03 -07007941 if ((pAdapter->aStaInfo[i].isUsed) &&
7942 (!pAdapter->aStaInfo[i].isDeauthInProgress))
Jeff Johnson295189b2012-06-20 16:38:30 -07007943 {
7944 u8 *macAddr = pAdapter->aStaInfo[i].macAddrSTA.bytes;
7945 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -08007946 "%s: Delete STA with MAC::"
7947 MAC_ADDRESS_STR,
7948 __func__, MAC_ADDR_ARRAY(macAddr));
Rajesh Chauhan18488fc2013-08-22 10:15:03 -07007949 vos_status = hdd_softap_sta_deauth(pAdapter, macAddr);
7950 if (VOS_IS_STATUS_SUCCESS(vos_status))
7951 pAdapter->aStaInfo[i].isDeauthInProgress = TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -07007952 }
7953 }
7954 }
7955 else
7956 {
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08007957
7958 vos_status = hdd_softap_GetStaId(pAdapter,(v_MACADDR_t *)mac, &staId);
7959 if (!VOS_IS_STATUS_SUCCESS(vos_status))
7960 {
7961 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -08007962 "%s: Skip this DEL STA as this is not used::"
7963 MAC_ADDRESS_STR,
7964 __func__, MAC_ADDR_ARRAY(mac));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08007965 return -ENOENT;
7966 }
7967
7968 if( pAdapter->aStaInfo[staId].isDeauthInProgress == TRUE)
7969 {
7970 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -08007971 "%s: Skip this DEL STA as deauth is in progress::"
7972 MAC_ADDRESS_STR,
7973 __func__, MAC_ADDR_ARRAY(mac));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08007974 return -ENOENT;
7975 }
7976
7977 pAdapter->aStaInfo[staId].isDeauthInProgress = TRUE;
7978
Jeff Johnson295189b2012-06-20 16:38:30 -07007979 hddLog(VOS_TRACE_LEVEL_INFO,
7980 "%s: Delete STA with MAC::"
Arif Hussain24bafea2013-11-15 15:10:03 -08007981 MAC_ADDRESS_STR,
Jeff Johnson295189b2012-06-20 16:38:30 -07007982 __func__,
Arif Hussain24bafea2013-11-15 15:10:03 -08007983 MAC_ADDR_ARRAY(mac));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08007984
7985 vos_status = hdd_softap_sta_deauth(pAdapter, mac);
7986 if (!VOS_IS_STATUS_SUCCESS(vos_status))
7987 {
7988 pAdapter->aStaInfo[staId].isDeauthInProgress = FALSE;
7989 hddLog(VOS_TRACE_LEVEL_INFO,
7990 "%s: STA removal failed for ::"
Arif Hussain24bafea2013-11-15 15:10:03 -08007991 MAC_ADDRESS_STR,
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08007992 __func__,
Arif Hussain24bafea2013-11-15 15:10:03 -08007993 MAC_ADDR_ARRAY(mac));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08007994 return -ENOENT;
7995 }
7996
Jeff Johnson295189b2012-06-20 16:38:30 -07007997 }
7998 }
7999
8000 EXIT();
8001
8002 return 0;
8003}
8004
Hoonki Lee11f7dda2013-02-14 16:55:44 -08008005static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
8006 struct net_device *dev, u8 *mac, struct station_parameters *params)
8007{
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308008 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkalab977a972013-02-18 19:15:09 -08008009 int status = -EPERM;
Hoonki Lee11f7dda2013-02-14 16:55:44 -08008010#ifdef FEATURE_WLAN_TDLS
8011 u32 mask, set;
Hoonki Lee11f7dda2013-02-14 16:55:44 -08008012 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308013
8014 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
8015 TRACE_CODE_HDD_CFG80211_ADD_STA,
8016 pAdapter->sessionId, params->listen_interval));
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008017 mask = params->sta_flags_mask;
8018
8019 set = params->sta_flags_set;
8020
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07008021#ifdef WLAN_FEATURE_TDLS_DEBUG
8022 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8023 "%s: mask 0x%x set 0x%x " MAC_ADDRESS_STR,
8024 __func__, mask, set, MAC_ADDR_ARRAY(mac));
8025#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008026
8027 if (mask & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
8028 if (set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008029 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 0, NULL);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008030 }
8031 }
8032#endif
Gopichand Nakkalab977a972013-02-18 19:15:09 -08008033 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -07008034}
8035
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008036
8037#ifdef FEATURE_WLAN_LFR
Wilson Yang6507c4e2013-10-01 20:11:19 -07008038#define MAX_PMKSAIDS_IN_CACHE 8
8039
8040static tPmkidCacheInfo PMKIDCache[MAX_PMKSAIDS_IN_CACHE]; // HDD local cache
8041static tANI_U32 PMKIDCacheIndex; // HDD local Cache index
8042
8043
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008044static int wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
Jeff Johnsond13512a2012-07-17 11:42:19 -07008045 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008046{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308047 tANI_U32 j=0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008048 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
8049 tHalHandle halHandle;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308050 eHalStatus result;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308051 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008052 tANI_U8 BSSIDMatched = 0;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308053 hdd_context_t *pHddCtx;
Jeff Johnson0299d0a2013-10-30 12:37:43 -07008054 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: set PMKSA for " MAC_ADDRESS_STR,
8055 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
Jeff Johnsone7245742012-09-05 17:12:55 -07008056
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308057 // Validate pAdapter
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308058 if ( NULL == pAdapter )
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008059 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308060 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008061 return -EINVAL;
8062 }
8063
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308064 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8065 status = wlan_hdd_validate_context(pHddCtx);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008066
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308067 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008068 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308069 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8070 "%s: HDD context is not valid", __func__);
8071 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008072 }
8073
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308074 // Retrieve halHandle
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008075 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
8076
Wilson Yang6507c4e2013-10-01 20:11:19 -07008077 for (j = 0; j < PMKIDCacheIndex; j++)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008078 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308079 if(vos_mem_compare(PMKIDCache[j].BSSID,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008080 pmksa->bssid, WNI_CFG_BSSID_LEN))
8081 {
8082 /* BSSID matched previous entry. Overwrite it. */
8083 BSSIDMatched = 1;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308084 vos_mem_copy(PMKIDCache[j].BSSID,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008085 pmksa->bssid, WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308086 vos_mem_copy(PMKIDCache[j].PMKID,
8087 pmksa->pmkid,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008088 CSR_RSN_PMKID_SIZE);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308089 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Reusing cache entry %d.",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008090 __func__, j );
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008091 dump_bssid(pmksa->bssid);
8092 dump_pmkid(halHandle, pmksa->pmkid);
8093 break;
8094 }
8095 }
8096
Madan Mohan Koyyalamudic4b317d2012-10-18 19:43:08 -07008097 /* Check we compared all entries,if then take the first slot now */
Wilson Yang6507c4e2013-10-01 20:11:19 -07008098 if(j == MAX_PMKSAIDS_IN_CACHE) PMKIDCacheIndex=0;
Madan Mohan Koyyalamudic4b317d2012-10-18 19:43:08 -07008099
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008100 if (!BSSIDMatched)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308101 {
8102 // Now, we DON'T have a BSSID match, so take a new entry in the cache.
Wilson Yang6507c4e2013-10-01 20:11:19 -07008103 vos_mem_copy(PMKIDCache[PMKIDCacheIndex].BSSID,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308104 pmksa->bssid, ETHER_ADDR_LEN);
Wilson Yang6507c4e2013-10-01 20:11:19 -07008105 vos_mem_copy(PMKIDCache[PMKIDCacheIndex].PMKID,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308106 pmksa->pmkid,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008107 CSR_RSN_PMKID_SIZE);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308108 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Adding a new cache entry %d.",
Wilson Yang6507c4e2013-10-01 20:11:19 -07008109 __func__, PMKIDCacheIndex );
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008110 dump_bssid(pmksa->bssid);
8111 dump_pmkid(halHandle, pmksa->pmkid);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308112 // Increment the HDD Local Cache index
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008113 // The "i=0" doesn't work for the call to sme_RoamSetPMKIDCache() - LFR FIXME
Wilson Yang6507c4e2013-10-01 20:11:19 -07008114 if (PMKIDCacheIndex <= (MAX_PMKSAIDS_IN_CACHE-1)) PMKIDCacheIndex++; else PMKIDCacheIndex = 0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008115 }
8116
8117
8118 // Calling csrRoamSetPMKIDCache to configure the PMKIDs into the cache
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308119 //hddLog(LOG1, FL("%s: Calling csrRoamSetPMKIDCache with %d cache entries."),
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008120 // __func__, i );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308121 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Calling csrRoamSetPMKIDCache with %d cache entries.",
Wilson Yang6507c4e2013-10-01 20:11:19 -07008122 __func__, PMKIDCacheIndex );
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008123 // Finally set the PMKSA ID Cache in CSR
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308124 result = sme_RoamSetPMKIDCache(halHandle,pAdapter->sessionId,
8125 PMKIDCache,
Wilson Yang6507c4e2013-10-01 20:11:19 -07008126 PMKIDCacheIndex);
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308127 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
8128 TRACE_CODE_HDD_CFG80211_SET_PMKSA,
8129 pAdapter->sessionId, result));
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008130 return 0;
8131}
8132
8133
Wilson Yang6507c4e2013-10-01 20:11:19 -07008134
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008135static int wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
Wilson Yang6507c4e2013-10-01 20:11:19 -07008136 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008137{
Wilson Yang6507c4e2013-10-01 20:11:19 -07008138 tANI_U32 j=0;
8139 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
8140 tHalHandle halHandle;
Wilson Yang6507c4e2013-10-01 20:11:19 -07008141 tANI_U8 BSSIDMatched = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -07008142 hdd_context_t *pHddCtx;
Wilson Yangef657d32014-01-15 19:19:23 -08008143 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -07008144
Jeff Johnson0299d0a2013-10-30 12:37:43 -07008145 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: deleting PMKSA for " MAC_ADDRESS_STR,
8146 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
Wilson Yang6507c4e2013-10-01 20:11:19 -07008147
8148 /* Validate pAdapter */
8149 if (NULL == pAdapter)
8150 {
8151 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
8152 return -EINVAL;
8153 }
8154
8155 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8156 status = wlan_hdd_validate_context(pHddCtx);
8157
8158 if (0 != status)
8159 {
8160 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8161 "%s: HDD context is not valid", __func__);
8162 return status;
8163 }
8164
8165 /*Retrieve halHandle*/
8166 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
8167
8168 /*in case index is 0,no entry to delete*/
8169 if (0 == PMKIDCacheIndex)
8170 {
8171 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid entry to delete" ,
8172 __func__);
8173 return -EINVAL;
8174 }
8175
8176 /*find the matching PMKSA entry from j=0 to (index-1),
8177 * and delete the matched one
8178 */
8179 for (j = 0; j<PMKIDCacheIndex; j++)
8180 {
8181 if (vos_mem_compare(PMKIDCache[j].BSSID,
8182 pmksa->bssid,
8183 WNI_CFG_BSSID_LEN))
8184 {
8185 /* BSSID matched entry */
8186 BSSIDMatched = 1;
8187
8188 if (j<PMKIDCacheIndex-1)
8189 {
8190 /*replace the matching entry with the last entry in HDD local cache*/
8191 vos_mem_copy(PMKIDCache[j].BSSID,
8192 PMKIDCache[PMKIDCacheIndex-1].BSSID,
8193 WNI_CFG_BSSID_LEN);
8194 vos_mem_copy(PMKIDCache[j].PMKID,
8195 PMKIDCache[PMKIDCacheIndex-1].PMKID,
8196 CSR_RSN_PMKID_SIZE);
8197 }
8198
8199 /*clear the last entry in HDD cache ---[index-1]*/
Wilson Yang6507c4e2013-10-01 20:11:19 -07008200 vos_mem_zero(PMKIDCache[PMKIDCacheIndex-1].BSSID, WNI_CFG_BSSID_LEN);
8201 vos_mem_zero(PMKIDCache[PMKIDCacheIndex-1].PMKID, CSR_RSN_PMKID_SIZE);
8202
8203 /*reduce the PMKID array index*/
8204 PMKIDCacheIndex--;
8205
8206 /*delete the last PMKID cache in CSR*/
Wilson Yangef657d32014-01-15 19:19:23 -08008207 if (eHAL_STATUS_SUCCESS !=
8208 sme_RoamDelPMKIDfromCache(halHandle, pAdapter->sessionId, pmksa->bssid))
Wilson Yang6507c4e2013-10-01 20:11:19 -07008209 {
8210 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: cannot delete PMKSA %d CONTENT.",
8211 __func__,PMKIDCacheIndex);
Wilson Yangef657d32014-01-15 19:19:23 -08008212 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -07008213 }
8214
8215 dump_bssid(pmksa->bssid);
8216 dump_pmkid(halHandle,pmksa->pmkid);
8217
8218 break;
8219 }
8220 }
8221
8222 /* we compare all entries,but cannot find matching entry */
8223 if (j == MAX_PMKSAIDS_IN_CACHE && !BSSIDMatched)
8224 {
Jeff Johnson0299d0a2013-10-30 12:37:43 -07008225 hddLog(VOS_TRACE_LEVEL_FATAL,
8226 "%s: No such PMKSA entry existed " MAC_ADDRESS_STR,
8227 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
Wilson Yang6507c4e2013-10-01 20:11:19 -07008228 dump_bssid(pmksa->bssid);
8229 dump_pmkid(halHandle, pmksa->pmkid);
8230 return -EINVAL;
8231 }
Wilson Yangef657d32014-01-15 19:19:23 -08008232 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008233}
8234
Wilson Yang6507c4e2013-10-01 20:11:19 -07008235
8236
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008237static int wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
8238{
Wilson Yang6507c4e2013-10-01 20:11:19 -07008239 tANI_U32 j=0;
8240 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
8241 tHalHandle halHandle;
8242 hdd_context_t *pHddCtx;
8243 tANI_U8 *pBSSId;
Wilson Yangef657d32014-01-15 19:19:23 -08008244 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -07008245
8246 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: flushing PMKSA ",__func__);
8247
8248 /* Validate pAdapter */
8249 if (NULL == pAdapter)
8250 {
8251 hddLog(VOS_TRACE_LEVEL_ERROR,
8252 "%s: Invalid Adapter" ,__func__);
8253 return -EINVAL;
8254 }
8255
8256 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8257 status = wlan_hdd_validate_context(pHddCtx);
8258
8259 if (0 != status)
8260 {
8261 hddLog(VOS_TRACE_LEVEL_ERROR,
8262 "%s: HDD context is not valid", __func__);
8263 return status;
8264 }
8265
8266 /*Retrieve halHandle*/
8267 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
8268
8269 /*in case index is 0,no entry to delete*/
8270 if (0 == PMKIDCacheIndex)
8271 {
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +05308272 hddLog(VOS_TRACE_LEVEL_ERROR, FL("No entries to flush"));
Wilson Yang6507c4e2013-10-01 20:11:19 -07008273 return -EINVAL;
8274 }
8275
8276 /*delete all the PMKSA one by one */
8277 for (j = 0; j<PMKIDCacheIndex; j++)
8278 {
Wilson Yang6507c4e2013-10-01 20:11:19 -07008279 pBSSId =(tANI_U8 *)(PMKIDCache[j].BSSID);
Wilson Yang6507c4e2013-10-01 20:11:19 -07008280
8281 /*delete the PMKID in CSR*/
Wilson Yangef657d32014-01-15 19:19:23 -08008282 if (eHAL_STATUS_SUCCESS !=
8283 sme_RoamDelPMKIDfromCache(halHandle, pAdapter->sessionId, pBSSId))
Wilson Yang6507c4e2013-10-01 20:11:19 -07008284 {
8285 hddLog(VOS_TRACE_LEVEL_ERROR ,"%s cannot flush PMKIDCache %d.",
8286 __func__,j);
Wilson Yangef657d32014-01-15 19:19:23 -08008287 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -07008288 }
Kiet Lam8d21d5b2013-10-31 17:18:29 +05308289 /*clear the entry in HDD cache 0--index-1 */
8290 vos_mem_zero(PMKIDCache[j].BSSID, WNI_CFG_BSSID_LEN);
8291 vos_mem_zero(PMKIDCache[j].PMKID, CSR_RSN_PMKID_SIZE);
Wilson Yang6507c4e2013-10-01 20:11:19 -07008292 }
8293
8294 PMKIDCacheIndex = 0;
Wilson Yangef657d32014-01-15 19:19:23 -08008295 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008296}
8297#endif
8298
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07008299#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308300static int wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07008301 struct net_device *dev, struct cfg80211_update_ft_ies_params *ftie)
8302{
8303 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
8304 hdd_station_ctx_t *pHddStaCtx;
8305
8306 if (NULL == pAdapter)
8307 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08008308 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07008309 return -ENODEV;
8310 }
8311
8312 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
8313
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308314 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
8315 TRACE_CODE_HDD_CFG80211_UPDATE_FT_IES,
8316 pAdapter->sessionId, pHddStaCtx->conn_info.connState));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07008317 // Added for debug on reception of Re-assoc Req.
8318 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
8319 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08008320 hddLog(LOGE, FL("Called with Ie of length = %zu when not associated"),
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07008321 ftie->ie_len);
Arif Hussain6d2a3322013-11-17 19:50:10 -08008322 hddLog(LOGE, FL("Should be Re-assoc Req IEs"));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07008323 }
8324
8325#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG
Arif Hussain6d2a3322013-11-17 19:50:10 -08008326 hddLog(LOGE, FL("%s called with Ie of length = %zu"), __func__,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07008327 ftie->ie_len);
8328#endif
8329
8330 // Pass the received FT IEs to SME
Gopichand Nakkala356fb102013-03-06 12:34:04 +05308331 sme_SetFTIEs( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
8332 (const u8 *)ftie->ie,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07008333 ftie->ie_len);
8334 return 0;
8335}
8336#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008337
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308338#ifdef FEATURE_WLAN_SCAN_PNO
8339
8340void hdd_cfg80211_sched_scan_done_callback(void *callbackContext,
8341 tSirPrefNetworkFoundInd *pPrefNetworkFoundInd)
8342{
8343 int ret;
8344 hdd_adapter_t* pAdapter = (hdd_adapter_t*)callbackContext;
8345 hdd_context_t *pHddCtx;
8346
Nirav Shah80830bf2013-12-31 16:35:12 +05308347 ENTER();
8348
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308349 if (NULL == pAdapter)
8350 {
Agarwal Ashish971c2882013-10-30 20:11:12 +05308351 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308352 "%s: HDD adapter is Null", __func__);
8353 return ;
8354 }
8355
8356 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8357 if (NULL == pHddCtx)
8358 {
8359 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8360 "%s: HDD context is Null!!!", __func__);
8361 return ;
8362 }
8363
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05308364 spin_lock(&pHddCtx->schedScan_lock);
8365 if (TRUE == pHddCtx->isWiphySuspended)
8366 {
8367 pHddCtx->isSchedScanUpdatePending = TRUE;
8368 spin_unlock(&pHddCtx->schedScan_lock);
8369 hddLog(VOS_TRACE_LEVEL_INFO,
8370 "%s: Update cfg80211 scan database after it resume", __func__);
8371 return ;
8372 }
8373 spin_unlock(&pHddCtx->schedScan_lock);
8374
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308375 ret = wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter);
8376
8377 if (0 > ret)
8378 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
8379
8380 cfg80211_sched_scan_results(pHddCtx->wiphy);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05308381 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8382 "%s: cfg80211 scan result database updated", __func__);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308383}
8384
8385/*
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +05308386 * FUNCTION: wlan_hdd_is_pno_allowed
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +05308387 * Disallow pno if any session is active
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +05308388 */
8389static eHalStatus wlan_hdd_is_pno_allowed(hdd_adapter_t *pAdapter)
8390{
8391 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
8392 hdd_adapter_t *pTempAdapter = NULL;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +05308393 hdd_station_ctx_t *pStaCtx;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +05308394 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8395 int status = 0;
8396 status = hdd_get_front_adapter(pHddCtx, &pAdapterNode);
8397
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +05308398 /* The current firmware design does not allow PNO during any
8399 * active sessions. Hence, determine the active sessions
8400 * and return a failure.
8401 */
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +05308402 while ((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status))
8403 {
8404 pTempAdapter = pAdapterNode->pAdapter;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +05308405 pStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pTempAdapter);
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +05308406
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +05308407 if (((WLAN_HDD_INFRA_STATION == pTempAdapter->device_mode)
8408 && (eConnectionState_NotConnected != pStaCtx->conn_info.connState))
8409 || (WLAN_HDD_P2P_CLIENT == pTempAdapter->device_mode)
8410 || (WLAN_HDD_P2P_GO == pTempAdapter->device_mode)
8411 || (WLAN_HDD_SOFTAP == pTempAdapter->device_mode)
8412 )
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +05308413 {
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +05308414 return eHAL_STATUS_FAILURE;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +05308415 }
8416 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
8417 pAdapterNode = pNext;
8418 }
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +05308419 return eHAL_STATUS_SUCCESS;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +05308420}
8421
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +05308422void hdd_cfg80211_sched_scan_start_status_cb(void *callbackContext, VOS_STATUS status)
8423{
8424 hdd_adapter_t *pAdapter = callbackContext;
8425 hdd_context_t *pHddCtx;
8426
8427 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
8428 {
8429 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8430 FL("Invalid adapter or adapter has invalid magic"));
8431 return;
8432 }
8433
8434 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8435 if (0 != wlan_hdd_validate_context(pHddCtx))
8436 {
8437 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8438 FL("HDD context is not valid"));
8439 return;
8440 }
8441
8442 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8443 FL("PNO enable response status = %d"), status);
8444
8445 pAdapter->pno_req_status = (status == VOS_STATUS_SUCCESS) ? 0 : -EBUSY;
8446 complete(&pAdapter->pno_comp_var);
8447}
8448
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +05308449/*
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308450 * FUNCTION: wlan_hdd_cfg80211_sched_scan_start
8451 * NL interface to enable PNO
8452 */
8453static int wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
8454 struct net_device *dev, struct cfg80211_sched_scan_request *request)
8455{
8456 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
8457 tpSirPNOScanReq pPnoRequest = NULL;
8458 hdd_context_t *pHddCtx;
8459 tHalHandle hHal;
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +05308460 v_U32_t i, indx, num_ch, tempInterval;
Sushant Kaushikd62d9782014-02-19 15:39:40 +05308461 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
8462 u8 channels_allowed[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308463 v_U32_t num_channels_allowed = WNI_CFG_VALID_CHANNEL_LIST_LEN;
8464 eHalStatus status = eHAL_STATUS_FAILURE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308465 int ret = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308466
8467 if (NULL == pAdapter)
8468 {
8469 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
8470 "%s: HDD adapter is Null", __func__);
8471 return -ENODEV;
8472 }
8473
8474 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05308475 ret = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308476
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05308477 if (0 != ret)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308478 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05308479 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8480 "%s: HDD context is not valid", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308481 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308482 }
8483
8484 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
8485 if (NULL == hHal)
8486 {
8487 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8488 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05308489 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308490 }
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +05308491
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +05308492 if (eHAL_STATUS_SUCCESS != wlan_hdd_is_pno_allowed(pAdapter))
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +05308493 {
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +05308494 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +05308495 FL("Cannot handle sched_scan"));
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +05308496 return -EBUSY;
8497 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308498
c_hpothu37f21312014-04-09 21:49:54 +05308499 if (TRUE == pHddCtx->isPnoEnable)
8500 {
8501 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
8502 FL("already PNO is enabled"));
8503 return -EBUSY;
8504 }
8505 pHddCtx->isPnoEnable = TRUE;
8506
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308507 pPnoRequest = (tpSirPNOScanReq) vos_mem_malloc(sizeof (tSirPNOScanReq));
8508 if (NULL == pPnoRequest)
8509 {
8510 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
8511 "%s: vos_mem_malloc failed", __func__);
c_hpothu37f21312014-04-09 21:49:54 +05308512 pHddCtx->isPnoEnable = FALSE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308513 return -ENOMEM;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308514 }
8515
Madan Mohan Koyyalamudic3f04352013-09-26 19:21:48 +05308516 memset(pPnoRequest, 0, sizeof (tSirPNOScanReq));
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308517 pPnoRequest->enable = 1; /*Enable PNO */
8518 pPnoRequest->ucNetworksCount = request->n_match_sets;
8519
8520 if (( !pPnoRequest->ucNetworksCount ) ||
8521 ( pPnoRequest->ucNetworksCount > SIR_PNO_MAX_SUPP_NETWORKS ))
8522 {
8523 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +05308524 "%s: Network input is not correct %d",
8525 __func__, pPnoRequest->ucNetworksCount);
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308526 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308527 goto error;
8528 }
8529
8530 if ( SIR_PNO_MAX_NETW_CHANNELS_EX < request->n_channels )
8531 {
8532 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +05308533 "%s: Incorrect number of channels %d",
8534 __func__, request->n_channels);
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308535 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308536 goto error;
8537 }
8538
8539 /* Framework provides one set of channels(all)
8540 * common for all saved profile */
8541 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
8542 channels_allowed, &num_channels_allowed))
8543 {
8544 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8545 "%s: failed to get valid channel list", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308546 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308547 goto error;
8548 }
8549 /* Checking each channel against allowed channel list */
8550 num_ch = 0;
Nirav Shah80830bf2013-12-31 16:35:12 +05308551 if (request->n_channels)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308552 {
Nirav Shah80830bf2013-12-31 16:35:12 +05308553 char chList [(request->n_channels*5)+1];
8554 int len;
8555 for (i = 0, len = 0; i < request->n_channels; i++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308556 {
Nirav Shah80830bf2013-12-31 16:35:12 +05308557 for (indx = 0; indx < num_channels_allowed; indx++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308558 {
Nirav Shah80830bf2013-12-31 16:35:12 +05308559 if (request->channels[i]->hw_value == channels_allowed[indx])
8560 {
8561 valid_ch[num_ch++] = request->channels[i]->hw_value;
8562 len += snprintf(chList+len, 5, "%d ",
8563 request->channels[i]->hw_value);
8564 break ;
8565 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308566 }
8567 }
Nirav Shah80830bf2013-12-31 16:35:12 +05308568 hddLog(VOS_TRACE_LEVEL_INFO,"Channel-List: %s ", chList);
8569 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308570
8571 /* Filling per profile params */
8572 for (i = 0; i < pPnoRequest->ucNetworksCount; i++)
8573 {
8574 pPnoRequest->aNetworks[i].ssId.length =
8575 request->match_sets[i].ssid.ssid_len;
8576
8577 if (( 0 == pPnoRequest->aNetworks[i].ssId.length ) ||
8578 ( pPnoRequest->aNetworks[i].ssId.length > 32 ) )
8579 {
8580 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +05308581 "%s: SSID Len %d is not correct for network %d",
8582 __func__, pPnoRequest->aNetworks[i].ssId.length, i);
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308583 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308584 goto error;
8585 }
8586
8587 memcpy(pPnoRequest->aNetworks[i].ssId.ssId,
8588 request->match_sets[i].ssid.ssid,
8589 request->match_sets[i].ssid.ssid_len);
8590 pPnoRequest->aNetworks[i].authentication = 0; /*eAUTH_TYPE_ANY*/
8591 pPnoRequest->aNetworks[i].encryption = 0; /*eED_ANY*/
8592 pPnoRequest->aNetworks[i].bcastNetwType = 0; /*eBCAST_UNKNOWN*/
8593
8594 /*Copying list of valid channel into request */
8595 memcpy(pPnoRequest->aNetworks[i].aChannels, valid_ch, num_ch);
8596 pPnoRequest->aNetworks[i].ucChannelCount = num_ch;
8597
8598 pPnoRequest->aNetworks[i].rssiThreshold = 0; //Default value
8599 }
8600
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +05308601 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnson59a121e2013-11-30 09:46:08 -08008602 "request->ie_len = %zu", request->ie_len);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +05308603 if ((0 < request->ie_len) && (NULL != request->ie))
8604 {
8605 pPnoRequest->us24GProbeTemplateLen = request->ie_len;
8606 memcpy(&pPnoRequest->p24GProbeTemplate, request->ie,
8607 pPnoRequest->us24GProbeTemplateLen);
8608
8609 pPnoRequest->us5GProbeTemplateLen = request->ie_len;
8610 memcpy(&pPnoRequest->p5GProbeTemplate, request->ie,
8611 pPnoRequest->us5GProbeTemplateLen);
8612 }
8613
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +05308614 /* Driver gets only one time interval which is hardcoded in
8615 * supplicant for 10000ms. Taking power consumption into account 6 timers
8616 * will be used, Timervalue is increased exponentially i.e 10,20,40,
8617 * 80,160,320 secs. And number of scan cycle for each timer
8618 * is configurable through INI param gPNOScanTimerRepeatValue.
8619 * If it is set to 0 only one timer will be used and PNO scan cycle
8620 * will be repeated after each interval specified by supplicant
8621 * till PNO is disabled.
8622 */
8623 if (0 == pHddCtx->cfg_ini->configPNOScanTimerRepeatValue)
8624 pPnoRequest->scanTimers.ucScanTimersCount = HDD_PNO_SCAN_TIMERS_SET_ONE;
8625 else
8626 pPnoRequest->scanTimers.ucScanTimersCount =
8627 HDD_PNO_SCAN_TIMERS_SET_MULTIPLE;
8628
8629 tempInterval = (request->interval)/1000;
8630 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8631 "Base scan interval = %d PNOScanTimerRepeatValue = %d",
8632 tempInterval, pHddCtx->cfg_ini->configPNOScanTimerRepeatValue);
8633 for ( i = 0; i < pPnoRequest->scanTimers.ucScanTimersCount; i++)
8634 {
8635 pPnoRequest->scanTimers.aTimerValues[i].uTimerRepeat =
8636 pHddCtx->cfg_ini->configPNOScanTimerRepeatValue;
8637 pPnoRequest->scanTimers.aTimerValues[i].uTimerValue = tempInterval;
8638 tempInterval *= 2;
8639 }
8640 //Repeat last timer until pno disabled.
8641 pPnoRequest->scanTimers.aTimerValues[i-1].uTimerRepeat = 0;
8642
Madan Mohan Koyyalamudid206c7b2013-09-26 22:54:51 +05308643 pPnoRequest->modePNO = SIR_PNO_MODE_IMMEDIATE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308644
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +05308645 INIT_COMPLETION(pAdapter->pno_comp_var);
8646 pPnoRequest->statusCallback = hdd_cfg80211_sched_scan_start_status_cb;
8647 pPnoRequest->callbackContext = pAdapter;
8648 pAdapter->pno_req_status = 0;
8649
Nirav Shah80830bf2013-12-31 16:35:12 +05308650 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8651 "SessionId %d, enable %d, modePNO %d, ucScanTimersCount %d",
8652 pAdapter->sessionId, pPnoRequest->enable, pPnoRequest->modePNO,
8653 pPnoRequest->scanTimers.ucScanTimersCount);
8654
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308655 status = sme_SetPreferredNetworkList(WLAN_HDD_GET_HAL_CTX(pAdapter),
8656 pPnoRequest, pAdapter->sessionId,
8657 hdd_cfg80211_sched_scan_done_callback, pAdapter);
8658 if (eHAL_STATUS_SUCCESS != status)
8659 {
8660 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +05308661 "%s: Failed to enable PNO", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308662 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308663 goto error;
8664 }
8665
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +05308666 ret = wait_for_completion_timeout(
8667 &pAdapter->pno_comp_var,
8668 msecs_to_jiffies(WLAN_WAIT_TIME_PNO));
8669 if (0 >= ret)
8670 {
8671 // Did not receive the response for PNO enable in time.
8672 // Assuming the PNO enable was success.
8673 // Returning error from here, because we timeout, results
8674 // in side effect of Wifi (Wifi Setting) not to work.
8675 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8676 FL("Timed out waiting for PNO to be Enabled"));
8677 ret = 0;
8678 goto error;
8679 }
8680
8681 ret = pAdapter->pno_req_status;
c_hpothu37f21312014-04-09 21:49:54 +05308682 return ret;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05308683
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308684error:
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +05308685 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8686 FL("PNO scanRequest offloaded ret = %d"), ret);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308687 vos_mem_free(pPnoRequest);
c_hpothu37f21312014-04-09 21:49:54 +05308688 pHddCtx->isPnoEnable = FALSE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308689 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308690}
8691
8692/*
8693 * FUNCTION: wlan_hdd_cfg80211_sched_scan_stop
8694 * NL interface to disable PNO
8695 */
8696static int wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
8697 struct net_device *dev)
8698{
8699 eHalStatus status = eHAL_STATUS_FAILURE;
8700 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
8701 hdd_context_t *pHddCtx;
8702 tHalHandle hHal;
8703 tpSirPNOScanReq pPnoRequest = NULL;
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308704 int ret = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308705
8706 ENTER();
8707
8708 if (NULL == pAdapter)
8709 {
8710 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
8711 "%s: HDD adapter is Null", __func__);
8712 return -ENODEV;
8713 }
8714
8715 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308716
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308717 if (NULL == pHddCtx)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308718 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05308719 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308720 "%s: HDD context is Null", __func__);
8721 return -ENODEV;
8722 }
8723
8724 /* The return 0 is intentional when isLogpInProgress and
8725 * isLoadUnloadInProgress. We did observe a crash due to a return of
8726 * failure in sched_scan_stop , especially for a case where the unload
8727 * of the happens at the same time. The function __cfg80211_stop_sched_scan
8728 * was clearing rdev->sched_scan_req only when the sched_scan_stop returns
8729 * success. If it returns a failure , then its next invocation due to the
8730 * clean up of the second interface will have the dev pointer corresponding
8731 * to the first one leading to a crash.
8732 */
8733 if (pHddCtx->isLogpInProgress)
8734 {
8735 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8736 "%s: LOGP in Progress. Ignore!!!", __func__);
8737 return ret;
8738 }
8739
Mihir Shete18156292014-03-11 15:38:30 +05308740 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308741 {
8742 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8743 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
8744 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308745 }
8746
8747 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
8748 if (NULL == hHal)
8749 {
8750 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8751 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05308752 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308753 }
8754
8755 pPnoRequest = (tpSirPNOScanReq) vos_mem_malloc(sizeof (tSirPNOScanReq));
8756 if (NULL == pPnoRequest)
8757 {
8758 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
8759 "%s: vos_mem_malloc failed", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308760 return -ENOMEM;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308761 }
8762
8763 memset(pPnoRequest, 0, sizeof (tSirPNOScanReq));
8764 pPnoRequest->enable = 0; /* Disable PNO */
8765 pPnoRequest->ucNetworksCount = 0;
8766
8767 status = sme_SetPreferredNetworkList(hHal, pPnoRequest,
8768 pAdapter->sessionId,
8769 NULL, pAdapter);
8770 if (eHAL_STATUS_SUCCESS != status)
8771 {
8772 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8773 "Failed to disabled PNO");
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308774 ret = -EINVAL;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +05308775 goto error;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308776 }
c_hpothu37f21312014-04-09 21:49:54 +05308777 pHddCtx->isPnoEnable = FALSE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308778
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +05308779error:
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05308780 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +05308781 FL("PNO scan disabled ret = %d"), ret);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308782 vos_mem_free(pPnoRequest);
8783
8784 EXIT();
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308785 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308786}
8787
8788#endif /*FEATURE_WLAN_SCAN_PNO*/
8789
8790
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008791#ifdef FEATURE_WLAN_TDLS
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +05308792#if TDLS_MGMT_VERSION2
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008793static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
8794 u8 *peer, u8 action_code, u8 dialog_token,
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +05308795 u16 status_code, u32 peer_capability, const u8 *buf, size_t len)
8796#else
8797static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
8798 u8 *peer, u8 action_code, u8 dialog_token,
8799 u16 status_code, const u8 *buf, size_t len)
8800#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008801{
8802
8803 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
8804 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008805 u8 peerMac[6];
8806 VOS_STATUS status;
Gopichand Nakkala05922802013-03-14 12:23:19 -07008807 int max_sta_failed = 0;
Hoonki Leea34dd892013-02-05 22:56:02 -08008808 int responder;
Hoonki Leed37cbb32013-04-20 00:31:14 -07008809 long rc;
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +05308810#if !(TDLS_MGMT_VERSION2)
8811 u32 peer_capability = 0;
8812#endif
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05308813 tANI_U16 numCurrTdlsPeers;
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008814
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308815 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
8816 TRACE_CODE_HDD_CFG80211_TDLS_MGMT,
8817 pAdapter->sessionId, action_code));
Hoonki Lee11f7dda2013-02-14 16:55:44 -08008818 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008819 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308820 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008821 "Invalid arguments");
8822 return -EINVAL;
8823 }
8824
Sameer Thalappil75ea31a2013-02-21 19:38:16 -08008825 if (pHddCtx->isLogpInProgress)
8826 {
8827 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8828 "%s:LOGP in Progress. Ignore!!!", __func__);
Gopichand Nakkala05922802013-03-14 12:23:19 -07008829 wlan_hdd_tdls_set_link_status(pAdapter, peer, eTDLS_LINK_IDLE);
Sameer Thalappil75ea31a2013-02-21 19:38:16 -08008830 return -EBUSY;
8831 }
8832
Hoonki Lee27511902013-03-14 18:19:06 -07008833 if (eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode)
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008834 {
Hoonki Lee27511902013-03-14 18:19:06 -07008835 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
8836 "%s: TDLS mode is disabled OR not enabled in FW."
8837 MAC_ADDRESS_STR " action %d declined.",
8838 __func__, MAC_ADDR_ARRAY(peer), action_code);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008839 return -ENOTSUPP;
8840 }
Lee Hoonkic1262f22013-01-24 21:59:00 -08008841
Hoonki Lee27511902013-03-14 18:19:06 -07008842 /* other than teardown frame, other mgmt frames are not sent if disabled */
8843 if (SIR_MAC_TDLS_TEARDOWN != action_code)
8844 {
8845 /* if tdls_mode is disabled to respond to peer's request */
8846 if (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode)
8847 {
8848 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
8849 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07008850 " TDLS mode is disabled. action %d declined.",
8851 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee27511902013-03-14 18:19:06 -07008852
8853 return -ENOTSUPP;
8854 }
8855 }
8856
Gopichand Nakkalab977a972013-02-18 19:15:09 -08008857 if (WLAN_IS_TDLS_SETUP_ACTION(action_code))
8858 {
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308859 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, peer, TRUE))
Gopichand Nakkalab977a972013-02-18 19:15:09 -08008860 {
8861 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07008862 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07008863 " TDLS setup is ongoing. action %d declined.",
8864 __func__, MAC_ADDR_ARRAY(peer), action_code);
8865 return -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -08008866 }
8867 }
8868
Hoonki Lee11f7dda2013-02-14 16:55:44 -08008869 if (SIR_MAC_TDLS_SETUP_REQ == action_code ||
8870 SIR_MAC_TDLS_SETUP_RSP == action_code )
Lee Hoonkic1262f22013-01-24 21:59:00 -08008871 {
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05308872 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
8873 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Lee Hoonkic1262f22013-01-24 21:59:00 -08008874 {
8875 /* supplicant still sends tdls_mgmt(SETUP_REQ) even after
8876 we return error code at 'add_station()'. Hence we have this
8877 check again in addtion to add_station().
8878 Anyway, there is no hard to double-check. */
Hoonki Lee11f7dda2013-02-14 16:55:44 -08008879 if (SIR_MAC_TDLS_SETUP_REQ == action_code)
Lee Hoonkic1262f22013-01-24 21:59:00 -08008880 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07008881 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8882 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05308883 " TDLS Max peer already connected. action (%d) declined. Num of peers (%d), Max allowed (%d).",
8884 __func__, MAC_ADDR_ARRAY(peer), action_code,
8885 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Sunil Dutt388ac8f2013-11-28 18:06:52 +05308886 return -EINVAL;
Lee Hoonkic1262f22013-01-24 21:59:00 -08008887 }
8888 else
8889 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -08008890 /* maximum reached. tweak to send error code to peer and return
8891 error code to supplicant */
Lee Hoonkic1262f22013-01-24 21:59:00 -08008892 status_code = eSIR_MAC_UNSPEC_FAILURE_STATUS;
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07008893 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8894 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05308895 " TDLS Max peer already connected, send response status (%d). Num of peers (%d), Max allowed (%d).",
8896 __func__, MAC_ADDR_ARRAY(peer), status_code,
8897 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -07008898 max_sta_failed = -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -08008899 /* fall through to send setup resp with failure status
8900 code */
Lee Hoonkic1262f22013-01-24 21:59:00 -08008901 }
8902 }
Hoonki Lee11f7dda2013-02-14 16:55:44 -08008903 else
8904 {
8905 hddTdlsPeer_t *pTdlsPeer;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308906 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008907 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Hoonki Lee11f7dda2013-02-14 16:55:44 -08008908 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07008909 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07008910 "%s:" MAC_ADDRESS_STR " already connected. action %d declined.",
8911 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee11f7dda2013-02-14 16:55:44 -08008912 return -EPERM;
8913 }
8914 }
Lee Hoonkic1262f22013-01-24 21:59:00 -08008915 }
Hoonki Lee11f7dda2013-02-14 16:55:44 -08008916 vos_mem_copy(peerMac, peer, 6);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008917
Hoonki Lee1090c6a2013-01-16 17:40:54 -08008918#ifdef WLAN_FEATURE_TDLS_DEBUG
8919 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +05308920 "%s: " MAC_ADDRESS_STR " action %d, dialog_token %d status %d, len = %zu",
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07008921 "tdls_mgmt", MAC_ADDR_ARRAY(peer),
8922 action_code, dialog_token, status_code, len);
Hoonki Lee1090c6a2013-01-16 17:40:54 -08008923#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008924
Hoonki Leea34dd892013-02-05 22:56:02 -08008925 /*Except teardown responder will not be used so just make 0*/
8926 responder = 0;
Hoonki Lee11f7dda2013-02-14 16:55:44 -08008927 if (SIR_MAC_TDLS_TEARDOWN == action_code)
Hoonki Leea34dd892013-02-05 22:56:02 -08008928 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -07008929
8930 hddTdlsPeer_t *pTdlsPeer;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308931 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peerMac, TRUE);
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -07008932
8933 if(pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
8934 responder = pTdlsPeer->is_responder;
8935 else
Hoonki Leea34dd892013-02-05 22:56:02 -08008936 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -07008937 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +05308938 "%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 -07008939 __func__, MAC_ADDR_ARRAY(peer), (NULL == pTdlsPeer) ? -1 : pTdlsPeer->link_status,
8940 dialog_token, status_code, len);
8941 return -EPERM;
Hoonki Leea34dd892013-02-05 22:56:02 -08008942 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008943 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008944
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +05308945 /* For explicit trigger of DIS_REQ come out of BMPS for
8946 successfully receiving DIS_RSP from peer. */
Hoonki Lee14621352013-04-16 17:51:19 -07008947 if ((SIR_MAC_TDLS_SETUP_RSP == action_code) ||
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +05308948 (SIR_MAC_TDLS_DIS_RSP == action_code) ||
8949 (SIR_MAC_TDLS_DIS_REQ == action_code))
Hoonki Lee14621352013-04-16 17:51:19 -07008950 {
8951 if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter)))
8952 {
8953 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +05308954 "%s: Sending frame action_code %u.Disable BMPS", __func__, action_code);
Hoonki Lee14621352013-04-16 17:51:19 -07008955 hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
8956 }
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +05308957 if (SIR_MAC_TDLS_DIS_REQ != action_code)
8958 wlan_hdd_tdls_set_cap(pAdapter, peerMac, eTDLS_CAP_SUPPORTED);
Hoonki Lee14621352013-04-16 17:51:19 -07008959 }
8960
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008961 /* make sure doesn't call send_mgmt() while it is pending */
8962 if (TDLS_CTX_MAGIC == pAdapter->mgmtTxCompletionStatus)
8963 {
8964 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008965 "%s: " MAC_ADDRESS_STR " action %d couldn't sent, as one is pending. return EBUSY",
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008966 __func__, MAC_ADDR_ARRAY(peer), action_code);
8967 return -EBUSY;
8968 }
8969
8970 pAdapter->mgmtTxCompletionStatus = TDLS_CTX_MAGIC;
Gopichand Nakkalab977a972013-02-18 19:15:09 -08008971 INIT_COMPLETION(pAdapter->tdls_mgmt_comp);
8972
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008973 status = sme_SendTdlsMgmtFrame(WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
Pradeep Reddy POTTETIca171f82014-03-21 14:17:35 +05308974 peerMac, action_code, dialog_token, status_code, peer_capability, (tANI_U8 *)buf, len, responder);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008975
Gopichand Nakkalab977a972013-02-18 19:15:09 -08008976 if (VOS_STATUS_SUCCESS != status)
8977 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008978 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8979 "%s: sme_SendTdlsMgmtFrame failed!", __func__);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008980 pAdapter->mgmtTxCompletionStatus = FALSE;
Hoonki Lee14621352013-04-16 17:51:19 -07008981 wlan_hdd_tdls_check_bmps(pAdapter);
Sunil Dutt388ac8f2013-11-28 18:06:52 +05308982 return -EINVAL;
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008983 }
8984
Hoonki Leed37cbb32013-04-20 00:31:14 -07008985 rc = wait_for_completion_interruptible_timeout(&pAdapter->tdls_mgmt_comp,
8986 msecs_to_jiffies(WAIT_TIME_TDLS_MGMT));
8987
8988 if ((rc <= 0) || (TRUE != pAdapter->mgmtTxCompletionStatus))
Gopichand Nakkalab977a972013-02-18 19:15:09 -08008989 {
Hoonki Leed37cbb32013-04-20 00:31:14 -07008990 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07008991 "%s: Mgmt Tx Completion failed status %ld TxCompletion %u",
Hoonki Leed37cbb32013-04-20 00:31:14 -07008992 __func__, rc, pAdapter->mgmtTxCompletionStatus);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008993 pAdapter->mgmtTxCompletionStatus = FALSE;
Yue Ma4f55ef32014-01-23 16:45:33 -08008994
8995 if (pHddCtx->isLogpInProgress)
8996 {
8997 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8998 "%s: LOGP in Progress. Ignore!!!", __func__);
8999 return -EAGAIN;
9000 }
9001
Hoonki Leed37cbb32013-04-20 00:31:14 -07009002 wlan_hdd_tdls_check_bmps(pAdapter);
Sunil Dutt388ac8f2013-11-28 18:06:52 +05309003 return -EINVAL;
Gopichand Nakkalab977a972013-02-18 19:15:09 -08009004 }
9005
Gopichand Nakkala05922802013-03-14 12:23:19 -07009006 if (max_sta_failed)
Hoonki Lee14621352013-04-16 17:51:19 -07009007 {
9008 wlan_hdd_tdls_check_bmps(pAdapter);
Gopichand Nakkala05922802013-03-14 12:23:19 -07009009 return max_sta_failed;
Hoonki Lee14621352013-04-16 17:51:19 -07009010 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -08009011
Hoonki Leea34dd892013-02-05 22:56:02 -08009012 if (SIR_MAC_TDLS_SETUP_RSP == action_code)
9013 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -08009014 wlan_hdd_tdls_set_responder(pAdapter, peerMac, TRUE);
Hoonki Leea34dd892013-02-05 22:56:02 -08009015 }
9016 else if (SIR_MAC_TDLS_SETUP_CNF == action_code)
9017 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -08009018 wlan_hdd_tdls_set_responder(pAdapter, peerMac, FALSE);
Hoonki Leea34dd892013-02-05 22:56:02 -08009019 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009020
9021 return 0;
9022}
9023
9024static int wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
9025 u8 *peer, enum nl80211_tdls_operation oper)
9026{
9027 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
9028 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309029 int status;
Hoonki Lee5305c3a2013-04-29 23:28:59 -07009030 hddTdlsPeer_t *pTdlsPeer;
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009031
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309032 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
9033 TRACE_CODE_HDD_CFG80211_TDLS_OPER,
9034 pAdapter->sessionId, oper));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309035 if ( NULL == peer )
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009036 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -08009037 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chilam Ngc4244af2013-04-01 15:37:32 -07009038 "%s: Invalid arguments", __func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009039 return -EINVAL;
9040 }
Hoonki Lee1090c6a2013-01-16 17:40:54 -08009041
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309042 status = wlan_hdd_validate_context(pHddCtx);
9043
9044 if (0 != status)
Sameer Thalappil75ea31a2013-02-21 19:38:16 -08009045 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309046 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9047 "%s: HDD context is not valid", __func__);
9048 return status;
Sameer Thalappil75ea31a2013-02-21 19:38:16 -08009049 }
9050
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009051
9052 if( FALSE == pHddCtx->cfg_ini->fEnableTDLSSupport ||
Hoonki Lee1090c6a2013-01-16 17:40:54 -08009053 FALSE == sme_IsFeatureSupportedByFW(TDLS))
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009054 {
Hoonki Lee1090c6a2013-01-16 17:40:54 -08009055 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chilam Ngc4244af2013-04-01 15:37:32 -07009056 "TDLS Disabled in INI OR not enabled in FW. "
9057 "Cannot process TDLS commands");
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009058 return -ENOTSUPP;
9059 }
9060
9061 switch (oper) {
9062 case NL80211_TDLS_ENABLE_LINK:
9063 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009064 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309065 long ret;
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05309066 tCsrTdlsLinkEstablishParams tdlsLinkEstablishParams;
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009067
Sunil Dutt41de4e22013-11-14 18:09:02 +05309068 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
9069
9070 if ( NULL == pTdlsPeer ) {
9071 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
9072 " (oper %d) not exsting. ignored",
9073 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
9074 return -EINVAL;
9075 }
9076
9077 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9078 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
9079 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
9080 "NL80211_TDLS_ENABLE_LINK");
9081
Gopichand Nakkala2f4a2822013-04-17 11:22:01 -07009082 if (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
9083 {
9084 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Staion Index %u "
9085 MAC_ADDRESS_STR " failed",
9086 __func__, pTdlsPeer->staId, MAC_ADDR_ARRAY(peer));
9087 return -EINVAL;
9088 }
9089
Hoonki Lee5305c3a2013-04-29 23:28:59 -07009090 if (eTDLS_LINK_CONNECTED != pTdlsPeer->link_status)
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07009091 {
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +05309092 if (IS_ADVANCE_TDLS_ENABLE) {
Gopichand Nakkala24be5312013-07-02 16:47:12 +05309093
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +05309094 if (0 != wlan_hdd_tdls_get_link_establish_params(
9095 pAdapter, peer,&tdlsLinkEstablishParams)) {
9096 return -EINVAL;
9097 }
9098 INIT_COMPLETION(pAdapter->tdls_link_establish_req_comp);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05309099
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +05309100 sme_SendTdlsLinkEstablishParams(WLAN_HDD_GET_HAL_CTX(pAdapter),
9101 pAdapter->sessionId, peer, &tdlsLinkEstablishParams);
9102 /* Send TDLS peer UAPSD capabilities to the firmware and
9103 * register with the TL on after the response for this operation
9104 * is received .
9105 */
9106 ret = wait_for_completion_interruptible_timeout(
9107 &pAdapter->tdls_link_establish_req_comp,
9108 msecs_to_jiffies(WAIT_TIME_TDLS_LINK_ESTABLISH_REQ));
9109 if (ret <= 0)
9110 {
9111 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9112 "%s: Link Establish Request Faled Status %ld",
9113 __func__, ret);
9114 return -EINVAL;
9115 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05309116 }
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -07009117 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer, eTDLS_LINK_CONNECTED);
Gopichand Nakkala471708b2013-06-04 20:03:01 +05309118 /* Mark TDLS client Authenticated .*/
9119 status = WLANTL_ChangeSTAState( pHddCtx->pvosContext,
9120 pTdlsPeer->staId,
9121 WLANTL_STA_AUTHENTICATED);
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -07009122 if (VOS_STATUS_SUCCESS == status)
9123 {
Hoonki Lee14621352013-04-16 17:51:19 -07009124 if (pTdlsPeer->is_responder == 0)
9125 {
9126 v_U8_t staId = (v_U8_t)pTdlsPeer->staId;
9127
9128 wlan_hdd_tdls_timer_restart(pAdapter,
9129 &pTdlsPeer->initiatorWaitTimeoutTimer,
9130 WAIT_TIME_TDLS_INITIATOR);
9131 /* suspend initiator TX until it receives direct packet from the
9132 reponder or WAIT_TIME_TDLS_INITIATOR timer expires */
9133 WLANTL_SuspendDataTx( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
9134 &staId, NULL);
9135 }
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -07009136 wlan_hdd_tdls_increment_peer_count(pAdapter);
9137 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07009138 wlan_hdd_tdls_check_bmps(pAdapter);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05309139
9140 /* Update TL about the UAPSD masks , to route the packets to firmware */
Gopichand Nakkala574f6d12013-06-27 19:38:43 +05309141 if ((TRUE == pHddCtx->cfg_ini->fEnableTDLSBufferSta)
9142 || pHddCtx->cfg_ini->fTDLSUapsdMask )
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05309143 {
Gopichand Nakkala574f6d12013-06-27 19:38:43 +05309144 int ac;
9145 uint8 ucAc[4] = { WLANTL_AC_VO,
9146 WLANTL_AC_VI,
9147 WLANTL_AC_BK,
9148 WLANTL_AC_BE };
9149 uint8 tlTid[4] = { 7, 5, 2, 3 } ;
9150 for(ac=0; ac < 4; ac++)
9151 {
9152 status = WLANTL_EnableUAPSDForAC( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
9153 pTdlsPeer->staId, ucAc[ac],
9154 tlTid[ac], tlTid[ac], 0, 0,
9155 WLANTL_BI_DIR );
9156 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05309157 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07009158 }
9159
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009160 }
9161 break;
9162 case NL80211_TDLS_DISABLE_LINK:
Lee Hoonkic1262f22013-01-24 21:59:00 -08009163 {
Sunil Dutt41de4e22013-11-14 18:09:02 +05309164 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
9165
9166 if ( NULL == pTdlsPeer ) {
9167 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
9168 " (oper %d) not exsting. ignored",
9169 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
9170 return -EINVAL;
9171 }
9172
9173 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9174 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
9175 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
9176 "NL80211_TDLS_DISABLE_LINK");
9177
Hoonki Lee5305c3a2013-04-29 23:28:59 -07009178 if(TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
Lee Hoonkic1262f22013-01-24 21:59:00 -08009179 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009180 long status;
9181
9182 INIT_COMPLETION(pAdapter->tdls_del_station_comp);
9183
Lee Hoonkic1262f22013-01-24 21:59:00 -08009184 sme_DeleteTdlsPeerSta( WLAN_HDD_GET_HAL_CTX(pAdapter),
9185 pAdapter->sessionId, peer );
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009186
9187 status = wait_for_completion_interruptible_timeout(&pAdapter->tdls_del_station_comp,
9188 msecs_to_jiffies(WAIT_TIME_TDLS_DEL_STA));
9189 if (status <= 0)
9190 {
Hoonki Lee5305c3a2013-04-29 23:28:59 -07009191 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer, eTDLS_LINK_IDLE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009192 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9193 "%s: Del station failed status %ld",
9194 __func__, status);
9195 return -EPERM;
9196 }
Hoonki Lee5305c3a2013-04-29 23:28:59 -07009197 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer, eTDLS_LINK_IDLE);
Lee Hoonkic1262f22013-01-24 21:59:00 -08009198 }
9199 else
9200 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07009201 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9202 "%s: TDLS Peer Station doesn't exist.", __func__);
Lee Hoonkic1262f22013-01-24 21:59:00 -08009203 }
Lee Hoonkic1262f22013-01-24 21:59:00 -08009204 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07009205 break;
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009206 case NL80211_TDLS_TEARDOWN:
Sunil Dutt41de4e22013-11-14 18:09:02 +05309207 {
9208 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9209 " %s : NL80211_TDLS_TEARDOWN for " MAC_ADDRESS_STR,
9210 __func__, MAC_ADDR_ARRAY(peer));
9211
9212 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
9213 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
9214
9215 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9216 " %s TDLS External control and Implicit Trigger not enabled ",
9217 __func__);
9218 return -ENOTSUPP;
9219 }
9220
Sunil Dutt41de4e22013-11-14 18:09:02 +05309221
9222 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
9223
9224 if ( NULL == pTdlsPeer ) {
9225 hddLog(VOS_TRACE_LEVEL_INFO, "%s: " MAC_ADDRESS_STR
9226 " peer not exsting",
9227 __func__, MAC_ADDR_ARRAY(peer));
Naresh Jayaram937abdf2013-11-26 19:50:25 +05309228 return -EINVAL;
Sunil Dutt41de4e22013-11-14 18:09:02 +05309229 }
9230 else {
9231 wlan_hdd_tdls_indicate_teardown(pAdapter, pTdlsPeer,
9232 eSIR_MAC_TDLS_TEARDOWN_UNSPEC_REASON);
9233 }
Naresh Jayaram937abdf2013-11-26 19:50:25 +05309234
9235 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, FALSE) )
9236 return -EINVAL;
Sunil Dutt41de4e22013-11-14 18:09:02 +05309237 break;
9238 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009239 case NL80211_TDLS_SETUP:
Sunil Dutt41de4e22013-11-14 18:09:02 +05309240 {
Naresh Jayaramdb4514b2013-11-25 18:08:10 +05309241 hddTdlsPeer_t *pTdlsPeer;
Sunil Dutt41de4e22013-11-14 18:09:02 +05309242 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9243 " %s : NL80211_TDLS_SETUP for " MAC_ADDRESS_STR,
9244 __func__, MAC_ADDR_ARRAY(peer));
9245
9246 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
9247 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
9248
9249 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9250 " %s TDLS External control and Implicit Trigger not enabled ",
9251 __func__);
9252 return -ENOTSUPP;
9253 }
9254
Naresh Jayaramdb4514b2013-11-25 18:08:10 +05309255 /* To cater the requirement of establishing the TDLS link
9256 * irrespective of the data traffic , get an entry of TDLS peer.
9257 */
9258 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, peer);
9259 if (pTdlsPeer == NULL) {
9260 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9261 "%s: peer " MAC_ADDRESS_STR " not existing",
9262 __func__, MAC_ADDR_ARRAY(peer));
9263 return -EINVAL;
9264 }
Naresh Jayaram937abdf2013-11-26 19:50:25 +05309265
9266 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, TRUE) ) {
9267
9268 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9269 " %s TDLS Add Force Peer Failed",
9270 __func__);
9271 return -EINVAL;
9272 }
Naresh Jayaramdb4514b2013-11-25 18:08:10 +05309273 break;
Sunil Dutt41de4e22013-11-14 18:09:02 +05309274 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009275 case NL80211_TDLS_DISCOVERY_REQ:
9276 /* We don't support in-driver setup/teardown/discovery */
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309277 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
9278 "%s: We don't support in-driver setup/teardown/discovery "
9279 ,__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009280 return -ENOTSUPP;
9281 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309282 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9283 "%s: unsupported event",__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009284 return -ENOTSUPP;
9285 }
9286 return 0;
9287}
Chilam NG571c65a2013-01-19 12:27:36 +05309288
9289int wlan_hdd_cfg80211_send_tdls_discover_req(struct wiphy *wiphy,
9290 struct net_device *dev, u8 *peer)
9291{
Arif Hussaina7c8e412013-11-20 11:06:42 -08009292 hddLog(VOS_TRACE_LEVEL_INFO,
9293 "tdls send discover req: "MAC_ADDRESS_STR,
9294 MAC_ADDR_ARRAY(peer));
Chilam NG571c65a2013-01-19 12:27:36 +05309295
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +05309296#if TDLS_MGMT_VERSION2
9297 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
9298 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
9299#else
Chilam NG571c65a2013-01-19 12:27:36 +05309300 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
9301 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, NULL, 0);
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +05309302#endif
Chilam NG571c65a2013-01-19 12:27:36 +05309303}
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009304#endif
9305
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309306#ifdef WLAN_FEATURE_GTK_OFFLOAD
9307/*
9308 * FUNCTION: wlan_hdd_cfg80211_update_replayCounterCallback
9309 * Callback rountine called upon receiving response for
9310 * get offload info
9311 */
9312void wlan_hdd_cfg80211_update_replayCounterCallback(void *callbackContext,
9313 tpSirGtkOffloadGetInfoRspParams pGtkOffloadGetInfoRsp)
9314{
9315
9316 hdd_adapter_t *pAdapter = (hdd_adapter_t *)callbackContext;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05309317 tANI_U8 tempReplayCounter[8];
9318 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309319
9320 ENTER();
9321
9322 if (NULL == pAdapter)
9323 {
Agarwal Ashish971c2882013-10-30 20:11:12 +05309324 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309325 "%s: HDD adapter is Null", __func__);
9326 return ;
9327 }
9328
9329 if (NULL == pGtkOffloadGetInfoRsp)
9330 {
9331 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9332 "%s: pGtkOffloadGetInfoRsp is Null", __func__);
9333 return ;
9334 }
9335
9336 if (VOS_STATUS_SUCCESS != pGtkOffloadGetInfoRsp->ulStatus)
9337 {
9338 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9339 "%s: wlan Failed to get replay counter value",
9340 __func__);
9341 return ;
9342 }
9343
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05309344 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9345 /* Update replay counter */
9346 pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter =
9347 pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
9348
9349 {
9350 /* changing from little to big endian since supplicant
9351 * works on big endian format
9352 */
9353 int i;
9354 tANI_U8 *p = (tANI_U8 *)&pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
9355
9356 for (i = 0; i < 8; i++)
9357 {
9358 tempReplayCounter[7-i] = (tANI_U8)p[i];
9359 }
9360 }
9361
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309362 /* Update replay counter to NL */
9363 cfg80211_gtk_rekey_notify(pAdapter->dev, pGtkOffloadGetInfoRsp->bssId,
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05309364 tempReplayCounter, GFP_KERNEL);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309365}
9366
9367/*
9368 * FUNCTION: wlan_hdd_cfg80211_set_rekey_data
9369 * This function is used to offload GTK rekeying job to the firmware.
9370 */
9371int wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
9372 struct cfg80211_gtk_rekey_data *data)
9373{
9374 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
9375 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
9376 hdd_station_ctx_t *pHddStaCtx;
9377 tHalHandle hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309378 int result;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05309379 tSirGtkOffloadParams hddGtkOffloadReqParams;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309380 eHalStatus status = eHAL_STATUS_FAILURE;
9381
9382 ENTER();
9383
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309384
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309385 if (NULL == pAdapter)
9386 {
9387 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
9388 "%s: HDD adapter is Null", __func__);
9389 return -ENODEV;
9390 }
9391
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309392 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
9393 TRACE_CODE_HDD_CFG80211_SET_REKEY_DATA,
9394 pAdapter->sessionId, pAdapter->device_mode));
9395
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309396 result = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309397
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309398 if (0 != result)
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309399 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309400 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9401 "%s: HDD context is not valid", __func__);
9402 return result;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309403 }
9404
9405 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9406 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
9407 if (NULL == hHal)
9408 {
9409 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9410 "%s: HAL context is Null!!!", __func__);
9411 return -EAGAIN;
9412 }
9413
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05309414 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_ENABLE;
9415 memcpy(pHddStaCtx->gtkOffloadReqParams.aKCK, data->kck, NL80211_KCK_LEN);
9416 memcpy(pHddStaCtx->gtkOffloadReqParams.aKEK, data->kek, NL80211_KEK_LEN);
9417 memcpy(pHddStaCtx->gtkOffloadReqParams.bssId, &pHddStaCtx->conn_info.bssId,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309418 WNI_CFG_BSSID_LEN);
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05309419 {
9420 /* changing from big to little endian since driver
9421 * works on little endian format
9422 */
9423 tANI_U8 *p =
9424 (tANI_U8 *)&pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter;
9425 int i;
9426
9427 for (i = 0; i < 8; i++)
9428 {
9429 p[7-i] = data->replay_ctr[i];
9430 }
9431 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309432
9433 if (TRUE == pHddCtx->hdd_wlan_suspended)
9434 {
9435 /* if wlan is suspended, enable GTK offload directly from here */
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05309436 memcpy(&hddGtkOffloadReqParams, &pHddStaCtx->gtkOffloadReqParams,
9437 sizeof (tSirGtkOffloadParams));
9438 status = sme_SetGTKOffload(hHal, &hddGtkOffloadReqParams,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309439 pAdapter->sessionId);
9440
9441 if (eHAL_STATUS_SUCCESS != status)
9442 {
9443 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9444 "%s: sme_SetGTKOffload failed, returned %d",
9445 __func__, status);
9446 return status;
9447 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309448 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9449 "%s: sme_SetGTKOffload successfull", __func__);
9450 }
9451 else
9452 {
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309453 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9454 "%s: wlan not suspended GTKOffload request is stored",
9455 __func__);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309456 }
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05309457
9458 return eHAL_STATUS_SUCCESS;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309459}
9460#endif /*WLAN_FEATURE_GTK_OFFLOAD*/
9461
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05309462/*
9463 * FUNCTION: wlan_hdd_cfg80211_set_mac_acl
9464 * This function is used to set access control policy
9465 */
9466static int wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy,
9467 struct net_device *dev, const struct cfg80211_acl_data *params)
9468{
9469 int i;
9470 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
9471 hdd_hostapd_state_t *pHostapdState;
9472 tsap_Config_t *pConfig;
9473 v_CONTEXT_t pVosContext = NULL;
9474 hdd_context_t *pHddCtx;
9475 int status;
9476
9477 ENTER();
9478
9479 if (NULL == pAdapter)
9480 {
9481 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
9482 "%s: HDD adapter is Null", __func__);
9483 return -ENODEV;
9484 }
9485
9486 if (NULL == params)
9487 {
9488 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
9489 "%s: params is Null", __func__);
9490 return -EINVAL;
9491 }
9492
9493 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9494 status = wlan_hdd_validate_context(pHddCtx);
9495
9496 if (0 != status)
9497 {
9498 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9499 "%s: HDD context is not valid", __func__);
9500 return status;
9501 }
9502
9503 pVosContext = pHddCtx->pvosContext;
9504 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
9505
9506 if (NULL == pHostapdState)
9507 {
9508 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
9509 "%s: pHostapdState is Null", __func__);
9510 return -EINVAL;
9511 }
9512
9513 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"acl policy: = %d"
9514 "no acl entries = %d", params->acl_policy, params->n_acl_entries);
9515
9516 if (WLAN_HDD_SOFTAP == pAdapter->device_mode)
9517 {
9518 pConfig = &pAdapter->sessionCtx.ap.sapConfig;
9519
9520 /* default value */
9521 pConfig->num_accept_mac = 0;
9522 pConfig->num_deny_mac = 0;
9523
9524 /**
9525 * access control policy
9526 * @NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED: Deny stations which are
9527 * listed in hostapd.deny file.
9528 * @NL80211_ACL_POLICY_DENY_UNLESS_LISTED: Allow stations which are
9529 * listed in hostapd.accept file.
9530 */
9531 if (NL80211_ACL_POLICY_DENY_UNLESS_LISTED == params->acl_policy)
9532 {
9533 pConfig->SapMacaddr_acl = eSAP_DENY_UNLESS_ACCEPTED;
9534 }
9535 else if (NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED == params->acl_policy)
9536 {
9537 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
9538 }
9539 else
9540 {
9541 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9542 "%s:Acl Policy : %d is not supported",
9543 __func__, params->acl_policy);
9544 return -ENOTSUPP;
9545 }
9546
9547 if (eSAP_DENY_UNLESS_ACCEPTED == pConfig->SapMacaddr_acl)
9548 {
9549 pConfig->num_accept_mac = params->n_acl_entries;
9550 for (i = 0; i < params->n_acl_entries; i++)
9551 {
9552 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9553 "** Add ACL MAC entry %i in WhiletList :"
9554 MAC_ADDRESS_STR, i,
9555 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
9556
9557 vos_mem_copy(&pConfig->accept_mac[i], params->mac_addrs[i].addr,
9558 sizeof(qcmacaddr));
9559 }
9560 }
9561 else if (eSAP_ACCEPT_UNLESS_DENIED == pConfig->SapMacaddr_acl)
9562 {
9563 pConfig->num_deny_mac = params->n_acl_entries;
9564 for (i = 0; i < params->n_acl_entries; i++)
9565 {
9566 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9567 "** Add ACL MAC entry %i in BlackList :"
9568 MAC_ADDRESS_STR, i,
9569 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
9570
9571 vos_mem_copy(&pConfig->deny_mac[i], params->mac_addrs[i].addr,
9572 sizeof(qcmacaddr));
9573 }
9574 }
9575
9576 if (VOS_STATUS_SUCCESS != WLANSAP_SetMacACL(pVosContext, pConfig))
9577 {
9578 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9579 "%s: SAP Set Mac Acl fail", __func__);
9580 return -EINVAL;
9581 }
9582 }
9583 else
9584 {
9585 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9586 "%s: Invalid device_mode = %d",
9587 __func__, pAdapter->device_mode);
9588 return -EINVAL;
9589 }
9590
9591 return 0;
9592}
9593
Leo Chang9056f462013-08-01 19:21:11 -07009594#ifdef WLAN_NL80211_TESTMODE
9595#ifdef FEATURE_WLAN_LPHB
Leo Changd9df8aa2013-09-26 13:32:26 -07009596void wlan_hdd_cfg80211_lphb_ind_handler
Leo Chang9056f462013-08-01 19:21:11 -07009597(
9598 void *pAdapter,
9599 void *indCont
9600)
9601{
Leo Changd9df8aa2013-09-26 13:32:26 -07009602 tSirLPHBInd *lphbInd;
9603 struct sk_buff *skb;
c_hpothu73f35e62014-04-18 13:40:08 +05309604 hdd_context_t *pHddCtxt;
Leo Chang9056f462013-08-01 19:21:11 -07009605
9606 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -07009607 "LPHB indication arrived");
Leo Chang9056f462013-08-01 19:21:11 -07009608
c_hpothu73f35e62014-04-18 13:40:08 +05309609 if (pAdapter == NULL)
9610 {
9611 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9612 "%s: pAdapter is NULL\n",__func__);
9613 return;
9614 }
9615
Leo Chang9056f462013-08-01 19:21:11 -07009616 if (NULL == indCont)
9617 {
9618 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -07009619 "LPHB IND, invalid argument");
Leo Chang9056f462013-08-01 19:21:11 -07009620 return;
9621 }
9622
c_hpothu73f35e62014-04-18 13:40:08 +05309623 pHddCtxt = (hdd_context_t *)pAdapter;
Leo Changd9df8aa2013-09-26 13:32:26 -07009624 lphbInd = (tSirLPHBInd *)indCont;
Leo Chang9056f462013-08-01 19:21:11 -07009625 skb = cfg80211_testmode_alloc_event_skb(
c_hpothu73f35e62014-04-18 13:40:08 +05309626 pHddCtxt->wiphy,
Leo Changd9df8aa2013-09-26 13:32:26 -07009627 sizeof(tSirLPHBInd),
Leo Chang9056f462013-08-01 19:21:11 -07009628 GFP_ATOMIC);
9629 if (!skb)
9630 {
9631 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9632 "LPHB timeout, NL buffer alloc fail");
9633 return;
9634 }
9635
Leo Changac3ba772013-10-07 09:47:04 -07009636 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_CMD, WLAN_HDD_TM_CMD_WLAN_HB))
Leo Changd9df8aa2013-09-26 13:32:26 -07009637 {
9638 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9639 "WLAN_HDD_TM_ATTR_CMD put fail");
9640 goto nla_put_failure;
9641 }
Leo Changac3ba772013-10-07 09:47:04 -07009642 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_TYPE, lphbInd->protocolType))
Leo Changd9df8aa2013-09-26 13:32:26 -07009643 {
9644 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9645 "WLAN_HDD_TM_ATTR_TYPE put fail");
9646 goto nla_put_failure;
9647 }
Leo Changac3ba772013-10-07 09:47:04 -07009648 if(nla_put(skb, WLAN_HDD_TM_ATTR_DATA,
Leo Changd9df8aa2013-09-26 13:32:26 -07009649 sizeof(tSirLPHBInd), lphbInd))
9650 {
9651 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9652 "WLAN_HDD_TM_ATTR_DATA put fail");
9653 goto nla_put_failure;
9654 }
Leo Chang9056f462013-08-01 19:21:11 -07009655 cfg80211_testmode_event(skb, GFP_ATOMIC);
9656 return;
9657
9658nla_put_failure:
9659 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9660 "NLA Put fail");
9661 kfree_skb(skb);
9662
9663 return;
9664}
9665#endif /* FEATURE_WLAN_LPHB */
9666
9667static int wlan_hdd_cfg80211_testmode(struct wiphy *wiphy, void *data, int len)
9668{
9669 struct nlattr *tb[WLAN_HDD_TM_ATTR_MAX + 1];
9670 int err = 0;
9671#ifdef FEATURE_WLAN_LPHB
9672 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Leo Changd9df8aa2013-09-26 13:32:26 -07009673 eHalStatus smeStatus;
Leo Chang9056f462013-08-01 19:21:11 -07009674#endif /* FEATURE_WLAN_LPHB */
9675
9676 err = nla_parse(tb, WLAN_HDD_TM_ATTR_MAX, data, len, wlan_hdd_tm_policy);
9677 if (err)
9678 {
9679 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9680 "%s Testmode INV ATTR", __func__);
9681 return err;
9682 }
9683
9684 if (!tb[WLAN_HDD_TM_ATTR_CMD])
9685 {
9686 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9687 "%s Testmode INV CMD", __func__);
9688 return -EINVAL;
9689 }
9690
9691 switch (nla_get_u32(tb[WLAN_HDD_TM_ATTR_CMD]))
9692 {
9693#ifdef FEATURE_WLAN_LPHB
9694 /* Low Power Heartbeat configuration request */
9695 case WLAN_HDD_TM_CMD_WLAN_HB:
9696 {
9697 int buf_len;
9698 void *buf;
9699 tSirLPHBReq *hb_params = NULL;
Amar Singhal05852702014-02-04 14:40:00 -08009700 tSirLPHBReq *hb_params_temp = NULL;
Leo Chang9056f462013-08-01 19:21:11 -07009701
9702 if (!tb[WLAN_HDD_TM_ATTR_DATA])
9703 {
9704 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9705 "%s Testmode INV DATA", __func__);
9706 return -EINVAL;
9707 }
9708
9709 buf = nla_data(tb[WLAN_HDD_TM_ATTR_DATA]);
9710 buf_len = nla_len(tb[WLAN_HDD_TM_ATTR_DATA]);
Amar Singhal05852702014-02-04 14:40:00 -08009711
9712 hb_params_temp =(tSirLPHBReq *)buf;
9713 if ((hb_params_temp->cmd == LPHB_SET_TCP_PARAMS_INDID) &&
9714 (hb_params_temp->params.lphbTcpParamReq.timePeriodSec == 0))
9715 return -EINVAL;
9716
Leo Chang9056f462013-08-01 19:21:11 -07009717 hb_params = (tSirLPHBReq *)vos_mem_malloc(sizeof(tSirLPHBReq));
9718 if (NULL == hb_params)
9719 {
9720 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9721 "%s Request Buffer Alloc Fail", __func__);
9722 return -EINVAL;
9723 }
9724
9725 vos_mem_copy(hb_params, buf, buf_len);
Leo Changd9df8aa2013-09-26 13:32:26 -07009726 smeStatus = sme_LPHBConfigReq((tHalHandle)(pHddCtx->hHal),
9727 hb_params,
9728 wlan_hdd_cfg80211_lphb_ind_handler);
9729 if (eHAL_STATUS_SUCCESS != smeStatus)
Leo Chang9056f462013-08-01 19:21:11 -07009730 {
Leo Changd9df8aa2013-09-26 13:32:26 -07009731 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9732 "LPHB Config Fail, disable");
Leo Chang9056f462013-08-01 19:21:11 -07009733 vos_mem_free(hb_params);
9734 }
Leo Chang9056f462013-08-01 19:21:11 -07009735 return 0;
9736 }
9737#endif /* FEATURE_WLAN_LPHB */
9738 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309739 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9740 "%s: unsupported event",__func__);
Leo Chang9056f462013-08-01 19:21:11 -07009741 return -EOPNOTSUPP;
9742 }
9743
9744 return err;
9745}
9746#endif /* CONFIG_NL80211_TESTMODE */
9747
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +05309748static int wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
9749 struct net_device *dev,
9750 int idx, struct survey_info *survey)
9751{
9752 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
9753 hdd_context_t *pHddCtx;
Mihir Sheted9072e02013-08-21 17:02:29 +05309754 hdd_station_ctx_t *pHddStaCtx;
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +05309755 tHalHandle halHandle;
Mihir Sheted9072e02013-08-21 17:02:29 +05309756 v_U32_t channel = 0, freq = 0; /* Initialization Required */
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +05309757 v_S7_t snr,rssi;
9758 int status, i, j, filled = 0;
9759
9760 ENTER();
9761
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +05309762 if (NULL == pAdapter)
9763 {
9764 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
9765 "%s: HDD adapter is Null", __func__);
9766 return -ENODEV;
9767 }
9768
9769 if (NULL == wiphy)
9770 {
9771 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
9772 "%s: wiphy is Null", __func__);
9773 return -ENODEV;
9774 }
9775
9776 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9777 status = wlan_hdd_validate_context(pHddCtx);
9778
9779 if (0 != status)
9780 {
9781 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9782 "%s: HDD context is not valid", __func__);
9783 return status;
9784 }
9785
Mihir Sheted9072e02013-08-21 17:02:29 +05309786 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9787
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +05309788 if (0 == pHddCtx->cfg_ini->fEnableSNRMonitoring ||
Mihir Sheted9072e02013-08-21 17:02:29 +05309789 0 != pAdapter->survey_idx ||
9790 eConnectionState_Associated != pHddStaCtx->conn_info.connState)
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +05309791 {
9792 /* The survey dump ops when implemented completely is expected to
9793 * return a survey of all channels and the ops is called by the
9794 * kernel with incremental values of the argument 'idx' till it
9795 * returns -ENONET. But we can only support the survey for the
9796 * operating channel for now. survey_idx is used to track
9797 * that the ops is called only once and then return -ENONET for
9798 * the next iteration
9799 */
9800 pAdapter->survey_idx = 0;
9801 return -ENONET;
9802 }
9803
9804 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
9805
9806 wlan_hdd_get_snr(pAdapter, &snr);
9807 wlan_hdd_get_rssi(pAdapter, &rssi);
9808
9809 sme_GetOperationChannel(halHandle, &channel, pAdapter->sessionId);
9810 hdd_wlan_get_freq(channel, &freq);
9811
9812
9813 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
9814 {
9815 if (NULL == wiphy->bands[i])
9816 {
9817 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
9818 "%s: wiphy->bands[i] is NULL, i = %d", __func__, i);
9819 continue;
9820 }
9821
9822 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
9823 {
9824 struct ieee80211_supported_band *band = wiphy->bands[i];
9825
9826 if (band->channels[j].center_freq == (v_U16_t)freq)
9827 {
9828 survey->channel = &band->channels[j];
9829 /* The Rx BDs contain SNR values in dB for the received frames
9830 * while the supplicant expects noise. So we calculate and
9831 * return the value of noise (dBm)
9832 * SNR (dB) = RSSI (dBm) - NOISE (dBm)
9833 */
9834 survey->noise = rssi - snr;
9835 survey->filled = SURVEY_INFO_NOISE_DBM;
9836 filled = 1;
9837 }
9838 }
9839 }
9840
9841 if (filled)
9842 pAdapter->survey_idx = 1;
9843 else
9844 {
9845 pAdapter->survey_idx = 0;
9846 return -ENONET;
9847 }
9848
9849 return 0;
9850}
9851
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05309852/*
9853 * FUNCTION: wlan_hdd_cfg80211_resume_wlan
9854 * this is called when cfg80211 driver resume
9855 * driver updates latest sched_scan scan result(if any) to cfg80211 database
9856 */
9857int wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
9858{
9859 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
9860 hdd_adapter_t *pAdapter;
9861 hdd_adapter_list_node_t *pAdapterNode, *pNext;
9862 VOS_STATUS status = VOS_STATUS_SUCCESS;
9863
9864 ENTER();
9865
9866 if ( NULL == pHddCtx )
9867 {
9868 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
9869 "%s: HddCtx validation failed", __func__);
9870 return 0;
9871 }
9872
9873 if (pHddCtx->isLogpInProgress)
9874 {
9875 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9876 "%s: LOGP in Progress. Ignore!!!", __func__);
9877 return 0;
9878 }
9879
Mihir Shete18156292014-03-11 15:38:30 +05309880 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05309881 {
9882 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9883 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
9884 return 0;
9885 }
9886
9887 spin_lock(&pHddCtx->schedScan_lock);
9888 pHddCtx->isWiphySuspended = FALSE;
9889 if (TRUE != pHddCtx->isSchedScanUpdatePending)
9890 {
9891 spin_unlock(&pHddCtx->schedScan_lock);
9892 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9893 "%s: Return resume is not due to PNO indication", __func__);
9894 return 0;
9895 }
9896 // Reset flag to avoid updatating cfg80211 data old results again
9897 pHddCtx->isSchedScanUpdatePending = FALSE;
9898 spin_unlock(&pHddCtx->schedScan_lock);
9899
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +05309900
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05309901 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
9902
9903 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
9904 {
9905 pAdapter = pAdapterNode->pAdapter;
9906 if ( (NULL != pAdapter) &&
9907 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) )
9908 {
9909 if (0 != wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter))
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +05309910 {
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05309911 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
9912 "%s: NO SCAN result", __func__);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +05309913 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05309914 else
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +05309915 {
9916 /* Acquire wakelock to handle the case where APP's tries to
9917 * suspend immediately after updating the scan results. Whis
9918 * results in app's is in suspended state and not able to
9919 * process the connect request to AP
9920 */
9921 hdd_prevent_suspend_timeout(2000);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05309922 cfg80211_sched_scan_results(pHddCtx->wiphy);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +05309923 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05309924
9925 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9926 "%s : cfg80211 scan result database updated", __func__);
9927
9928 return 0;
9929
9930 }
9931 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
9932 pAdapterNode = pNext;
9933 }
9934
9935 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9936 "%s: Failed to find Adapter", __func__);
9937 return 0;
9938}
9939
9940/*
9941 * FUNCTION: wlan_hdd_cfg80211_suspend_wlan
9942 * this is called when cfg80211 driver suspends
9943 */
9944int wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
9945 struct cfg80211_wowlan *wow)
9946{
9947 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
9948
9949 ENTER();
9950 if (NULL == pHddCtx)
9951 {
9952 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
9953 "%s: HddCtx validation failed", __func__);
9954 return 0;
9955 }
9956
9957 pHddCtx->isWiphySuspended = TRUE;
9958
9959 EXIT();
9960
9961 return 0;
9962}
9963
Jeff Johnson295189b2012-06-20 16:38:30 -07009964/* cfg80211_ops */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309965static struct cfg80211_ops wlan_hdd_cfg80211_ops =
Jeff Johnson295189b2012-06-20 16:38:30 -07009966{
9967 .add_virtual_intf = wlan_hdd_add_virtual_intf,
9968 .del_virtual_intf = wlan_hdd_del_virtual_intf,
9969 .change_virtual_intf = wlan_hdd_cfg80211_change_iface,
9970 .change_station = wlan_hdd_change_station,
9971#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
9972 .add_beacon = wlan_hdd_cfg80211_add_beacon,
9973 .del_beacon = wlan_hdd_cfg80211_del_beacon,
9974 .set_beacon = wlan_hdd_cfg80211_set_beacon,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009975#else
9976 .start_ap = wlan_hdd_cfg80211_start_ap,
9977 .change_beacon = wlan_hdd_cfg80211_change_beacon,
9978 .stop_ap = wlan_hdd_cfg80211_stop_ap,
Jeff Johnson295189b2012-06-20 16:38:30 -07009979#endif
9980 .change_bss = wlan_hdd_cfg80211_change_bss,
9981 .add_key = wlan_hdd_cfg80211_add_key,
9982 .get_key = wlan_hdd_cfg80211_get_key,
9983 .del_key = wlan_hdd_cfg80211_del_key,
9984 .set_default_key = wlan_hdd_cfg80211_set_default_key,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -08009985#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07009986 .set_channel = wlan_hdd_cfg80211_set_channel,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -08009987#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009988 .scan = wlan_hdd_cfg80211_scan,
9989 .connect = wlan_hdd_cfg80211_connect,
9990 .disconnect = wlan_hdd_cfg80211_disconnect,
9991 .join_ibss = wlan_hdd_cfg80211_join_ibss,
9992 .leave_ibss = wlan_hdd_cfg80211_leave_ibss,
9993 .set_wiphy_params = wlan_hdd_cfg80211_set_wiphy_params,
9994 .set_tx_power = wlan_hdd_cfg80211_set_txpower,
9995 .get_tx_power = wlan_hdd_cfg80211_get_txpower,
Jeff Johnson295189b2012-06-20 16:38:30 -07009996 .remain_on_channel = wlan_hdd_cfg80211_remain_on_channel,
9997 .cancel_remain_on_channel = wlan_hdd_cfg80211_cancel_remain_on_channel,
DARAM SUDHA39eede62014-02-12 11:16:40 +05309998 .mgmt_tx = wlan_hdd_mgmt_tx,
Jeff Johnson295189b2012-06-20 16:38:30 -07009999#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
10000 .mgmt_tx_cancel_wait = wlan_hdd_cfg80211_mgmt_tx_cancel_wait,
10001 .set_default_mgmt_key = wlan_hdd_set_default_mgmt_key,
10002 .set_txq_params = wlan_hdd_set_txq_params,
10003#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010004 .get_station = wlan_hdd_cfg80211_get_station,
10005 .set_power_mgmt = wlan_hdd_cfg80211_set_power_mgmt,
10006 .del_station = wlan_hdd_cfg80211_del_station,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010007 .add_station = wlan_hdd_cfg80211_add_station,
10008#ifdef FEATURE_WLAN_LFR
10009 .set_pmksa = wlan_hdd_cfg80211_set_pmksa,
10010 .del_pmksa = wlan_hdd_cfg80211_del_pmksa,
10011 .flush_pmksa = wlan_hdd_cfg80211_flush_pmksa,
10012#endif
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070010013#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
10014 .update_ft_ies = wlan_hdd_cfg80211_update_ft_ies,
10015#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080010016#ifdef FEATURE_WLAN_TDLS
10017 .tdls_mgmt = wlan_hdd_cfg80211_tdls_mgmt,
10018 .tdls_oper = wlan_hdd_cfg80211_tdls_oper,
10019#endif
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053010020#ifdef WLAN_FEATURE_GTK_OFFLOAD
10021 .set_rekey_data = wlan_hdd_cfg80211_set_rekey_data,
10022#endif /* WLAN_FEATURE_GTK_OFFLOAD */
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053010023#ifdef FEATURE_WLAN_SCAN_PNO
10024 .sched_scan_start = wlan_hdd_cfg80211_sched_scan_start,
10025 .sched_scan_stop = wlan_hdd_cfg80211_sched_scan_stop,
10026#endif /*FEATURE_WLAN_SCAN_PNO */
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053010027 .resume = wlan_hdd_cfg80211_resume_wlan,
10028 .suspend = wlan_hdd_cfg80211_suspend_wlan,
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053010029 .set_mac_acl = wlan_hdd_cfg80211_set_mac_acl,
Leo Chang9056f462013-08-01 19:21:11 -070010030#ifdef WLAN_NL80211_TESTMODE
10031 .testmode_cmd = wlan_hdd_cfg80211_testmode,
10032#endif
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053010033 .dump_survey = wlan_hdd_cfg80211_dump_survey,
Jeff Johnson295189b2012-06-20 16:38:30 -070010034};
10035