blob: 05dd615fc61b5335a4eb88493b3e23abeb96f0d4 [file] [log] [blame]
Jeff Johnson295189b2012-06-20 16:38:30 -07001/*
Kiet Lam842dad02014-02-18 18:44:02 -08002 * Copyright (c) 2012-2014 The Linux Foundation. All rights reserved.
3 *
4 * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
5 *
6 *
7 * Permission to use, copy, modify, and/or distribute this software for
8 * any purpose with or without fee is hereby granted, provided that the
9 * above copyright notice and this permission notice appear in all
10 * copies.
11 *
12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
13 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
14 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
15 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
16 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
17 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
18 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
19 * PERFORMANCE OF THIS SOFTWARE.
20 */
21
22/*
Kiet Lamaa8e15a2014-02-11 23:30:06 -080023 * Copyright (c) 2012-2014 Qualcomm Atheros, Inc.
24 * All Rights Reserved.
25 * Qualcomm Atheros Confidential and Proprietary.
Kiet Lam842dad02014-02-18 18:44:02 -080026 *
Kiet Lamaa8e15a2014-02-11 23:30:06 -080027 */
Kiet Lam842dad02014-02-18 18:44:02 -080028
29
Jeff Johnson295189b2012-06-20 16:38:30 -070030/**========================================================================
31
32 \file wlan_hdd_cfg80211.c
33
34 \brief WLAN Host Device Driver implementation
35
Jeff Johnson295189b2012-06-20 16:38:30 -070036 ========================================================================*/
37
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070038/**=========================================================================
Jeff Johnson295189b2012-06-20 16:38:30 -070039
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070040 EDIT HISTORY FOR FILE
Jeff Johnson295189b2012-06-20 16:38:30 -070041
42
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070043 This section contains comments describing changes made to the module.
44 Notice that changes are listed in reverse chronological order.
Jeff Johnson295189b2012-06-20 16:38:30 -070045
46
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070047 $Header:$ $DateTime: $ $Author: $
Jeff Johnson295189b2012-06-20 16:38:30 -070048
49
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070050 when who what, where, why
Jeff Johnson295189b2012-06-20 16:38:30 -070051 -------- --- --------------------------------------------------------
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070052 21/12/09 Ashwani Created module.
Jeff Johnson295189b2012-06-20 16:38:30 -070053
54 07/06/10 Kumar Deepak Implemented cfg80211 callbacks for ANDROID
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070055 Ganesh K
Jeff Johnson295189b2012-06-20 16:38:30 -070056 ==========================================================================*/
57
Jeff Johnson295189b2012-06-20 16:38:30 -070058
59#include <linux/version.h>
60#include <linux/module.h>
61#include <linux/kernel.h>
62#include <linux/init.h>
63#include <linux/wireless.h>
64#include <wlan_hdd_includes.h>
65#include <net/arp.h>
66#include <net/cfg80211.h>
67#include <linux/wireless.h>
68#include <wlan_hdd_wowl.h>
69#include <aniGlobal.h>
70#include "ccmApi.h"
71#include "sirParams.h"
72#include "dot11f.h"
73#include "wlan_hdd_assoc.h"
74#include "wlan_hdd_wext.h"
75#include "sme_Api.h"
76#include "wlan_hdd_p2p.h"
77#include "wlan_hdd_cfg80211.h"
78#include "wlan_hdd_hostapd.h"
79#include "sapInternal.h"
80#include "wlan_hdd_softap_tx_rx.h"
81#include "wlan_hdd_main.h"
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053082#include "wlan_hdd_assoc.h"
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053083#include "wlan_hdd_power.h"
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053084#include "wlan_hdd_trace.h"
85#include "vos_types.h"
86#include "vos_trace.h"
Jeff Johnson295189b2012-06-20 16:38:30 -070087#ifdef WLAN_BTAMP_FEATURE
88#include "bap_hdd_misc.h"
89#endif
90#include <qc_sap_ioctl.h>
Mohit Khanna698ba2a2012-12-04 15:08:18 -080091#ifdef FEATURE_WLAN_TDLS
92#include "wlan_hdd_tdls.h"
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053093#include "wlan_hdd_wmm.h"
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053094#include "wlan_qct_wda.h"
Mohit Khanna698ba2a2012-12-04 15:08:18 -080095#endif
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +053096#include "wlan_nv.h"
Leo Chang6fe1f922013-06-07 19:21:24 -070097#include "wlan_hdd_dev_pwr.h"
Jeff Johnson295189b2012-06-20 16:38:30 -070098
99#define g_mode_rates_size (12)
100#define a_mode_rates_size (8)
101#define FREQ_BASE_80211G (2407)
102#define FREQ_BAND_DIFF_80211G (5)
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700103#define MAX_SCAN_SSID 9
Kiet Lamac06e2c2013-10-23 16:25:07 +0530104#define MAX_PENDING_LOG 5
Jeff Johnson295189b2012-06-20 16:38:30 -0700105#define GET_IE_LEN_IN_BSS_DESC(lenInBss) ( lenInBss + sizeof(lenInBss) - \
krunal soni2a6a9062014-02-11 14:14:23 -0800106 ((uintptr_t)OFFSET_OF( tSirBssDescription, ieFields)))
Jeff Johnson295189b2012-06-20 16:38:30 -0700107
108#define HDD2GHZCHAN(freq, chan, flag) { \
109 .band = IEEE80211_BAND_2GHZ, \
110 .center_freq = (freq), \
111 .hw_value = (chan),\
112 .flags = (flag), \
113 .max_antenna_gain = 0 ,\
114 .max_power = 30, \
115}
116
117#define HDD5GHZCHAN(freq, chan, flag) { \
118 .band = IEEE80211_BAND_5GHZ, \
119 .center_freq = (freq), \
120 .hw_value = (chan),\
121 .flags = (flag), \
122 .max_antenna_gain = 0 ,\
123 .max_power = 30, \
124}
125
126#define HDD_G_MODE_RATETAB(rate, rate_id, flag)\
127{\
128 .bitrate = rate, \
129 .hw_value = rate_id, \
130 .flags = flag, \
131}
132
Lee Hoonkic1262f22013-01-24 21:59:00 -0800133#ifndef WLAN_FEATURE_TDLS_DEBUG
134#define TDLS_LOG_LEVEL VOS_TRACE_LEVEL_INFO
135#else
136#define TDLS_LOG_LEVEL VOS_TRACE_LEVEL_ERROR
137#endif
138
Gopichand Nakkala356fb102013-03-06 12:34:04 +0530139#ifdef WLAN_FEATURE_VOWIFI_11R
140#define WLAN_AKM_SUITE_FT_8021X 0x000FAC03
141#define WLAN_AKM_SUITE_FT_PSK 0x000FAC04
142#endif
143
Naresh Jayaram3180aa42014-02-12 21:47:26 +0530144#define HDD_CHANNEL_14 14
145
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530146static const u32 hdd_cipher_suites[] =
Jeff Johnson295189b2012-06-20 16:38:30 -0700147{
148 WLAN_CIPHER_SUITE_WEP40,
149 WLAN_CIPHER_SUITE_WEP104,
150 WLAN_CIPHER_SUITE_TKIP,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800151#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -0700152#define WLAN_CIPHER_SUITE_KRK 0x004096ff /* use for KRK */
153 WLAN_CIPHER_SUITE_KRK,
154 WLAN_CIPHER_SUITE_CCMP,
155#else
156 WLAN_CIPHER_SUITE_CCMP,
157#endif
158#ifdef FEATURE_WLAN_WAPI
159 WLAN_CIPHER_SUITE_SMS4,
160#endif
Chet Lanctot186b5732013-03-18 10:26:30 -0700161#ifdef WLAN_FEATURE_11W
162 WLAN_CIPHER_SUITE_AES_CMAC,
163#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700164};
165
166static inline int is_broadcast_ether_addr(const u8 *addr)
167{
168 return ((addr[0] == 0xff) && (addr[1] == 0xff) && (addr[2] == 0xff) &&
169 (addr[3] == 0xff) && (addr[4] == 0xff) && (addr[5] == 0xff));
170}
171
172static struct ieee80211_channel hdd_channels_2_4_GHZ[] =
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530173{
Jeff Johnson295189b2012-06-20 16:38:30 -0700174 HDD2GHZCHAN(2412, 1, 0) ,
175 HDD2GHZCHAN(2417, 2, 0) ,
176 HDD2GHZCHAN(2422, 3, 0) ,
177 HDD2GHZCHAN(2427, 4, 0) ,
178 HDD2GHZCHAN(2432, 5, 0) ,
179 HDD2GHZCHAN(2437, 6, 0) ,
180 HDD2GHZCHAN(2442, 7, 0) ,
181 HDD2GHZCHAN(2447, 8, 0) ,
182 HDD2GHZCHAN(2452, 9, 0) ,
183 HDD2GHZCHAN(2457, 10, 0) ,
184 HDD2GHZCHAN(2462, 11, 0) ,
185 HDD2GHZCHAN(2467, 12, 0) ,
186 HDD2GHZCHAN(2472, 13, 0) ,
187 HDD2GHZCHAN(2484, 14, 0) ,
188};
189
Jeff Johnson295189b2012-06-20 16:38:30 -0700190static struct ieee80211_channel hdd_social_channels_2_4_GHZ[] =
191{
192 HDD2GHZCHAN(2412, 1, 0) ,
193 HDD2GHZCHAN(2437, 6, 0) ,
194 HDD2GHZCHAN(2462, 11, 0) ,
195};
Jeff Johnson295189b2012-06-20 16:38:30 -0700196
197static struct ieee80211_channel hdd_channels_5_GHZ[] =
198{
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -0700199 HDD5GHZCHAN(4920, 240, 0) ,
200 HDD5GHZCHAN(4940, 244, 0) ,
201 HDD5GHZCHAN(4960, 248, 0) ,
202 HDD5GHZCHAN(4980, 252, 0) ,
203 HDD5GHZCHAN(5040, 208, 0) ,
204 HDD5GHZCHAN(5060, 212, 0) ,
205 HDD5GHZCHAN(5080, 216, 0) ,
Jeff Johnson295189b2012-06-20 16:38:30 -0700206 HDD5GHZCHAN(5180, 36, 0) ,
207 HDD5GHZCHAN(5200, 40, 0) ,
208 HDD5GHZCHAN(5220, 44, 0) ,
209 HDD5GHZCHAN(5240, 48, 0) ,
210 HDD5GHZCHAN(5260, 52, 0) ,
211 HDD5GHZCHAN(5280, 56, 0) ,
212 HDD5GHZCHAN(5300, 60, 0) ,
213 HDD5GHZCHAN(5320, 64, 0) ,
214 HDD5GHZCHAN(5500,100, 0) ,
215 HDD5GHZCHAN(5520,104, 0) ,
216 HDD5GHZCHAN(5540,108, 0) ,
217 HDD5GHZCHAN(5560,112, 0) ,
218 HDD5GHZCHAN(5580,116, 0) ,
219 HDD5GHZCHAN(5600,120, 0) ,
220 HDD5GHZCHAN(5620,124, 0) ,
221 HDD5GHZCHAN(5640,128, 0) ,
222 HDD5GHZCHAN(5660,132, 0) ,
223 HDD5GHZCHAN(5680,136, 0) ,
224 HDD5GHZCHAN(5700,140, 0) ,
Leo Chang80de3c22013-11-26 10:52:12 -0800225#ifdef FEATURE_WLAN_CH144
226 HDD5GHZCHAN(5720,144, 0) ,
227#endif /* FEATURE_WLAN_CH144 */
Jeff Johnson295189b2012-06-20 16:38:30 -0700228 HDD5GHZCHAN(5745,149, 0) ,
229 HDD5GHZCHAN(5765,153, 0) ,
230 HDD5GHZCHAN(5785,157, 0) ,
231 HDD5GHZCHAN(5805,161, 0) ,
232 HDD5GHZCHAN(5825,165, 0) ,
233};
234
235static struct ieee80211_rate g_mode_rates[] =
236{
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530237 HDD_G_MODE_RATETAB(10, 0x1, 0),
238 HDD_G_MODE_RATETAB(20, 0x2, 0),
239 HDD_G_MODE_RATETAB(55, 0x4, 0),
240 HDD_G_MODE_RATETAB(110, 0x8, 0),
241 HDD_G_MODE_RATETAB(60, 0x10, 0),
242 HDD_G_MODE_RATETAB(90, 0x20, 0),
243 HDD_G_MODE_RATETAB(120, 0x40, 0),
244 HDD_G_MODE_RATETAB(180, 0x80, 0),
245 HDD_G_MODE_RATETAB(240, 0x100, 0),
246 HDD_G_MODE_RATETAB(360, 0x200, 0),
247 HDD_G_MODE_RATETAB(480, 0x400, 0),
Jeff Johnson295189b2012-06-20 16:38:30 -0700248 HDD_G_MODE_RATETAB(540, 0x800, 0),
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530249};
Jeff Johnson295189b2012-06-20 16:38:30 -0700250
251static struct ieee80211_rate a_mode_rates[] =
252{
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530253 HDD_G_MODE_RATETAB(60, 0x10, 0),
254 HDD_G_MODE_RATETAB(90, 0x20, 0),
255 HDD_G_MODE_RATETAB(120, 0x40, 0),
256 HDD_G_MODE_RATETAB(180, 0x80, 0),
257 HDD_G_MODE_RATETAB(240, 0x100, 0),
258 HDD_G_MODE_RATETAB(360, 0x200, 0),
259 HDD_G_MODE_RATETAB(480, 0x400, 0),
Jeff Johnson295189b2012-06-20 16:38:30 -0700260 HDD_G_MODE_RATETAB(540, 0x800, 0),
261};
262
263static struct ieee80211_supported_band wlan_hdd_band_2_4_GHZ =
264{
265 .channels = hdd_channels_2_4_GHZ,
266 .n_channels = ARRAY_SIZE(hdd_channels_2_4_GHZ),
267 .band = IEEE80211_BAND_2GHZ,
268 .bitrates = g_mode_rates,
269 .n_bitrates = g_mode_rates_size,
270 .ht_cap.ht_supported = 1,
271 .ht_cap.cap = IEEE80211_HT_CAP_SGI_20
272 | IEEE80211_HT_CAP_GRN_FLD
273 | IEEE80211_HT_CAP_DSSSCCK40
274 | IEEE80211_HT_CAP_LSIG_TXOP_PROT,
275 .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
276 .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
277 .ht_cap.mcs.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
278 .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ),
279 .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
280};
281
Jeff Johnson295189b2012-06-20 16:38:30 -0700282static struct ieee80211_supported_band wlan_hdd_band_p2p_2_4_GHZ =
283{
284 .channels = hdd_social_channels_2_4_GHZ,
285 .n_channels = ARRAY_SIZE(hdd_social_channels_2_4_GHZ),
286 .band = IEEE80211_BAND_2GHZ,
287 .bitrates = g_mode_rates,
288 .n_bitrates = g_mode_rates_size,
289 .ht_cap.ht_supported = 1,
290 .ht_cap.cap = IEEE80211_HT_CAP_SGI_20
291 | IEEE80211_HT_CAP_GRN_FLD
292 | IEEE80211_HT_CAP_DSSSCCK40
293 | IEEE80211_HT_CAP_LSIG_TXOP_PROT,
294 .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
295 .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
296 .ht_cap.mcs.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
297 .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ),
298 .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
299};
Jeff Johnson295189b2012-06-20 16:38:30 -0700300
301static struct ieee80211_supported_band wlan_hdd_band_5_GHZ =
302{
303 .channels = hdd_channels_5_GHZ,
304 .n_channels = ARRAY_SIZE(hdd_channels_5_GHZ),
305 .band = IEEE80211_BAND_5GHZ,
306 .bitrates = a_mode_rates,
307 .n_bitrates = a_mode_rates_size,
308 .ht_cap.ht_supported = 1,
309 .ht_cap.cap = IEEE80211_HT_CAP_SGI_20
310 | IEEE80211_HT_CAP_GRN_FLD
311 | IEEE80211_HT_CAP_DSSSCCK40
312 | IEEE80211_HT_CAP_LSIG_TXOP_PROT
313 | IEEE80211_HT_CAP_SGI_40
314 | IEEE80211_HT_CAP_SUP_WIDTH_20_40,
315 .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
316 .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
317 .ht_cap.mcs.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
318 .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ),
319 .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
320};
321
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530322/* This structure contain information what kind of frame are expected in
Jeff Johnson295189b2012-06-20 16:38:30 -0700323 TX/RX direction for each kind of interface */
324static const struct ieee80211_txrx_stypes
325wlan_hdd_txrx_stypes[NUM_NL80211_IFTYPES] = {
326 [NL80211_IFTYPE_STATION] = {
327 .tx = 0xffff,
328 .rx = BIT(SIR_MAC_MGMT_ACTION) |
329 BIT(SIR_MAC_MGMT_PROBE_REQ),
330 },
331 [NL80211_IFTYPE_AP] = {
332 .tx = 0xffff,
333 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
334 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
335 BIT(SIR_MAC_MGMT_PROBE_REQ) |
336 BIT(SIR_MAC_MGMT_DISASSOC) |
337 BIT(SIR_MAC_MGMT_AUTH) |
338 BIT(SIR_MAC_MGMT_DEAUTH) |
339 BIT(SIR_MAC_MGMT_ACTION),
340 },
Jeff Johnsonbc006202013-04-29 14:05:30 -0700341 [NL80211_IFTYPE_ADHOC] = {
342 .tx = 0xffff,
343 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
344 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
345 BIT(SIR_MAC_MGMT_PROBE_REQ) |
346 BIT(SIR_MAC_MGMT_DISASSOC) |
347 BIT(SIR_MAC_MGMT_AUTH) |
348 BIT(SIR_MAC_MGMT_DEAUTH) |
349 BIT(SIR_MAC_MGMT_ACTION),
350 },
Jeff Johnson295189b2012-06-20 16:38:30 -0700351 [NL80211_IFTYPE_P2P_CLIENT] = {
352 .tx = 0xffff,
353 .rx = BIT(SIR_MAC_MGMT_ACTION) |
354 BIT(SIR_MAC_MGMT_PROBE_REQ),
355 },
356 [NL80211_IFTYPE_P2P_GO] = {
357 /* This is also same as for SoftAP */
358 .tx = 0xffff,
359 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
360 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
361 BIT(SIR_MAC_MGMT_PROBE_REQ) |
362 BIT(SIR_MAC_MGMT_DISASSOC) |
363 BIT(SIR_MAC_MGMT_AUTH) |
364 BIT(SIR_MAC_MGMT_DEAUTH) |
365 BIT(SIR_MAC_MGMT_ACTION),
366 },
Jeff Johnson295189b2012-06-20 16:38:30 -0700367};
368
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800369#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800370static const struct ieee80211_iface_limit
371wlan_hdd_iface_limit[] = {
372 {
Sunil Ravia72c3992013-01-31 06:12:22 -0800373 /* max = 3 ; Our driver create two interfaces during driver init
374 * wlan0 and p2p0 interfaces. p2p0 is considered as station
375 * interface until a group is formed. In JB architecture, once the
376 * group is formed, interface type of p2p0 is changed to P2P GO or
377 * Client.
378 * When supplicant remove the group, it first issue a set interface
379 * cmd to change the mode back to Station. In JB this works fine as
380 * we advertize two station type interface during driver init.
381 * Some vendors create separate interface for P2P GO/Client,
382 * after group formation(Third one). But while group remove
383 * supplicant first tries to change the mode(3rd interface) to STATION
384 * But as we advertized only two sta type interfaces nl80211 was
385 * returning error for the third one which was leading to failure in
386 * delete interface. Ideally while removing the group, supplicant
387 * should not try to change the 3rd interface mode to Station type.
388 * Till we get a fix in wpa_supplicant, we advertize max STA
389 * interface type to 3
390 */
391 .max = 3,
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800392 .types = BIT(NL80211_IFTYPE_STATION),
393 },
394 {
395 .max = 1,
Jeff Johnsonbc006202013-04-29 14:05:30 -0700396 .types = BIT(NL80211_IFTYPE_ADHOC) | BIT(NL80211_IFTYPE_AP),
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800397 },
398 {
399 .max = 1,
400 .types = BIT(NL80211_IFTYPE_P2P_GO) |
401 BIT(NL80211_IFTYPE_P2P_CLIENT),
402 },
403};
404
405/* By default, only single channel concurrency is allowed */
406static struct ieee80211_iface_combination
407wlan_hdd_iface_combination = {
408 .limits = wlan_hdd_iface_limit,
409 .num_different_channels = 1,
Sunil Ravia72c3992013-01-31 06:12:22 -0800410 /*
411 * max = WLAN_MAX_INTERFACES ; JellyBean architecture creates wlan0
412 * and p2p0 interfaces during driver init
413 * Some vendors create separate interface for P2P operations.
414 * wlan0: STA interface
415 * p2p0: P2P Device interface, action frames goes
416 * through this interface.
417 * p2p-xx: P2P interface, After GO negotiation this interface is
418 * created for p2p operations(GO/CLIENT interface).
419 */
420 .max_interfaces = WLAN_MAX_INTERFACES,
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800421 .n_limits = ARRAY_SIZE(wlan_hdd_iface_limit),
422 .beacon_int_infra_match = false,
423};
424#endif
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800425
Jeff Johnson295189b2012-06-20 16:38:30 -0700426static struct cfg80211_ops wlan_hdd_cfg80211_ops;
427
428/* Data rate 100KBPS based on IE Index */
429struct index_data_rate_type
430{
431 v_U8_t beacon_rate_index;
432 v_U16_t supported_rate[4];
433};
434
435/* 11B, 11G Rate table include Basic rate and Extended rate
436 The IDX field is the rate index
437 The HI field is the rate when RSSI is strong or being ignored
438 (in this case we report actual rate)
439 The MID field is the rate when RSSI is moderate
440 (in this case we cap 11b rates at 5.5 and 11g rates at 24)
441 The LO field is the rate when RSSI is low
442 (in this case we don't report rates, actual current rate used)
443 */
444static const struct
445{
446 v_U8_t beacon_rate_index;
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -0700447 v_U16_t supported_rate[4];
Jeff Johnson295189b2012-06-20 16:38:30 -0700448} supported_data_rate[] =
449{
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -0700450/* IDX HI HM LM LO (RSSI-based index */
451 {2, { 10, 10, 10, 0}},
452 {4, { 20, 20, 10, 0}},
453 {11, { 55, 20, 10, 0}},
454 {12, { 60, 55, 20, 0}},
455 {18, { 90, 55, 20, 0}},
456 {22, {110, 55, 20, 0}},
457 {24, {120, 90, 60, 0}},
458 {36, {180, 120, 60, 0}},
459 {44, {220, 180, 60, 0}},
460 {48, {240, 180, 90, 0}},
461 {66, {330, 180, 90, 0}},
462 {72, {360, 240, 90, 0}},
463 {96, {480, 240, 120, 0}},
464 {108, {540, 240, 120, 0}}
Jeff Johnson295189b2012-06-20 16:38:30 -0700465};
466
467/* MCS Based rate table */
468static struct index_data_rate_type supported_mcs_rate[] =
469{
470/* MCS L20 L40 S20 S40 */
471 {0, {65, 135, 72, 150}},
472 {1, {130, 270, 144, 300}},
473 {2, {195, 405, 217, 450}},
474 {3, {260, 540, 289, 600}},
475 {4, {390, 810, 433, 900}},
476 {5, {520, 1080, 578, 1200}},
477 {6, {585, 1215, 650, 1350}},
478 {7, {650, 1350, 722, 1500}}
479};
480
Leo Chang6f8870f2013-03-26 18:11:36 -0700481#ifdef WLAN_FEATURE_11AC
482
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530483#define DATA_RATE_11AC_MCS_MASK 0x03
Leo Chang6f8870f2013-03-26 18:11:36 -0700484
485struct index_vht_data_rate_type
486{
487 v_U8_t beacon_rate_index;
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530488 v_U16_t supported_VHT80_rate[2];
489 v_U16_t supported_VHT40_rate[2];
490 v_U16_t supported_VHT20_rate[2];
Leo Chang6f8870f2013-03-26 18:11:36 -0700491};
492
493typedef enum
494{
495 DATA_RATE_11AC_MAX_MCS_7,
496 DATA_RATE_11AC_MAX_MCS_8,
497 DATA_RATE_11AC_MAX_MCS_9,
498 DATA_RATE_11AC_MAX_MCS_NA
499} eDataRate11ACMaxMcs;
500
501/* MCS Based VHT rate table */
502static struct index_vht_data_rate_type supported_vht_mcs_rate[] =
503{
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530504/* MCS L80 S80 L40 S40 L20 S40*/
505 {0, {293, 325}, {135, 150}, {65, 72}},
506 {1, {585, 650}, {270, 300}, {130, 144}},
507 {2, {878, 975}, {405, 450}, {195, 217}},
508 {3, {1170, 1300}, {540, 600}, {260, 289}},
509 {4, {1755, 1950}, {810, 900}, {390, 433}},
510 {5, {2340, 2600}, {1080, 1200}, {520, 578}},
511 {6, {2633, 2925}, {1215, 1350}, {585, 650}},
512 {7, {2925, 3250}, {1350, 1500}, {650, 722}},
513 {8, {3510, 3900}, {1620, 1800}, {780, 867}},
514 {9, {3900, 4333}, {1800, 2000}, {780, 867}}
Leo Chang6f8870f2013-03-26 18:11:36 -0700515};
516#endif /* WLAN_FEATURE_11AC */
517
Jeff Johnson295189b2012-06-20 16:38:30 -0700518extern struct net_device_ops net_ops_struct;
519
Leo Chang9056f462013-08-01 19:21:11 -0700520#ifdef WLAN_NL80211_TESTMODE
521enum wlan_hdd_tm_attr
522{
523 WLAN_HDD_TM_ATTR_INVALID = 0,
524 WLAN_HDD_TM_ATTR_CMD = 1,
525 WLAN_HDD_TM_ATTR_DATA = 2,
526 WLAN_HDD_TM_ATTR_TYPE = 3,
527 /* keep last */
528 WLAN_HDD_TM_ATTR_AFTER_LAST,
529 WLAN_HDD_TM_ATTR_MAX = WLAN_HDD_TM_ATTR_AFTER_LAST - 1,
530};
531
532enum wlan_hdd_tm_cmd
533{
534 WLAN_HDD_TM_CMD_WLAN_HB = 1,
535};
536
537#define WLAN_HDD_TM_DATA_MAX_LEN 5000
538
539static const struct nla_policy wlan_hdd_tm_policy[WLAN_HDD_TM_ATTR_MAX + 1] =
540{
541 [WLAN_HDD_TM_ATTR_CMD] = { .type = NLA_U32 },
542 [WLAN_HDD_TM_ATTR_DATA] = { .type = NLA_BINARY,
543 .len = WLAN_HDD_TM_DATA_MAX_LEN },
544};
545#endif /* WLAN_NL80211_TESTMODE */
546
Rajesh Chauhan98a31f82014-01-06 20:15:25 -0800547#ifdef FEATURE_WLAN_CH_AVOID
548/*
549 * FUNCTION: wlan_hdd_send_avoid_freq_event
550 * This is called when wlan driver needs to send vendor specific
551 * avoid frequency range event to userspace
552 */
553int wlan_hdd_send_avoid_freq_event(hdd_context_t *pHddCtx,
554 tHddAvoidFreqList *pAvoidFreqList)
555{
556 struct sk_buff *vendor_event;
557
558 ENTER();
559
560 if (!pHddCtx)
561 {
562 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
563 "%s: HDD context is null", __func__);
564 return -1;
565 }
566
567 if (!pAvoidFreqList)
568 {
569 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
570 "%s: pAvoidFreqList is null", __func__);
571 return -1;
572 }
573
574 vendor_event = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
575 sizeof(tHddAvoidFreqList),
576 QCOM_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY_INDEX,
577 GFP_KERNEL);
578 if (!vendor_event)
579 {
580 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
581 "%s: cfg80211_vendor_event_alloc failed", __func__);
582 return -1;
583 }
584
585 memcpy(skb_put(vendor_event, sizeof(tHddAvoidFreqList)),
586 (void *)pAvoidFreqList, sizeof(tHddAvoidFreqList));
587
588 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
589
590 EXIT();
591 return 0;
592}
593#endif /* FEATURE_WLAN_CH_AVOID */
594
595/* vendor specific events */
596static const struct nl80211_vendor_cmd_info wlan_hdd_cfg80211_vendor_events[] =
597{
598#ifdef FEATURE_WLAN_CH_AVOID
599 {
600 .vendor_id = QCOM_NL80211_VENDOR_ID,
601 .subcmd = QCOM_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY
602 },
603#endif /* FEATURE_WLAN_CH_AVOID */
604};
605
Jeff Johnson295189b2012-06-20 16:38:30 -0700606/*
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +0530607 * FUNCTION: wlan_hdd_cfg80211_wiphy_alloc
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530608 * This function is called by hdd_wlan_startup()
609 * during initialization.
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +0530610 * This function is used to allocate wiphy structure.
Jeff Johnson295189b2012-06-20 16:38:30 -0700611 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +0530612struct wiphy *wlan_hdd_cfg80211_wiphy_alloc(int priv_size)
Jeff Johnson295189b2012-06-20 16:38:30 -0700613{
614 struct wiphy *wiphy;
615 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530616 /*
617 * Create wiphy device
Jeff Johnson295189b2012-06-20 16:38:30 -0700618 */
619 wiphy = wiphy_new(&wlan_hdd_cfg80211_ops, priv_size);
620
621 if (!wiphy)
622 {
623 /* Print error and jump into err label and free the memory */
624 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wiphy init failed", __func__);
625 return NULL;
626 }
627
628 return wiphy;
629}
630
631/*
632 * FUNCTION: wlan_hdd_cfg80211_update_band
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530633 * This function is called from the supplicant through a
Jeff Johnson295189b2012-06-20 16:38:30 -0700634 * private ioctl to change the band value
635 */
636int wlan_hdd_cfg80211_update_band(struct wiphy *wiphy, eCsrBand eBand)
637{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +0530638 int i, j;
639 eNVChannelEnabledType channelEnabledState;
640
Jeff Johnsone7245742012-09-05 17:12:55 -0700641 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +0530642
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +0530643 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
Jeff Johnson295189b2012-06-20 16:38:30 -0700644 {
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +0530645
646 if (NULL == wiphy->bands[i])
647 {
648 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[i] is NULL, i = %d",
649 __func__, i);
650 continue;
651 }
652
653 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
654 {
655 struct ieee80211_supported_band *band = wiphy->bands[i];
656
657 channelEnabledState = vos_nv_getChannelEnabledState(
658 band->channels[j].hw_value);
659
660 if (IEEE80211_BAND_2GHZ == i && eCSR_BAND_5G == eBand) // 5G only
661 {
662 // Enable Social channels for P2P
663 if (WLAN_HDD_IS_SOCIAL_CHANNEL(band->channels[j].center_freq) &&
664 NV_CHANNEL_ENABLE == channelEnabledState)
665 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
666 else
667 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
668 continue;
669 }
670 else if (IEEE80211_BAND_5GHZ == i && eCSR_BAND_24 == eBand) // 2G only
671 {
672 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
673 continue;
674 }
675
676 if (NV_CHANNEL_DISABLE == channelEnabledState ||
677 NV_CHANNEL_INVALID == channelEnabledState)
678 {
679 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
680 }
681 else if (NV_CHANNEL_DFS == channelEnabledState)
682 {
683 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
684 band->channels[j].flags |= IEEE80211_CHAN_RADAR;
685 }
686 else
687 {
688 band->channels[j].flags &= ~(IEEE80211_CHAN_DISABLED
689 |IEEE80211_CHAN_RADAR);
690 }
691 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700692 }
693 return 0;
694}
695/*
696 * FUNCTION: wlan_hdd_cfg80211_init
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530697 * This function is called by hdd_wlan_startup()
698 * during initialization.
Jeff Johnson295189b2012-06-20 16:38:30 -0700699 * This function is used to initialize and register wiphy structure.
700 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +0530701int wlan_hdd_cfg80211_init(struct device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -0700702 struct wiphy *wiphy,
703 hdd_config_t *pCfg
704 )
705{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +0530706 int i, j;
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +0530707 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
708
Jeff Johnsone7245742012-09-05 17:12:55 -0700709 ENTER();
710
Jeff Johnson295189b2012-06-20 16:38:30 -0700711 /* Now bind the underlying wlan device with wiphy */
712 set_wiphy_dev(wiphy, dev);
713
714 wiphy->mgmt_stypes = wlan_hdd_txrx_stypes;
Amar Singhalfddc28c2013-09-05 13:03:40 -0700715
Kiet Lam6c583332013-10-14 05:37:09 +0530716#ifndef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -0700717 /* the flag for the other case would be initialzed in
718 vos_init_wiphy_from_nv_bin */
Amar Singhal0a402232013-10-11 20:57:16 -0700719 wiphy->flags |= WIPHY_FLAG_STRICT_REGULATORY;
Kiet Lam6c583332013-10-14 05:37:09 +0530720#endif
Amar Singhala49cbc52013-10-08 18:37:44 -0700721
Amar Singhalfddc28c2013-09-05 13:03:40 -0700722 /* This will disable updating of NL channels from passive to
723 * active if a beacon is received on passive channel. */
724 wiphy->flags |= WIPHY_FLAG_DISABLE_BEACON_HINTS;
Amar Singhalf0073192013-09-20 12:34:56 -0700725
Amar Singhalfddc28c2013-09-05 13:03:40 -0700726
Amar Singhala49cbc52013-10-08 18:37:44 -0700727
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700728#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -0700729 wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME
730 | WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD
731 | WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL
Jeff Johnsone7245742012-09-05 17:12:55 -0700732 | WIPHY_FLAG_OFFCHAN_TX;
Kiet Lam6c583332013-10-14 05:37:09 +0530733 wiphy->country_ie_pref = NL80211_COUNTRY_IE_IGNORE_CORE;
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700734#endif
Amar Singhala49cbc52013-10-08 18:37:44 -0700735
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800736#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowda640728a2013-03-28 12:21:54 -0700737 if (pCfg->isFastTransitionEnabled
James Zmuda77fb5ae2013-01-29 08:00:17 -0800738#ifdef FEATURE_WLAN_LFR
Srinivas Girigowda640728a2013-03-28 12:21:54 -0700739 || pCfg->isFastRoamIniFeatureEnabled
740#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800741#ifdef FEATURE_WLAN_ESE
742 || pCfg->isEseIniFeatureEnabled
Srinivas Girigowda640728a2013-03-28 12:21:54 -0700743#endif
744 )
745 {
746 wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM;
747 }
James Zmuda77fb5ae2013-01-29 08:00:17 -0800748#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -0800749#ifdef FEATURE_WLAN_TDLS
750 wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS
751 | WIPHY_FLAG_TDLS_EXTERNAL_SETUP;
752#endif
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +0530753#ifdef FEATURE_WLAN_SCAN_PNO
Hardik Kantilal Patel3dfd8792013-11-13 20:34:57 +0530754 if (pCfg->configPNOScanSupport)
755 {
756 wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN;
757 wiphy->max_sched_scan_ssids = SIR_PNO_MAX_SUPP_NETWORKS;
758 wiphy->max_match_sets = SIR_PNO_MAX_SUPP_NETWORKS;
759 wiphy->max_sched_scan_ie_len = SIR_MAC_MAX_IE_LENGTH;
760 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +0530761#endif/*FEATURE_WLAN_SCAN_PNO*/
Mohit Khanna698ba2a2012-12-04 15:08:18 -0800762
Amar Singhalfddc28c2013-09-05 13:03:40 -0700763#ifdef CONFIG_ENABLE_LINUX_REG
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -0700764 /* even with WIPHY_FLAG_CUSTOM_REGULATORY,
765 driver can still register regulatory callback and
Amar Singhalfddc28c2013-09-05 13:03:40 -0700766 it will get regulatory settings in wiphy->band[], but
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -0700767 driver need to determine what to do with both
768 regulatory settings */
Amar Singhalfddc28c2013-09-05 13:03:40 -0700769
770 wiphy->reg_notifier = wlan_hdd_linux_reg_notifier;
Amar Singhala49cbc52013-10-08 18:37:44 -0700771#else
772 wiphy->reg_notifier = wlan_hdd_crda_reg_notifier;
Amar Singhalfddc28c2013-09-05 13:03:40 -0700773#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700774
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530775 wiphy->max_scan_ssids = MAX_SCAN_SSID;
776
Madan Mohan Koyyalamudi6815b162013-07-19 17:17:46 +0530777 wiphy->max_scan_ie_len = SIR_MAC_MAX_IE_LENGTH;
Jeff Johnson295189b2012-06-20 16:38:30 -0700778
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +0530779 wiphy->max_acl_mac_addrs = MAX_ACL_MAC_ADDRESS;
780
Jeff Johnson295189b2012-06-20 16:38:30 -0700781 /* Supports STATION & AD-HOC modes right now */
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530782 wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -0700783 | BIT(NL80211_IFTYPE_ADHOC)
Jeff Johnson295189b2012-06-20 16:38:30 -0700784 | BIT(NL80211_IFTYPE_P2P_CLIENT)
785 | BIT(NL80211_IFTYPE_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -0700786 | BIT(NL80211_IFTYPE_AP);
787
Rashmi Ramannabd3feb72014-02-25 16:14:48 +0530788 if( pCfg->advertiseConcurrentOperation )
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800789 {
Rashmi Ramannabd3feb72014-02-25 16:14:48 +0530790#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
791 if( pCfg->enableMCC )
792 {
793 /* Currently, supports up to two channels */
794 wlan_hdd_iface_combination.num_different_channels = 2;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800795
Rashmi Ramannabd3feb72014-02-25 16:14:48 +0530796 if( !pCfg->allowMCCGODiffBI )
797 wlan_hdd_iface_combination.beacon_int_infra_match = true;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800798
Rashmi Ramannabd3feb72014-02-25 16:14:48 +0530799 }
800 wiphy->iface_combinations = &wlan_hdd_iface_combination;
801 wiphy->n_iface_combinations = 1;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800802#endif
Rashmi Ramannabd3feb72014-02-25 16:14:48 +0530803 }
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800804
Jeff Johnson295189b2012-06-20 16:38:30 -0700805 /* Before registering we need to update the ht capabilitied based
806 * on ini values*/
807 if( !pCfg->ShortGI20MhzEnable )
808 {
809 wlan_hdd_band_2_4_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
810 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
811 wlan_hdd_band_p2p_2_4_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
812 }
813
814 if( !pCfg->ShortGI40MhzEnable )
815 {
816 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_40;
817 }
818
819 if( !pCfg->nChannelBondingMode5GHz )
820 {
821 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
822 }
823
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +0530824 wiphy->bands[IEEE80211_BAND_2GHZ] = &wlan_hdd_band_2_4_GHZ;
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +0530825 if (true == hdd_is_5g_supported(pHddCtx))
826 {
827 wiphy->bands[IEEE80211_BAND_5GHZ] = &wlan_hdd_band_5_GHZ;
828 }
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +0530829
830 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
831 {
832
833 if (NULL == wiphy->bands[i])
834 {
835 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[i] is NULL, i = %d",
836 __func__, i);
837 continue;
838 }
839
840 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
841 {
842 struct ieee80211_supported_band *band = wiphy->bands[i];
843
844 if (IEEE80211_BAND_2GHZ == i && eCSR_BAND_5G == pCfg->nBandCapability) // 5G only
845 {
846 // Enable social channels for P2P
847 if (WLAN_HDD_IS_SOCIAL_CHANNEL(band->channels[j].center_freq))
848 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
849 else
850 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
851 continue;
852 }
853 else if (IEEE80211_BAND_5GHZ == i && eCSR_BAND_24 == pCfg->nBandCapability) // 2G only
854 {
855 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
856 continue;
857 }
858 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700859 }
860 /*Initialise the supported cipher suite details*/
861 wiphy->cipher_suites = hdd_cipher_suites;
862 wiphy->n_cipher_suites = ARRAY_SIZE(hdd_cipher_suites);
863
864 /*signal strength in mBm (100*dBm) */
865 wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
866
867#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Jeff Johnson295189b2012-06-20 16:38:30 -0700868 wiphy->max_remain_on_channel_duration = 1000;
869#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700870
Rajesh Chauhan98a31f82014-01-06 20:15:25 -0800871 wiphy->n_vendor_commands = 0;
872 wiphy->vendor_events = wlan_hdd_cfg80211_vendor_events;
873 wiphy->n_vendor_events = ARRAY_SIZE(wlan_hdd_cfg80211_vendor_events);
874
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +0530875 EXIT();
876 return 0;
877}
878
879/* In this function we are registering wiphy. */
880int wlan_hdd_cfg80211_register(struct wiphy *wiphy)
881{
882 ENTER();
883 /* Register our wiphy dev with cfg80211 */
Jeff Johnson295189b2012-06-20 16:38:30 -0700884 if (0 > wiphy_register(wiphy))
885 {
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +0530886 /* print error */
Jeff Johnson295189b2012-06-20 16:38:30 -0700887 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
888 return -EIO;
889 }
890
891 EXIT();
892 return 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530893}
Jeff Johnson295189b2012-06-20 16:38:30 -0700894
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +0530895/* In this function we are updating channel list when,
896 regulatory domain is FCC and country code is US.
897 Here In FCC standard 5GHz UNII-1 Bands are indoor only.
898 As per FCC smart phone is not a indoor device.
899 GO should not opeate on indoor channels */
900void wlan_hdd_cfg80211_update_reg_info(struct wiphy *wiphy)
901{
902 int j;
903 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
904 tANI_U8 defaultCountryCode[3] = SME_INVALID_COUNTRY_CODE;
905 //Default counrtycode from NV at the time of wiphy initialization.
906 if (eHAL_STATUS_SUCCESS != sme_GetDefaultCountryCodeFrmNv(pHddCtx->hHal,
907 &defaultCountryCode[0]))
908 {
Jeff Johnson0299d0a2013-10-30 12:37:43 -0700909 hddLog(LOGE, FL("Failed to get default country code from NV"));
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +0530910 }
911 if ((defaultCountryCode[0]== 'U') && (defaultCountryCode[1]=='S'))
912 {
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +0530913 if (NULL == wiphy->bands[IEEE80211_BAND_5GHZ])
914 {
915 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[IEEE80211_BAND_5GHZ] is NULL",__func__ );
916 return;
917 }
918 for (j = 0; j < wiphy->bands[IEEE80211_BAND_5GHZ]->n_channels; j++)
919 {
920 struct ieee80211_supported_band *band = wiphy->bands[IEEE80211_BAND_5GHZ];
921 // Mark UNII -1 band channel as passive
922 if (WLAN_HDD_CHANNEL_IN_UNII_1_BAND(band->channels[j].center_freq))
923 band->channels[j].flags |= IEEE80211_CHAN_PASSIVE_SCAN;
924 }
925 }
926}
927
Jeff Johnson295189b2012-06-20 16:38:30 -0700928/* In this function we will do all post VOS start initialization.
929 In this function we will register for all frame in which supplicant
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530930 is interested.
Jeff Johnson295189b2012-06-20 16:38:30 -0700931*/
932void wlan_hdd_cfg80211_post_voss_start(hdd_adapter_t* pAdapter)
933{
Jeff Johnson295189b2012-06-20 16:38:30 -0700934 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
935 /* Register for all P2P action, public action etc frames */
936 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
937
Jeff Johnsone7245742012-09-05 17:12:55 -0700938 ENTER();
939
Jeff Johnson295189b2012-06-20 16:38:30 -0700940 /* Right now we are registering these frame when driver is getting
941 initialized. Once we will move to 2.6.37 kernel, in which we have
942 frame register ops, we will move this code as a part of that */
943 /* GAS Initial Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530944 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Jeff Johnson295189b2012-06-20 16:38:30 -0700945 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
946
947 /* GAS Initial Response */
948 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
949 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530950
Jeff Johnson295189b2012-06-20 16:38:30 -0700951 /* GAS Comeback Request */
952 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
953 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
954
955 /* GAS Comeback Response */
956 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
957 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
958
959 /* P2P Public Action */
960 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530961 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -0700962 P2P_PUBLIC_ACTION_FRAME_SIZE );
963
964 /* P2P Action */
965 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
966 (v_U8_t*)P2P_ACTION_FRAME,
967 P2P_ACTION_FRAME_SIZE );
Chet Lanctot186b5732013-03-18 10:26:30 -0700968
Gopichand Nakkalae3d56e72013-04-21 23:33:32 +0530969 /* WNM BSS Transition Request frame */
970 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
971 (v_U8_t*)WNM_BSS_ACTION_FRAME,
972 WNM_BSS_ACTION_FRAME_SIZE );
Leela Venkata Kiran Kumar Reddy Chiralae8e62c82013-10-29 18:23:26 -0700973
974 /* WNM-Notification */
975 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
976 (v_U8_t*)WNM_NOTIFICATION_FRAME,
977 WNM_NOTIFICATION_FRAME_SIZE );
Jeff Johnson295189b2012-06-20 16:38:30 -0700978}
979
980void wlan_hdd_cfg80211_pre_voss_stop(hdd_adapter_t* pAdapter)
981{
Jeff Johnson295189b2012-06-20 16:38:30 -0700982 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
983 /* Register for all P2P action, public action etc frames */
984 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
985
Jeff Johnsone7245742012-09-05 17:12:55 -0700986 ENTER();
987
Jeff Johnson295189b2012-06-20 16:38:30 -0700988 /* Right now we are registering these frame when driver is getting
989 initialized. Once we will move to 2.6.37 kernel, in which we have
990 frame register ops, we will move this code as a part of that */
991 /* GAS Initial Request */
992
993 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
994 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
995
996 /* GAS Initial Response */
997 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
998 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530999
Jeff Johnson295189b2012-06-20 16:38:30 -07001000 /* GAS Comeback Request */
1001 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
1002 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
1003
1004 /* GAS Comeback Response */
1005 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
1006 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
1007
1008 /* P2P Public Action */
1009 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301010 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -07001011 P2P_PUBLIC_ACTION_FRAME_SIZE );
1012
1013 /* P2P Action */
1014 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
1015 (v_U8_t*)P2P_ACTION_FRAME,
1016 P2P_ACTION_FRAME_SIZE );
Leela Venkata Kiran Kumar Reddy Chiralae8e62c82013-10-29 18:23:26 -07001017 /* WNM-Notification */
1018 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
1019 (v_U8_t*)WNM_NOTIFICATION_FRAME,
1020 WNM_NOTIFICATION_FRAME_SIZE );
Jeff Johnson295189b2012-06-20 16:38:30 -07001021}
1022
1023#ifdef FEATURE_WLAN_WAPI
1024void wlan_hdd_cfg80211_set_key_wapi(hdd_adapter_t* pAdapter, u8 key_index,
1025 const u8 *mac_addr, u8 *key , int key_Len)
1026{
1027 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
1028 tCsrRoamSetKey setKey;
1029 v_BOOL_t isConnected = TRUE;
1030 int status = 0;
1031 v_U32_t roamId= 0xFF;
1032 tANI_U8 *pKeyPtr = NULL;
1033 int n = 0;
1034
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05301035 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s(%d)",
1036 __func__, hdd_device_modetoString(pAdapter->device_mode),
1037 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07001038
Gopichand Nakkalae7480202013-02-11 15:24:22 +05301039 vos_mem_zero(&setKey, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -07001040 setKey.keyId = key_index; // Store Key ID
1041 setKey.encType = eCSR_ENCRYPT_TYPE_WPI; // SET WAPI Encryption
1042 setKey.keyDirection = eSIR_TX_RX; // Key Directionn both TX and RX
1043 setKey.paeRole = 0 ; // the PAE role
1044 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
1045 {
1046 vos_set_macaddr_broadcast( (v_MACADDR_t *)setKey.peerMac );
1047 }
1048 else
1049 {
1050 isConnected = hdd_connIsConnected(pHddStaCtx);
1051 vos_mem_copy(setKey.peerMac,&pHddStaCtx->conn_info.bssId,WNI_CFG_BSSID_LEN);
1052 }
1053 setKey.keyLength = key_Len;
1054 pKeyPtr = setKey.Key;
1055 memcpy( pKeyPtr, key, key_Len);
1056
Arif Hussain6d2a3322013-11-17 19:50:10 -08001057 hddLog(VOS_TRACE_LEVEL_INFO,"%s: WAPI KEY LENGTH:0x%04x",
Jeff Johnson295189b2012-06-20 16:38:30 -07001058 __func__, key_Len);
1059 for (n = 0 ; n < key_Len; n++)
1060 hddLog(VOS_TRACE_LEVEL_INFO, "%s WAPI KEY Data[%d]:%02x ",
1061 __func__,n,setKey.Key[n]);
1062
1063 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
1064 if ( isConnected )
1065 {
1066 status= sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
1067 pAdapter->sessionId, &setKey, &roamId );
1068 }
1069 if ( status != 0 )
1070 {
1071 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1072 "[%4d] sme_RoamSetKey returned ERROR status= %d",
1073 __LINE__, status );
1074 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
1075 }
1076}
1077#endif /* FEATURE_WLAN_WAPI*/
1078
1079#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301080int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07001081 beacon_data_t **ppBeacon,
1082 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001083#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301084int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001085 beacon_data_t **ppBeacon,
1086 struct cfg80211_beacon_data *params,
1087 int dtim_period)
1088#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301089{
Jeff Johnson295189b2012-06-20 16:38:30 -07001090 int size;
1091 beacon_data_t *beacon = NULL;
1092 beacon_data_t *old = NULL;
1093 int head_len,tail_len;
1094
Jeff Johnsone7245742012-09-05 17:12:55 -07001095 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07001096 if (params->head && !params->head_len)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05301097 {
1098 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1099 FL("head_len is NULL"));
Jeff Johnson295189b2012-06-20 16:38:30 -07001100 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05301101 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001102
1103 old = pAdapter->sessionCtx.ap.beacon;
1104
1105 if (!params->head && !old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05301106 {
1107 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1108 FL("session(%d) old and new heads points to NULL"),
1109 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07001110 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05301111 }
1112
1113 if (params->tail && !params->tail_len)
1114 {
1115 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1116 FL("tail_len is zero but tail is not NULL"));
1117 return -EINVAL;
1118 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001119
Jeff Johnson295189b2012-06-20 16:38:30 -07001120#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,38))
1121 /* Kernel 3.0 is not updating dtim_period for set beacon */
1122 if (!params->dtim_period)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05301123 {
1124 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1125 FL("dtim period is 0"));
Jeff Johnson295189b2012-06-20 16:38:30 -07001126 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05301127 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001128#endif
1129
1130 if(params->head)
1131 head_len = params->head_len;
1132 else
1133 head_len = old->head_len;
1134
1135 if(params->tail || !old)
1136 tail_len = params->tail_len;
1137 else
1138 tail_len = old->tail_len;
1139
1140 size = sizeof(beacon_data_t) + head_len + tail_len;
1141
1142 beacon = kzalloc(size, GFP_KERNEL);
1143
1144 if( beacon == NULL )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05301145 {
1146 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1147 FL("Mem allocation for beacon failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -07001148 return -ENOMEM;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05301149 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001150
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001151#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07001152 if(params->dtim_period || !old )
1153 beacon->dtim_period = params->dtim_period;
1154 else
1155 beacon->dtim_period = old->dtim_period;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001156#else
1157 if(dtim_period || !old )
1158 beacon->dtim_period = dtim_period;
1159 else
1160 beacon->dtim_period = old->dtim_period;
1161#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301162
Jeff Johnson295189b2012-06-20 16:38:30 -07001163 beacon->head = ((u8 *) beacon) + sizeof(beacon_data_t);
1164 beacon->tail = beacon->head + head_len;
1165 beacon->head_len = head_len;
1166 beacon->tail_len = tail_len;
1167
1168 if(params->head) {
1169 memcpy (beacon->head,params->head,beacon->head_len);
1170 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301171 else {
Jeff Johnson295189b2012-06-20 16:38:30 -07001172 if(old)
1173 memcpy (beacon->head,old->head,beacon->head_len);
1174 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301175
Jeff Johnson295189b2012-06-20 16:38:30 -07001176 if(params->tail) {
1177 memcpy (beacon->tail,params->tail,beacon->tail_len);
1178 }
1179 else {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301180 if(old)
Jeff Johnson295189b2012-06-20 16:38:30 -07001181 memcpy (beacon->tail,old->tail,beacon->tail_len);
1182 }
1183
1184 *ppBeacon = beacon;
1185
1186 kfree(old);
1187
1188 return 0;
1189
1190}
Jeff Johnson295189b2012-06-20 16:38:30 -07001191
1192v_U8_t* wlan_hdd_cfg80211_get_ie_ptr(v_U8_t *pIes, int length, v_U8_t eid)
1193{
1194 int left = length;
1195 v_U8_t *ptr = pIes;
1196 v_U8_t elem_id,elem_len;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301197
Jeff Johnson295189b2012-06-20 16:38:30 -07001198 while(left >= 2)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301199 {
Jeff Johnson295189b2012-06-20 16:38:30 -07001200 elem_id = ptr[0];
1201 elem_len = ptr[1];
1202 left -= 2;
1203 if(elem_len > left)
1204 {
1205 hddLog(VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07001206 FL("****Invalid IEs eid = %d elem_len=%d left=%d*****"),
Jeff Johnson295189b2012-06-20 16:38:30 -07001207 eid,elem_len,left);
1208 return NULL;
1209 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301210 if (elem_id == eid)
Jeff Johnson295189b2012-06-20 16:38:30 -07001211 {
1212 return ptr;
1213 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301214
Jeff Johnson295189b2012-06-20 16:38:30 -07001215 left -= elem_len;
1216 ptr += (elem_len + 2);
1217 }
1218 return NULL;
1219}
1220
Jeff Johnson295189b2012-06-20 16:38:30 -07001221/* Check if rate is 11g rate or not */
1222static int wlan_hdd_rate_is_11g(u8 rate)
1223{
Sanjay Devnani28322e22013-06-21 16:13:40 -07001224 static const u8 gRateArray[8] = {12, 18, 24, 36, 48, 72, 96, 108}; /* actual rate * 2 */
Jeff Johnson295189b2012-06-20 16:38:30 -07001225 u8 i;
1226 for (i = 0; i < 8; i++)
1227 {
1228 if(rate == gRateArray[i])
1229 return TRUE;
1230 }
1231 return FALSE;
1232}
1233
1234/* Check for 11g rate and set proper 11g only mode */
1235static void wlan_hdd_check_11gmode(u8 *pIe, u8* require_ht,
1236 u8* pCheckRatesfor11g, eSapPhyMode* pSapHw_mode)
1237{
1238 u8 i, num_rates = pIe[0];
1239
1240 pIe += 1;
1241 for ( i = 0; i < num_rates; i++)
1242 {
1243 if( *pCheckRatesfor11g && (TRUE == wlan_hdd_rate_is_11g(pIe[i] & RATE_MASK)))
1244 {
1245 /* If rate set have 11g rate than change the mode to 11G */
1246 *pSapHw_mode = eSAP_DOT11_MODE_11g;
1247 if (pIe[i] & BASIC_RATE_MASK)
1248 {
1249 /* If we have 11g rate as basic rate, it means mode
1250 is 11g only mode.
1251 */
1252 *pSapHw_mode = eSAP_DOT11_MODE_11g_ONLY;
1253 *pCheckRatesfor11g = FALSE;
1254 }
1255 }
1256 else if((BASIC_RATE_MASK | WLAN_BSS_MEMBERSHIP_SELECTOR_HT_PHY) == pIe[i])
1257 {
1258 *require_ht = TRUE;
1259 }
1260 }
1261 return;
1262}
1263
1264static void wlan_hdd_set_sapHwmode(hdd_adapter_t *pHostapdAdapter)
1265{
1266 tsap_Config_t *pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
1267 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
1268 struct ieee80211_mgmt *pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
1269 u8 checkRatesfor11g = TRUE;
1270 u8 require_ht = FALSE;
1271 u8 *pIe=NULL;
1272
1273 pConfig->SapHw_mode= eSAP_DOT11_MODE_11b;
1274
1275 pIe = wlan_hdd_cfg80211_get_ie_ptr(&pMgmt_frame->u.beacon.variable[0],
1276 pBeacon->head_len, WLAN_EID_SUPP_RATES);
1277 if (pIe != NULL)
1278 {
1279 pIe += 1;
1280 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
1281 &pConfig->SapHw_mode);
1282 }
1283
1284 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
1285 WLAN_EID_EXT_SUPP_RATES);
1286 if (pIe != NULL)
1287 {
1288
1289 pIe += 1;
1290 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
1291 &pConfig->SapHw_mode);
1292 }
1293
1294 if( pConfig->channel > 14 )
1295 {
1296 pConfig->SapHw_mode= eSAP_DOT11_MODE_11a;
1297 }
1298
1299 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
1300 WLAN_EID_HT_CAPABILITY);
1301
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301302 if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07001303 {
1304 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n;
1305 if(require_ht)
1306 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n_ONLY;
1307 }
1308}
1309
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05301310static int wlan_hdd_add_ie(hdd_adapter_t* pHostapdAdapter, v_U8_t *genie,
1311 v_U8_t *total_ielen, v_U8_t *oui, v_U8_t oui_size)
1312{
Arif Hussaine7f3ea52013-09-12 21:56:36 -07001313 v_U16_t ielen = 0;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05301314 v_U8_t *pIe = NULL;
1315 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
1316
1317 pIe = wlan_hdd_get_vendor_oui_ie_ptr(oui, oui_size,
1318 pBeacon->tail, pBeacon->tail_len);
1319
1320 if (pIe)
1321 {
1322 ielen = pIe[1] + 2;
1323 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
1324 {
1325 vos_mem_copy(&genie[*total_ielen], pIe, ielen);
1326 }
1327 else
1328 {
1329 hddLog( VOS_TRACE_LEVEL_ERROR, "**Ie Length is too big***");
1330 return -EINVAL;
1331 }
1332 *total_ielen += ielen;
1333 }
1334 return 0;
1335}
1336
Arif Hussaine7f3ea52013-09-12 21:56:36 -07001337static void wlan_hdd_add_hostapd_conf_vsie(hdd_adapter_t* pHostapdAdapter,
1338 v_U8_t *genie, v_U8_t *total_ielen)
1339{
1340 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
1341 int left = pBeacon->tail_len;
1342 v_U8_t *ptr = pBeacon->tail;
1343 v_U8_t elem_id, elem_len;
1344 v_U16_t ielen = 0;
1345
1346 if ( NULL == ptr || 0 == left )
1347 return;
1348
1349 while (left >= 2)
1350 {
1351 elem_id = ptr[0];
1352 elem_len = ptr[1];
1353 left -= 2;
1354 if (elem_len > left)
1355 {
1356 hddLog( VOS_TRACE_LEVEL_ERROR,
1357 "****Invalid IEs eid = %d elem_len=%d left=%d*****",
1358 elem_id, elem_len, left);
1359 return;
1360 }
1361 if (IE_EID_VENDOR == elem_id)
1362 {
1363 /* skipping the VSIE's which we don't want to include or
1364 * it will be included by existing code
1365 */
1366 if ((memcmp( &ptr[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) != 0 ) &&
1367#ifdef WLAN_FEATURE_WFD
1368 (memcmp( &ptr[2], WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE) != 0) &&
1369#endif
1370 (memcmp( &ptr[2], WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
1371 (memcmp( &ptr[2], BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
1372 (memcmp( &ptr[2], "\x00\x50\xf2\x02", WPA_OUI_TYPE_SIZE) != 0) &&
1373 (memcmp( &ptr[2], WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
1374 (memcmp( &ptr[2], P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE) != 0))
1375 {
1376 ielen = ptr[1] + 2;
1377 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
1378 {
1379 vos_mem_copy(&genie[*total_ielen], ptr, ielen);
1380 *total_ielen += ielen;
1381 }
1382 else
1383 {
1384 hddLog( VOS_TRACE_LEVEL_ERROR,
1385 "IE Length is too big "
1386 "IEs eid=%d elem_len=%d total_ie_lent=%d",
1387 elem_id, elem_len, *total_ielen);
1388 }
1389 }
1390 }
1391
1392 left -= elem_len;
1393 ptr += (elem_len + 2);
1394 }
1395 return;
1396}
1397
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001398#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07001399static int wlan_hdd_cfg80211_update_apies(hdd_adapter_t* pHostapdAdapter,
1400 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001401#else
1402static int wlan_hdd_cfg80211_update_apies(hdd_adapter_t* pHostapdAdapter,
1403 struct cfg80211_beacon_data *params)
1404#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07001405{
1406 v_U8_t *genie;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05301407 v_U8_t total_ielen = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07001408 v_U8_t addIE[1] = {0};
Jeff Johnsone7245742012-09-05 17:12:55 -07001409 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07001410
1411 genie = vos_mem_malloc(MAX_GENIE_LEN);
1412
1413 if(genie == NULL) {
1414
1415 return -ENOMEM;
1416 }
1417
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05301418 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
1419 &total_ielen, WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07001420 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05301421 hddLog(LOGE,
1422 FL("Adding WPS IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05301423 ret = -EINVAL;
1424 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001425 }
1426
1427#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05301428 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
1429 &total_ielen, WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE))
1430 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05301431 hddLog(LOGE,
1432 FL("Adding WFD IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05301433 ret = -EINVAL;
1434 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001435 }
1436#endif
1437
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05301438 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
1439 &total_ielen, P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07001440 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05301441 hddLog(LOGE,
1442 FL("Adding P2P IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05301443 ret = -EINVAL;
1444 goto done;
1445 }
1446
1447 if (WLAN_HDD_SOFTAP == pHostapdAdapter->device_mode)
1448 {
Arif Hussaine7f3ea52013-09-12 21:56:36 -07001449 wlan_hdd_add_hostapd_conf_vsie(pHostapdAdapter, genie, &total_ielen);
Jeff Johnson295189b2012-06-20 16:38:30 -07001450 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001451
1452 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1453 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, genie, total_ielen, NULL,
1454 eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
1455 {
1456 hddLog(LOGE,
1457 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001458 ret = -EINVAL;
1459 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001460 }
1461
1462 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1463 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
1464 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
1465 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
1466 ==eHAL_STATUS_FAILURE)
1467 {
1468 hddLog(LOGE,
1469 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001470 ret = -EINVAL;
1471 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001472 }
1473
1474 // Added for ProResp IE
1475 if ( (params->proberesp_ies != NULL) && (params->proberesp_ies_len != 0) )
1476 {
1477 u16 rem_probe_resp_ie_len = params->proberesp_ies_len;
1478 u8 probe_rsp_ie_len[3] = {0};
1479 u8 counter = 0;
1480 /* Check Probe Resp Length if it is greater then 255 then Store
1481 Probe Resp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1 &
1482 WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are not able
1483 Store More then 255 bytes into One Variable.
1484 */
1485 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
1486 {
1487 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
1488 {
1489 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
1490 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
1491 }
1492 else
1493 {
1494 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
1495 rem_probe_resp_ie_len = 0;
1496 }
1497 }
1498
1499 rem_probe_resp_ie_len = 0;
1500
1501 if (probe_rsp_ie_len[0] > 0)
1502 {
1503 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1504 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
1505 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
1506 probe_rsp_ie_len[0], NULL,
1507 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
1508 {
1509 hddLog(LOGE,
1510 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001511 ret = -EINVAL;
1512 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001513 }
1514 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
1515 }
1516
1517 if (probe_rsp_ie_len[1] > 0)
1518 {
1519 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1520 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
1521 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
1522 probe_rsp_ie_len[1], NULL,
1523 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
1524 {
1525 hddLog(LOGE,
1526 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001527 ret = -EINVAL;
1528 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001529 }
1530 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
1531 }
1532
1533 if (probe_rsp_ie_len[2] > 0)
1534 {
1535 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1536 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
1537 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
1538 probe_rsp_ie_len[2], NULL,
1539 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
1540 {
1541 hddLog(LOGE,
1542 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001543 ret = -EINVAL;
1544 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001545 }
1546 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
1547 }
1548
1549 if (probe_rsp_ie_len[1] == 0 )
1550 {
1551 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1552 WNI_CFG_PROBE_RSP_ADDNIE_DATA2, (tANI_U8*)addIE, 0, NULL,
1553 eANI_BOOLEAN_FALSE) )
1554 {
1555 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08001556 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07001557 }
1558 }
1559
1560 if (probe_rsp_ie_len[2] == 0 )
1561 {
1562 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1563 WNI_CFG_PROBE_RSP_ADDNIE_DATA3, (tANI_U8*)addIE, 0, NULL,
1564 eANI_BOOLEAN_FALSE) )
1565 {
1566 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08001567 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07001568 }
1569 }
1570
1571 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1572 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
1573 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
1574 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
1575 == eHAL_STATUS_FAILURE)
1576 {
1577 hddLog(LOGE,
1578 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001579 ret = -EINVAL;
1580 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001581 }
1582 }
1583 else
1584 {
1585 // Reset WNI_CFG_PROBE_RSP Flags
1586 wlan_hdd_reset_prob_rspies(pHostapdAdapter);
1587
1588 hddLog(VOS_TRACE_LEVEL_INFO,
1589 "%s: No Probe Response IE received in set beacon",
1590 __func__);
1591 }
1592
1593 // Added for AssocResp IE
1594 if ( (params->assocresp_ies != NULL) && (params->assocresp_ies_len != 0) )
1595 {
1596 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1597 WNI_CFG_ASSOC_RSP_ADDNIE_DATA, (tANI_U8*)params->assocresp_ies,
1598 params->assocresp_ies_len, NULL,
1599 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
1600 {
1601 hddLog(LOGE,
1602 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001603 ret = -EINVAL;
1604 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001605 }
1606
1607 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1608 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 1, NULL,
1609 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
1610 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
1611 == eHAL_STATUS_FAILURE)
1612 {
1613 hddLog(LOGE,
1614 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001615 ret = -EINVAL;
1616 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001617 }
1618 }
1619 else
1620 {
1621 hddLog(VOS_TRACE_LEVEL_INFO,
1622 "%s: No Assoc Response IE received in set beacon",
1623 __func__);
1624
1625 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1626 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
1627 eANI_BOOLEAN_FALSE) )
1628 {
1629 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08001630 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07001631 }
1632 }
1633
Jeff Johnsone7245742012-09-05 17:12:55 -07001634done:
Jeff Johnson295189b2012-06-20 16:38:30 -07001635 vos_mem_free(genie);
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05301636 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07001637}
Jeff Johnson295189b2012-06-20 16:38:30 -07001638
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301639/*
Jeff Johnson295189b2012-06-20 16:38:30 -07001640 * FUNCTION: wlan_hdd_validate_operation_channel
1641 * called by wlan_hdd_cfg80211_start_bss() and
1642 * wlan_hdd_cfg80211_set_channel()
1643 * This function validates whether given channel is part of valid
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301644 * channel list.
1645 */
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07001646VOS_STATUS wlan_hdd_validate_operation_channel(hdd_adapter_t *pAdapter,int channel)
Jeff Johnson295189b2012-06-20 16:38:30 -07001647{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301648
Jeff Johnson295189b2012-06-20 16:38:30 -07001649 v_U32_t num_ch = 0;
1650 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN];
1651 u32 indx = 0;
1652 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05301653 v_U8_t fValidChannel = FALSE, count = 0;
1654 hdd_config_t *hdd_pConfig_ini= (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301655
Jeff Johnson295189b2012-06-20 16:38:30 -07001656 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
1657
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05301658 if ( hdd_pConfig_ini->sapAllowAllChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -07001659 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05301660 /* Validate the channel */
1661 for (count = RF_CHAN_1 ; count <= RF_CHAN_165 ; count++)
Jeff Johnson295189b2012-06-20 16:38:30 -07001662 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05301663 if ( channel == rfChannels[count].channelNum )
1664 {
1665 fValidChannel = TRUE;
1666 break;
1667 }
1668 }
1669 if (fValidChannel != TRUE)
1670 {
1671 hddLog(VOS_TRACE_LEVEL_ERROR,
1672 "%s: Invalid Channel [%d]", __func__, channel);
1673 return VOS_STATUS_E_FAILURE;
Jeff Johnson295189b2012-06-20 16:38:30 -07001674 }
1675 }
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05301676 else
Jeff Johnson295189b2012-06-20 16:38:30 -07001677 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05301678 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
1679 valid_ch, &num_ch))
1680 {
1681 hddLog(VOS_TRACE_LEVEL_ERROR,
1682 "%s: failed to get valid channel list", __func__);
1683 return VOS_STATUS_E_FAILURE;
1684 }
1685 for (indx = 0; indx < num_ch; indx++)
1686 {
1687 if (channel == valid_ch[indx])
1688 {
1689 break;
1690 }
1691 }
1692
Rashmi Ramanna3b59e122014-04-10 14:45:13 +05301693 if (indx >= num_ch)
1694 {
1695 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
1696 {
1697 eCsrBand band;
1698 unsigned int freq;
1699
1700 sme_GetFreqBand(hHal, &band);
1701
1702 if (eCSR_BAND_5G == band)
1703 {
1704#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
1705 if (channel <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
1706 {
1707 freq = ieee80211_channel_to_frequency(channel,
1708 IEEE80211_BAND_2GHZ);
1709 }
1710 else
1711 {
1712 freq = ieee80211_channel_to_frequency(channel,
1713 IEEE80211_BAND_5GHZ);
1714 }
1715#else
1716 freq = ieee80211_channel_to_frequency(channel);
1717#endif
1718 if(WLAN_HDD_IS_SOCIAL_CHANNEL(freq))
1719 return VOS_STATUS_SUCCESS;
1720 }
1721 }
1722
1723 hddLog(VOS_TRACE_LEVEL_ERROR,
1724 "%s: Invalid Channel [%d]", __func__, channel);
1725 return VOS_STATUS_E_FAILURE;
1726 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001727 }
Rashmi Ramanna3b59e122014-04-10 14:45:13 +05301728
Jeff Johnson295189b2012-06-20 16:38:30 -07001729 return VOS_STATUS_SUCCESS;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301730
Jeff Johnson295189b2012-06-20 16:38:30 -07001731}
1732
Viral Modi3a32cc52013-02-08 11:14:52 -08001733/**
1734 * FUNCTION: wlan_hdd_cfg80211_set_channel
1735 * This function is used to set the channel number
1736 */
1737static int wlan_hdd_cfg80211_set_channel( struct wiphy *wiphy, struct net_device *dev,
1738 struct ieee80211_channel *chan,
1739 enum nl80211_channel_type channel_type
1740 )
1741{
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05301742 hdd_adapter_t *pAdapter = NULL;
Viral Modi3a32cc52013-02-08 11:14:52 -08001743 v_U32_t num_ch = 0;
Jeff Johnson4416a782013-03-25 14:17:50 -07001744 int channel = 0;
Viral Modi3a32cc52013-02-08 11:14:52 -08001745 int freq = chan->center_freq; /* freq is in MHZ */
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05301746 hdd_context_t *pHddCtx;
1747 int status;
Viral Modi3a32cc52013-02-08 11:14:52 -08001748
1749 ENTER();
1750
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05301751
Viral Modi3a32cc52013-02-08 11:14:52 -08001752 if( NULL == dev )
1753 {
1754 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08001755 "%s: Called with dev = NULL.", __func__);
Viral Modi3a32cc52013-02-08 11:14:52 -08001756 return -ENODEV;
1757 }
1758 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
1759
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05301760 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
1761 TRACE_CODE_HDD_CFG80211_SET_CHANNEL, pAdapter->sessionId,
1762 channel_type ));
Viral Modi3a32cc52013-02-08 11:14:52 -08001763 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05301764 "%s: device_mode = %s (%d) freq = %d", __func__,
1765 hdd_device_modetoString(pAdapter->device_mode),
1766 pAdapter->device_mode, chan->center_freq);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05301767
1768 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1769 status = wlan_hdd_validate_context(pHddCtx);
1770
1771 if (0 != status)
Viral Modi3a32cc52013-02-08 11:14:52 -08001772 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05301773 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1774 "%s: HDD context is not valid", __func__);
1775 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -08001776 }
1777
1778 /*
1779 * Do freq to chan conversion
1780 * TODO: for 11a
1781 */
1782
1783 channel = ieee80211_frequency_to_channel(freq);
1784
1785 /* Check freq range */
1786 if ((WNI_CFG_CURRENT_CHANNEL_STAMIN > channel) ||
1787 (WNI_CFG_CURRENT_CHANNEL_STAMAX < channel))
1788 {
1789 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08001790 "%s: Channel [%d] is outside valid range from %d to %d",
Viral Modi3a32cc52013-02-08 11:14:52 -08001791 __func__, channel, WNI_CFG_CURRENT_CHANNEL_STAMIN,
1792 WNI_CFG_CURRENT_CHANNEL_STAMAX);
1793 return -EINVAL;
1794 }
1795
1796 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
1797
Gopichand Nakkala6ab19562013-03-07 13:59:42 +05301798 if ((WLAN_HDD_SOFTAP != pAdapter->device_mode) &&
1799 (WLAN_HDD_P2P_GO != pAdapter->device_mode))
Viral Modi3a32cc52013-02-08 11:14:52 -08001800 {
1801 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pAdapter,channel))
1802 {
1803 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08001804 "%s: Invalid Channel [%d]", __func__, channel);
Viral Modi3a32cc52013-02-08 11:14:52 -08001805 return -EINVAL;
1806 }
1807 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
1808 "%s: set channel to [%d] for device mode =%d",
1809 __func__, channel,pAdapter->device_mode);
1810 }
1811 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Viral Modi3a32cc52013-02-08 11:14:52 -08001812 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Viral Modi3a32cc52013-02-08 11:14:52 -08001813 )
1814 {
1815 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
1816 tCsrRoamProfile * pRoamProfile = &pWextState->roamProfile;
1817 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
1818
1819 if (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState)
1820 {
1821 /* Link is up then return cant set channel*/
1822 hddLog( VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08001823 "%s: IBSS Associated, can't set the channel", __func__);
Viral Modi3a32cc52013-02-08 11:14:52 -08001824 return -EINVAL;
1825 }
1826
1827 num_ch = pRoamProfile->ChannelInfo.numOfChannels = 1;
1828 pHddStaCtx->conn_info.operationChannel = channel;
1829 pRoamProfile->ChannelInfo.ChannelList =
1830 &pHddStaCtx->conn_info.operationChannel;
1831 }
1832 else if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Viral Modi3a32cc52013-02-08 11:14:52 -08001833 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Viral Modi3a32cc52013-02-08 11:14:52 -08001834 )
1835 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05301836 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
1837 {
1838 if(VOS_STATUS_SUCCESS !=
1839 wlan_hdd_validate_operation_channel(pAdapter,channel))
1840 {
1841 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08001842 "%s: Invalid Channel [%d]", __func__, channel);
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05301843 return -EINVAL;
1844 }
1845 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
1846 }
1847 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
Viral Modi3a32cc52013-02-08 11:14:52 -08001848 {
1849 hdd_config_t *cfg_param = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
1850
1851 /* If auto channel selection is configured as enable/ 1 then ignore
1852 channel set by supplicant
1853 */
1854 if ( cfg_param->apAutoChannelSelection )
1855 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05301856 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel =
1857 AUTO_CHANNEL_SELECT;
Viral Modi3a32cc52013-02-08 11:14:52 -08001858 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05301859 "%s: set channel to auto channel (0) for device mode =%s (%d)",
1860 __func__, hdd_device_modetoString(pAdapter->device_mode),
1861 pAdapter->device_mode);
Viral Modi3a32cc52013-02-08 11:14:52 -08001862 }
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05301863 else
1864 {
1865 if(VOS_STATUS_SUCCESS !=
1866 wlan_hdd_validate_operation_channel(pAdapter,channel))
1867 {
1868 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08001869 "%s: Invalid Channel [%d]", __func__, channel);
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05301870 return -EINVAL;
1871 }
1872 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
1873 }
Viral Modi3a32cc52013-02-08 11:14:52 -08001874 }
1875 }
1876 else
1877 {
1878 hddLog(VOS_TRACE_LEVEL_FATAL,
1879 "%s: Invalid device mode failed to set valid channel", __func__);
1880 return -EINVAL;
1881 }
1882 EXIT();
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05301883 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -08001884}
1885
Jeff Johnson295189b2012-06-20 16:38:30 -07001886#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
1887static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
1888 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001889#else
1890static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
1891 struct cfg80211_beacon_data *params,
1892 const u8 *ssid, size_t ssid_len,
1893 enum nl80211_hidden_ssid hidden_ssid)
1894#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07001895{
1896 tsap_Config_t *pConfig;
1897 beacon_data_t *pBeacon = NULL;
1898 struct ieee80211_mgmt *pMgmt_frame;
1899 v_U8_t *pIe=NULL;
1900 v_U16_t capab_info;
1901 eCsrAuthType RSNAuthType;
1902 eCsrEncryptionType RSNEncryptType;
1903 eCsrEncryptionType mcRSNEncryptType;
1904 int status = VOS_STATUS_SUCCESS;
1905 tpWLAN_SAPEventCB pSapEventCallback;
1906 hdd_hostapd_state_t *pHostapdState;
1907 v_U8_t wpaRsnIEdata[(SIR_MAC_MAX_IE_LENGTH * 2)+4]; //Max ie length 255 * 2(WPA+RSN) + 2 bytes (vendor specific ID) * 2
1908 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05301909 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07001910 struct qc_mac_acl_entry *acl_entry = NULL;
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05301911 hdd_config_t *iniConfig;
Jeff Johnson295189b2012-06-20 16:38:30 -07001912 v_SINT_t i;
Madan Mohan Koyyalamudi543172b2012-12-05 16:40:18 -08001913 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
Chet Lanctot8cecea22014-02-11 19:09:36 -08001914 v_BOOL_t MFPCapable;
1915 v_BOOL_t MFPRequired;
Abhishek Singhf0ac1752014-03-05 17:47:09 +05301916 eHddDot11Mode sapDot11Mode =
1917 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->sapDot11Mode;
Jeff Johnson295189b2012-06-20 16:38:30 -07001918
1919 ENTER();
1920
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05301921 iniConfig = pHddCtx->cfg_ini;
1922
Jeff Johnson295189b2012-06-20 16:38:30 -07001923 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter);
1924
1925 pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
1926
1927 pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
1928
1929 pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
1930
1931 pConfig->beacon_int = pMgmt_frame->u.beacon.beacon_int;
1932
1933 //channel is already set in the set_channel Call back
1934 //pConfig->channel = pCommitConfig->channel;
1935
1936 /*Protection parameter to enable or disable*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301937 pConfig->protEnabled =
Jeff Johnson295189b2012-06-20 16:38:30 -07001938 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtEnabled;
1939
1940 pConfig->dtim_period = pBeacon->dtim_period;
1941
Arif Hussain6d2a3322013-11-17 19:50:10 -08001942 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"****pConfig->dtim_period=%d***",
Jeff Johnson295189b2012-06-20 16:38:30 -07001943 pConfig->dtim_period);
1944
1945
Madan Mohan Koyyalamudie0ca11f2012-11-27 15:57:52 -08001946 if (pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson32d95a32012-09-10 13:15:23 -07001947 {
1948 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -07001949 WLAN_EID_COUNTRY);
Kiet Lam083504c2013-11-25 14:17:45 +05301950 if(memcmp(pHddCtx->cfg_ini->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0)
1951 {
1952 tANI_BOOLEAN restartNeeded;
1953 pConfig->ieee80211d = 1;
1954 vos_mem_copy(pConfig->countryCode, pHddCtx->cfg_ini->apCntryCode, 3);
1955 sme_setRegInfo(hHal, pConfig->countryCode);
1956 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
1957 }
1958 else if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07001959 {
Jeff Johnson32d95a32012-09-10 13:15:23 -07001960 tANI_BOOLEAN restartNeeded;
Jeff Johnson32d95a32012-09-10 13:15:23 -07001961 pConfig->ieee80211d = 1;
1962 vos_mem_copy(pConfig->countryCode, &pIe[2], 3);
1963 sme_setRegInfo(hHal, pConfig->countryCode);
1964 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
Jeff Johnson295189b2012-06-20 16:38:30 -07001965 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07001966 else
1967 {
1968 pConfig->ieee80211d = 0;
1969 }
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05301970 /*
1971 * If auto channel is configured i.e. channel is 0,
1972 * so skip channel validation.
1973 */
1974 if( AUTO_CHANNEL_SELECT != pConfig->channel )
1975 {
1976 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pHostapdAdapter,pConfig->channel))
1977 {
1978 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08001979 "%s: Invalid Channel [%d]", __func__, pConfig->channel);
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05301980 return -EINVAL;
1981 }
1982 }
1983 else
1984 {
1985 if(1 != pHddCtx->is_dynamic_channel_range_set)
1986 {
1987 hdd_config_t *hdd_pConfig= (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini;
1988 WLANSAP_SetChannelRange(hHal, hdd_pConfig->apStartChannelNum,
1989 hdd_pConfig->apEndChannelNum,hdd_pConfig->apOperatingBand);
1990 }
1991 pHddCtx->is_dynamic_channel_range_set = 0;
1992 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001993 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07001994 else
Jeff Johnson295189b2012-06-20 16:38:30 -07001995 {
1996 pConfig->ieee80211d = 0;
1997 }
1998 pConfig->authType = eSAP_AUTO_SWITCH;
1999
2000 capab_info = pMgmt_frame->u.beacon.capab_info;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302001
2002 pConfig->privacy = (pMgmt_frame->u.beacon.capab_info &
Jeff Johnson295189b2012-06-20 16:38:30 -07002003 WLAN_CAPABILITY_PRIVACY) ? VOS_TRUE : VOS_FALSE;
2004
2005 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uPrivacy = pConfig->privacy;
2006
2007 /*Set wps station to configured*/
2008 pIe = wlan_hdd_get_wps_ie_ptr(pBeacon->tail, pBeacon->tail_len);
2009
2010 if(pIe)
2011 {
2012 if(pIe[1] < (2 + WPS_OUI_TYPE_SIZE))
2013 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08002014 hddLog( VOS_TRACE_LEVEL_ERROR, "**Wps Ie Length is too small***");
Jeff Johnson295189b2012-06-20 16:38:30 -07002015 return -EINVAL;
2016 }
2017 else if(memcmp(&pIe[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) == 0)
2018 {
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07002019 hddLog( VOS_TRACE_LEVEL_INFO, "** WPS IE(len %d) ***", (pIe[1]+2));
Jeff Johnson295189b2012-06-20 16:38:30 -07002020 /* Check 15 bit of WPS IE as it contain information for wps state
2021 * WPS state
2022 */
2023 if(SAP_WPS_ENABLED_UNCONFIGURED == pIe[15])
2024 {
2025 pConfig->wps_state = SAP_WPS_ENABLED_UNCONFIGURED;
2026 } else if(SAP_WPS_ENABLED_CONFIGURED == pIe[15])
2027 {
2028 pConfig->wps_state = SAP_WPS_ENABLED_CONFIGURED;
2029 }
2030 }
2031 }
2032 else
2033 {
2034 pConfig->wps_state = SAP_WPS_DISABLED;
2035 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302036 pConfig->fwdWPSPBCProbeReq = 1; // Forward WPS PBC probe request frame up
Jeff Johnson295189b2012-06-20 16:38:30 -07002037
2038 pConfig->RSNWPAReqIELength = 0;
2039 pConfig->pRSNWPAReqIE = NULL;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302040 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -07002041 WLAN_EID_RSN);
2042 if(pIe && pIe[1])
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302043 {
Jeff Johnson295189b2012-06-20 16:38:30 -07002044 pConfig->RSNWPAReqIELength = pIe[1] + 2;
2045 memcpy(&wpaRsnIEdata[0], pIe, pConfig->RSNWPAReqIELength);
2046 pConfig->pRSNWPAReqIE = &wpaRsnIEdata[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302047 /* The actual processing may eventually be more extensive than
2048 * this. Right now, just consume any PMKIDs that are sent in
Jeff Johnson295189b2012-06-20 16:38:30 -07002049 * by the app.
2050 * */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302051 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -07002052 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
2053 &RSNEncryptType,
2054 &mcRSNEncryptType,
2055 &RSNAuthType,
Chet Lanctot8cecea22014-02-11 19:09:36 -08002056 &MFPCapable,
2057 &MFPRequired,
Jeff Johnson295189b2012-06-20 16:38:30 -07002058 pConfig->pRSNWPAReqIE[1]+2,
2059 pConfig->pRSNWPAReqIE );
2060
2061 if( VOS_STATUS_SUCCESS == status )
2062 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302063 /* Now copy over all the security attributes you have
2064 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -07002065 * */
2066 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
2067 pConfig->mcRSNEncryptType = mcRSNEncryptType;
2068 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
2069 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05302070 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -08002071 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -07002072 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
2073 }
2074 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302075
Jeff Johnson295189b2012-06-20 16:38:30 -07002076 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE,
2077 pBeacon->tail, pBeacon->tail_len);
2078
2079 if(pIe && pIe[1] && (pIe[0] == DOT11F_EID_WPA))
2080 {
2081 if (pConfig->pRSNWPAReqIE)
2082 {
2083 /*Mixed mode WPA/WPA2*/
2084 memcpy((&wpaRsnIEdata[0] + pConfig->RSNWPAReqIELength), pIe, pIe[1] + 2);
2085 pConfig->RSNWPAReqIELength += pIe[1] + 2;
2086 }
2087 else
2088 {
2089 pConfig->RSNWPAReqIELength = pIe[1] + 2;
2090 memcpy(&wpaRsnIEdata[0], pIe, pConfig->RSNWPAReqIELength);
2091 pConfig->pRSNWPAReqIE = &wpaRsnIEdata[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302092 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -07002093 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
2094 &RSNEncryptType,
2095 &mcRSNEncryptType,
2096 &RSNAuthType,
Chet Lanctot8cecea22014-02-11 19:09:36 -08002097 &MFPCapable,
2098 &MFPRequired,
Jeff Johnson295189b2012-06-20 16:38:30 -07002099 pConfig->pRSNWPAReqIE[1]+2,
2100 pConfig->pRSNWPAReqIE );
2101
2102 if( VOS_STATUS_SUCCESS == status )
2103 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302104 /* Now copy over all the security attributes you have
2105 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -07002106 * */
2107 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
2108 pConfig->mcRSNEncryptType = mcRSNEncryptType;
2109 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
2110 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05302111 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -08002112 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -07002113 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
2114 }
2115 }
2116 }
2117
Jeff Johnson4416a782013-03-25 14:17:50 -07002118 if (pConfig->RSNWPAReqIELength > sizeof wpaRsnIEdata) {
2119 hddLog( VOS_TRACE_LEVEL_ERROR, "**RSNWPAReqIELength is too large***");
2120 return -EINVAL;
2121 }
2122
Jeff Johnson295189b2012-06-20 16:38:30 -07002123 pConfig->SSIDinfo.ssidHidden = VOS_FALSE;
2124
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002125#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07002126 if (params->ssid != NULL)
2127 {
2128 memcpy(pConfig->SSIDinfo.ssid.ssId, params->ssid, params->ssid_len);
2129 pConfig->SSIDinfo.ssid.length = params->ssid_len;
2130 if (params->hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
2131 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
2132 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002133#else
2134 if (ssid != NULL)
2135 {
2136 memcpy(pConfig->SSIDinfo.ssid.ssId, ssid, ssid_len);
2137 pConfig->SSIDinfo.ssid.length = ssid_len;
2138 if (hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
2139 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
2140 }
2141#endif
2142
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302143 vos_mem_copy(pConfig->self_macaddr.bytes,
Jeff Johnson295189b2012-06-20 16:38:30 -07002144 pHostapdAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302145
Jeff Johnson295189b2012-06-20 16:38:30 -07002146 /* default value */
2147 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
2148 pConfig->num_accept_mac = 0;
2149 pConfig->num_deny_mac = 0;
2150
2151 pIe = wlan_hdd_get_vendor_oui_ie_ptr(BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
2152 pBeacon->tail, pBeacon->tail_len);
2153
2154 /* pIe for black list is following form:
2155 type : 1 byte
2156 length : 1 byte
2157 OUI : 4 bytes
2158 acl type : 1 byte
2159 no of mac addr in black list: 1 byte
2160 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302161 */
2162 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07002163 {
2164 pConfig->SapMacaddr_acl = pIe[6];
2165 pConfig->num_deny_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -08002166 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no deny mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07002167 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05302168 if (pConfig->num_deny_mac > MAX_ACL_MAC_ADDRESS)
2169 pConfig->num_deny_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07002170 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
2171 for (i = 0; i < pConfig->num_deny_mac; i++)
2172 {
2173 vos_mem_copy(&pConfig->deny_mac[i], acl_entry->addr, sizeof(qcmacaddr));
2174 acl_entry++;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302175 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002176 }
2177 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
2178 pBeacon->tail, pBeacon->tail_len);
2179
2180 /* pIe for white list is following form:
2181 type : 1 byte
2182 length : 1 byte
2183 OUI : 4 bytes
2184 acl type : 1 byte
2185 no of mac addr in white list: 1 byte
2186 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302187 */
2188 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07002189 {
2190 pConfig->SapMacaddr_acl = pIe[6];
2191 pConfig->num_accept_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -08002192 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no accept mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07002193 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05302194 if (pConfig->num_accept_mac > MAX_ACL_MAC_ADDRESS)
2195 pConfig->num_accept_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07002196 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
2197 for (i = 0; i < pConfig->num_accept_mac; i++)
2198 {
2199 vos_mem_copy(&pConfig->accept_mac[i], acl_entry->addr, sizeof(qcmacaddr));
2200 acl_entry++;
2201 }
2202 }
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05302203
Jeff Johnson295189b2012-06-20 16:38:30 -07002204 wlan_hdd_set_sapHwmode(pHostapdAdapter);
2205
Jeff Johnsone7245742012-09-05 17:12:55 -07002206#ifdef WLAN_FEATURE_11AC
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -08002207 /* Overwrite the hostapd setting for HW mode only for 11ac.
Kiet Lam0f320422013-11-21 19:29:17 +05302208 * This is valid only if mode is set to 11n in hostapd, either AUTO or
2209 * 11ac in .ini and 11ac is supported by both host and firmware.
2210 * Otherwise, leave whatever is set in hostapd (a OR b OR g OR n mode)
2211 */
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -08002212 if( ((pConfig->SapHw_mode == eSAP_DOT11_MODE_11n) ||
2213 (pConfig->SapHw_mode == eSAP_DOT11_MODE_11n_ONLY)) &&
Abhishek Singhf0ac1752014-03-05 17:47:09 +05302214 (( sapDot11Mode == eHDD_DOT11_MODE_AUTO ) ||
2215 ( sapDot11Mode == eHDD_DOT11_MODE_11ac ) ||
2216 ( sapDot11Mode == eHDD_DOT11_MODE_11ac_ONLY ) ) &&
2217 (sme_IsFeatureSupportedByDriver(DOT11AC)) &&
2218 (sme_IsFeatureSupportedByFW(DOT11AC)) )
Jeff Johnsone7245742012-09-05 17:12:55 -07002219 {
Siddharth Bhalf42f8592014-05-15 13:39:07 +05302220 v_U32_t operatingBand = 0;
Jeff Johnsone7245742012-09-05 17:12:55 -07002221 pConfig->SapHw_mode = eSAP_DOT11_MODE_11ac;
Siddharth Bhalf42f8592014-05-15 13:39:07 +05302222 ccmCfgGetInt(hHal, WNI_CFG_SAP_CHANNEL_SELECT_OPERATING_BAND, &operatingBand);
Ravi Joshi83bfaa12013-05-28 22:12:08 -07002223
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05302224 /* If ACS disable and selected channel <= 14
2225 * OR
2226 * ACS enabled and ACS operating band is choosen as 2.4
2227 * AND
2228 * VHT in 2.4G Disabled
2229 * THEN
2230 * Fallback to 11N mode
2231 */
2232 if (((AUTO_CHANNEL_SELECT != pConfig->channel && pConfig->channel <= SIR_11B_CHANNEL_END)
2233 || (AUTO_CHANNEL_SELECT == pConfig->channel &&
Siddharth Bhalf42f8592014-05-15 13:39:07 +05302234 operatingBand == RF_SUBBAND_2_4_GHZ)) &&
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05302235 iniConfig->enableVhtFor24GHzBand == FALSE)
Ravi Joshi83bfaa12013-05-28 22:12:08 -07002236 {
Siddharth Bhalf42f8592014-05-15 13:39:07 +05302237 hddLog(LOGW, FL("Setting hwmode to 11n, operatingBand = %d, Channel = %d"),
2238 operatingBand, pConfig->channel);
Ravi Joshi83bfaa12013-05-28 22:12:08 -07002239 pConfig->SapHw_mode = eSAP_DOT11_MODE_11n;
2240 }
Jeff Johnsone7245742012-09-05 17:12:55 -07002241 }
2242#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302243
Ravi Joshiaeb7d9e2013-05-02 12:28:14 -07002244 if ( AUTO_CHANNEL_SELECT != pConfig->channel )
2245 {
2246 sme_SelectCBMode(hHal,
2247 sapConvertSapPhyModeToCsrPhyMode(pConfig->SapHw_mode),
2248 pConfig->channel);
2249 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002250 // ht_capab is not what the name conveys,this is used for protection bitmap
2251 pConfig->ht_capab =
2252 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtection;
2253
2254 if ( 0 != wlan_hdd_cfg80211_update_apies(pHostapdAdapter, params) )
2255 {
2256 hddLog(LOGE, FL("SAP Not able to set AP IEs"));
2257 return -EINVAL;
2258 }
2259
2260 //Uapsd Enabled Bit
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302261 pConfig->UapsdEnable =
Jeff Johnson295189b2012-06-20 16:38:30 -07002262 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apUapsdEnabled;
2263 //Enable OBSS protection
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302264 pConfig->obssProtEnabled =
2265 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apOBSSProtEnabled;
Jeff Johnson295189b2012-06-20 16:38:30 -07002266
Chet Lanctot8cecea22014-02-11 19:09:36 -08002267#ifdef WLAN_FEATURE_11W
2268 pConfig->mfpCapable = MFPCapable;
2269 pConfig->mfpRequired = MFPRequired;
2270 hddLog(LOGW, FL("Soft AP MFP capable %d, MFP required %d\n"),
2271 pConfig->mfpCapable, pConfig->mfpRequired);
2272#endif
2273
Arif Hussain6d2a3322013-11-17 19:50:10 -08002274 hddLog(LOGW, FL("SOftAP macaddress : "MAC_ADDRESS_STR),
Jeff Johnson295189b2012-06-20 16:38:30 -07002275 MAC_ADDR_ARRAY(pHostapdAdapter->macAddressCurrent.bytes));
Arif Hussain6d2a3322013-11-17 19:50:10 -08002276 hddLog(LOGW,FL("ssid =%s, beaconint=%d, channel=%d"),
2277 pConfig->SSIDinfo.ssid.ssId, (int)pConfig->beacon_int,
2278 (int)pConfig->channel);
2279 hddLog(LOGW,FL("hw_mode=%x, privacy=%d, authType=%d"),
2280 pConfig->SapHw_mode, pConfig->privacy,
2281 pConfig->authType);
2282 hddLog(LOGW,FL("RSN/WPALen=%d, Uapsd = %d"),
2283 (int)pConfig->RSNWPAReqIELength, pConfig->UapsdEnable);
2284 hddLog(LOGW,FL("ProtEnabled = %d, OBSSProtEnabled = %d"),
2285 pConfig->protEnabled, pConfig->obssProtEnabled);
Jeff Johnson295189b2012-06-20 16:38:30 -07002286
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302287 if(test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -07002288 {
2289 //Bss already started. just return.
2290 //TODO Probably it should update some beacon params.
2291 hddLog( LOGE, "Bss Already started...Ignore the request");
2292 EXIT();
2293 return 0;
2294 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302295
Jeff Johnson295189b2012-06-20 16:38:30 -07002296 pConfig->persona = pHostapdAdapter->device_mode;
2297
2298 pSapEventCallback = hdd_hostapd_SAPEventCB;
2299 if(WLANSAP_StartBss(pVosContext, pSapEventCallback, pConfig,
2300 (v_PVOID_t)pHostapdAdapter->dev) != VOS_STATUS_SUCCESS)
2301 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08002302 hddLog(LOGE,FL("SAP Start Bss fail"));
Jeff Johnson295189b2012-06-20 16:38:30 -07002303 return -EINVAL;
2304 }
2305
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302306 hddLog(LOG1,
Jeff Johnson295189b2012-06-20 16:38:30 -07002307 FL("Waiting for Scan to complete(auto mode) and BSS to start"));
2308
2309 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302310
Jeff Johnson295189b2012-06-20 16:38:30 -07002311 if (!VOS_IS_STATUS_SUCCESS(status))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302312 {
2313 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08002314 ("ERROR: HDD vos wait for single_event failed!!"));
Tushnim Bhattacharyyaad37df12013-10-02 12:01:33 -07002315 smeGetCommandQStatus(hHal);
Jeff Johnson295189b2012-06-20 16:38:30 -07002316 VOS_ASSERT(0);
2317 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302318
Jeff Johnson295189b2012-06-20 16:38:30 -07002319 set_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags);
2320
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07002321#ifdef WLAN_FEATURE_P2P_DEBUG
2322 if (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO)
2323 {
2324 if(globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED)
2325 {
2326 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
2327 hddLog(LOGE,"[P2P State] From Go nego completed to "
Jeff Johnson1250df42012-12-10 14:31:52 -08002328 "Non-autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07002329 }
2330 else if(globalP2PConnectionStatus == P2P_NOT_ACTIVE)
2331 {
2332 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
2333 hddLog(LOGE,"[P2P State] From Inactive to "
Jeff Johnson1250df42012-12-10 14:31:52 -08002334 "Autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07002335 }
2336 }
2337#endif
2338
Jeff Johnson295189b2012-06-20 16:38:30 -07002339 pHostapdState->bCommit = TRUE;
2340 EXIT();
2341
2342 return 0;
2343}
2344
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002345#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302346static int wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy,
2347 struct net_device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -07002348 struct beacon_parameters *params)
2349{
2350 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302351 hdd_context_t *pHddCtx;
2352 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07002353
2354 ENTER();
2355
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302356 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2357 TRACE_CODE_HDD_CFG80211_ADD_BEACON,
2358 pAdapter->sessionId, params->interval));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05302359 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "device mode=%s (%d)",
2360 hdd_device_modetoString(pAdapter->device_mode),
2361 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07002362
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302363 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2364 status = wlan_hdd_validate_context(pHddCtx);
2365
2366 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002367 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302368 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2369 "%s: HDD context is not valid", __func__);
2370 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002371 }
2372
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302373 if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07002374 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07002375 )
2376 {
2377 beacon_data_t *old,*new;
2378
2379 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302380
Jeff Johnson295189b2012-06-20 16:38:30 -07002381 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302382 {
2383 hddLog(VOS_TRACE_LEVEL_WARN,
2384 FL("already beacon info added to session(%d)"),
2385 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07002386 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302387 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002388
2389 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
2390
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302391 if(status != VOS_STATUS_SUCCESS)
Jeff Johnson295189b2012-06-20 16:38:30 -07002392 {
2393 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08002394 "%s:Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002395 return -EINVAL;
2396 }
2397
2398 pAdapter->sessionCtx.ap.beacon = new;
2399
2400 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
2401 }
2402
2403 EXIT();
2404 return status;
2405}
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302406
2407static int wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07002408 struct net_device *dev,
2409 struct beacon_parameters *params)
2410{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302411 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302412 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302413 hdd_context_t *pHddCtx;
2414 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07002415
2416 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302417 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2418 TRACE_CODE_HDD_CFG80211_SET_BEACON,
2419 pAdapter->sessionId, pHddStaCtx->conn_info.authType));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05302420 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
2421 __func__, hdd_device_modetoString(pAdapter->device_mode),
2422 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07002423
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302424 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2425 status = wlan_hdd_validate_context(pHddCtx);
2426
2427 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002428 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302429 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2430 "%s: HDD context is not valid", __func__);
2431 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002432 }
2433
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302434 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07002435 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302436 )
Jeff Johnson295189b2012-06-20 16:38:30 -07002437 {
2438 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302439
Jeff Johnson295189b2012-06-20 16:38:30 -07002440 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302441
Jeff Johnson295189b2012-06-20 16:38:30 -07002442 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302443 {
2444 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2445 FL("session(%d) old and new heads points to NULL"),
2446 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07002447 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302448 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002449
2450 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
2451
2452 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302453 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08002454 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002455 return -EINVAL;
2456 }
2457
2458 pAdapter->sessionCtx.ap.beacon = new;
2459
2460 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
2461 }
2462
2463 EXIT();
2464 return status;
2465}
2466
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002467#endif //(LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
2468
2469#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07002470static int wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy,
2471 struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002472#else
2473static int wlan_hdd_cfg80211_stop_ap (struct wiphy *wiphy,
2474 struct net_device *dev)
2475#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07002476{
2477 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnsone7245742012-09-05 17:12:55 -07002478 hdd_context_t *pHddCtx = NULL;
2479 hdd_scaninfo_t *pScanInfo = NULL;
2480 hdd_adapter_t *staAdapter = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302481 VOS_STATUS status;
Jeff Johnson295189b2012-06-20 16:38:30 -07002482
2483 ENTER();
2484
2485 if (NULL == pAdapter)
2486 {
2487 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002488 "%s: HDD adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002489 return -ENODEV;
2490 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07002491
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302492 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2493 TRACE_CODE_HDD_CFG80211_STOP_AP,
2494 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302495 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2496 status = wlan_hdd_validate_context(pHddCtx);
2497
2498 if (0 != status)
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07002499 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302500 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2501 "%s: HDD context is not valid", __func__);
2502 return status;
Jeff Johnson4416a782013-03-25 14:17:50 -07002503 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07002504
2505 staAdapter = hdd_get_adapter(pAdapter->pHddCtx, WLAN_HDD_INFRA_STATION);
2506 if (NULL == staAdapter)
2507 {
2508 staAdapter = hdd_get_adapter(pAdapter->pHddCtx, WLAN_HDD_P2P_CLIENT);
2509 if (NULL == staAdapter)
2510 {
Rajesh Chauhan52d885b2013-11-01 10:54:25 -07002511 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
2512 "%s: HDD adapter context for STA/P2P-CLI is Null",
2513 __func__);
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07002514 }
2515 }
2516
2517 pScanInfo = &pHddCtx->scan_info;
2518
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05302519 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
2520 __func__, hdd_device_modetoString(pAdapter->device_mode),
2521 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07002522
Rajesh Chauhan52d885b2013-11-01 10:54:25 -07002523 if ((pScanInfo != NULL) && pScanInfo->mScanPending && staAdapter)
Jeff Johnsone7245742012-09-05 17:12:55 -07002524 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302525 long ret;
2526
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -08002527 INIT_COMPLETION(pScanInfo->abortscan_event_var);
Srinivas, Dasari138af4f2014-02-07 11:13:45 +05302528 hdd_abort_mac_scan(staAdapter->pHddCtx, pAdapter->sessionId,
2529 eCSR_SCAN_ABORT_DEFAULT);
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302530 ret = wait_for_completion_interruptible_timeout(
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -08002531 &pScanInfo->abortscan_event_var,
Jeff Johnsone7245742012-09-05 17:12:55 -07002532 msecs_to_jiffies(WLAN_WAIT_TIME_ABORTSCAN));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302533 if (ret <= 0)
Jeff Johnsone7245742012-09-05 17:12:55 -07002534 {
Rajesh Chauhan52d885b2013-11-01 10:54:25 -07002535 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302536 FL("Timeout occurred while waiting for abortscan %ld"),
2537 ret);
Yue Ma4f55ef32014-01-23 16:45:33 -08002538
2539 if (pHddCtx->isLogpInProgress)
2540 {
2541 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2542 "%s: LOGP in Progress. Ignore!!!", __func__);
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302543
2544 VOS_ASSERT(pScanInfo->mScanPending);
Yue Ma4f55ef32014-01-23 16:45:33 -08002545 return -EAGAIN;
2546 }
Jeff Johnsone7245742012-09-05 17:12:55 -07002547 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -07002548 }
2549 }
2550
Arun Kumar Khandavallia3bd8002014-01-17 16:21:19 +05302551 hdd_hostapd_stop(dev);
2552
Jeff Johnson295189b2012-06-20 16:38:30 -07002553 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07002554 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07002555 )
2556 {
2557 beacon_data_t *old;
2558
2559 old = pAdapter->sessionCtx.ap.beacon;
2560
2561 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302562 {
2563 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2564 FL("session(%d) beacon data points to NULL"),
2565 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07002566 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302567 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002568
Jeff Johnson295189b2012-06-20 16:38:30 -07002569 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07002570
2571 mutex_lock(&pHddCtx->sap_lock);
2572 if(test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
2573 {
Jeff Johnson4416a782013-03-25 14:17:50 -07002574 if ( VOS_STATUS_SUCCESS == (status = WLANSAP_StopBss(pHddCtx->pvosContext) ) )
Jeff Johnson295189b2012-06-20 16:38:30 -07002575 {
2576 hdd_hostapd_state_t *pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
2577
2578 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
2579
2580 if (!VOS_IS_STATUS_SUCCESS(status))
2581 {
2582 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08002583 ("ERROR: HDD vos wait for single_event failed!!"));
Jeff Johnson295189b2012-06-20 16:38:30 -07002584 VOS_ASSERT(0);
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302585 }
2586 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002587 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
2588 }
2589 mutex_unlock(&pHddCtx->sap_lock);
2590
2591 if(status != VOS_STATUS_SUCCESS)
2592 {
2593 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08002594 "%s:Error!!! Stopping the BSS",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002595 return -EINVAL;
2596 }
2597
Jeff Johnson4416a782013-03-25 14:17:50 -07002598 if (ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -07002599 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 0,NULL, eANI_BOOLEAN_FALSE)
2600 ==eHAL_STATUS_FAILURE)
2601 {
2602 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08002603 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07002604 }
2605
Jeff Johnson4416a782013-03-25 14:17:50 -07002606 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -07002607 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
2608 eANI_BOOLEAN_FALSE) )
2609 {
2610 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08002611 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07002612 }
2613
2614 // Reset WNI_CFG_PROBE_RSP Flags
2615 wlan_hdd_reset_prob_rspies(pAdapter);
2616
2617 pAdapter->sessionCtx.ap.beacon = NULL;
2618 kfree(old);
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07002619#ifdef WLAN_FEATURE_P2P_DEBUG
2620 if((pAdapter->device_mode == WLAN_HDD_P2P_GO) &&
2621 (globalP2PConnectionStatus == P2P_GO_COMPLETED_STATE))
2622 {
2623 hddLog(LOGE,"[P2P State] From GO completed to Inactive state "
2624 "GO got removed");
2625 globalP2PConnectionStatus = P2P_NOT_ACTIVE;
2626 }
2627#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07002628 }
2629 EXIT();
2630 return status;
2631}
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002632
2633#if (LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
2634
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302635static int wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
2636 struct net_device *dev,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002637 struct cfg80211_ap_settings *params)
2638{
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302639 hdd_adapter_t *pAdapter;
2640 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302641 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002642
2643 ENTER();
2644
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302645 if (NULL == dev)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07002646 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302647 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302648 "%s: Device is Null", __func__);
2649 return -ENODEV;
2650 }
2651
2652 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2653 if (NULL == pAdapter)
2654 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302655 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302656 "%s: HDD adapter is Null", __func__);
2657 return -ENODEV;
2658 }
2659
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302660 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2661 TRACE_CODE_HDD_CFG80211_START_AP, pAdapter->sessionId,
2662 params-> beacon_interval));
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302663 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
2664 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302665 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302666 "%s: HDD adapter magic is invalid", __func__);
2667 return -ENODEV;
2668 }
2669
2670 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302671 status = wlan_hdd_validate_context(pHddCtx);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302672
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302673 if (0 != status)
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302674 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302675 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2676 "%s: HDD context is not valid", __func__);
2677 return status;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302678 }
2679
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05302680 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device mode = %s (%d)",
2681 __func__, hdd_device_modetoString(pAdapter->device_mode),
2682 pAdapter->device_mode);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302683
2684 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002685 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002686 )
2687 {
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302688 beacon_data_t *old, *new;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002689
2690 old = pAdapter->sessionCtx.ap.beacon;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302691
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002692 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302693 {
2694 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
2695 FL("already beacon info added to session(%d)"),
2696 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002697 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302698 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002699
2700 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter, &new, &params->beacon, params->dtim_period);
2701
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302702 if (status != 0)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002703 {
2704 hddLog(VOS_TRACE_LEVEL_FATAL,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302705 "%s:Error!!! Allocating the new beacon", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002706 return -EINVAL;
2707 }
2708 pAdapter->sessionCtx.ap.beacon = new;
Viral Modi3a32cc52013-02-08 11:14:52 -08002709#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
Yue Maf49ba872013-08-19 12:04:25 -07002710 wlan_hdd_cfg80211_set_channel(wiphy, dev,
2711#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
2712 params->channel, params->channel_type);
2713#else
2714 params->chandef.chan, cfg80211_get_chandef_type(&(params->chandef)));
2715#endif
Viral Modi3a32cc52013-02-08 11:14:52 -08002716#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002717 status = wlan_hdd_cfg80211_start_bss(pAdapter, &params->beacon, params->ssid,
2718 params->ssid_len, params->hidden_ssid);
2719 }
2720
2721 EXIT();
2722 return status;
2723}
2724
2725
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302726static int wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002727 struct net_device *dev,
2728 struct cfg80211_beacon_data *params)
2729{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302730 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302731 hdd_context_t *pHddCtx;
2732 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002733
2734 ENTER();
2735
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302736 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2737 TRACE_CODE_HDD_CFG80211_CHANGE_BEACON,
2738 pAdapter->sessionId, pAdapter->device_mode));
Arif Hussain6d2a3322013-11-17 19:50:10 -08002739 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002740 __func__, pAdapter->device_mode);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302741
2742 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2743 status = wlan_hdd_validate_context(pHddCtx);
2744
2745 if (0 != status)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07002746 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302747 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2748 "%s: HDD context is not valid", __func__);
2749 return status;
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07002750 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002751
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302752 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002753 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302754 )
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002755 {
2756 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302757
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002758 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302759
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002760 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302761 {
2762 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2763 FL("session(%d) beacon data points to NULL"),
2764 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002765 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302766 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002767
2768 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter, &new, params, 0);
2769
2770 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302771 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08002772 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002773 return -EINVAL;
2774 }
2775
2776 pAdapter->sessionCtx.ap.beacon = new;
2777
2778 status = wlan_hdd_cfg80211_start_bss(pAdapter, params, NULL, 0, 0);
2779 }
2780
2781 EXIT();
2782 return status;
2783}
2784
2785#endif //(LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
2786
Jeff Johnson295189b2012-06-20 16:38:30 -07002787
2788static int wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
2789 struct net_device *dev,
2790 struct bss_parameters *params)
2791{
2792 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2793
2794 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302795
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302796 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2797 TRACE_CODE_HDD_CFG80211_CHANGE_BSS,
2798 pAdapter->sessionId, params->ap_isolate));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05302799 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
2800 __func__, hdd_device_modetoString(pAdapter->device_mode),
2801 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07002802
2803 if((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07002804 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302805 )
Jeff Johnson295189b2012-06-20 16:38:30 -07002806 {
2807 /* ap_isolate == -1 means that in change bss, upper layer doesn't
2808 * want to update this parameter */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302809 if (-1 != params->ap_isolate)
Jeff Johnson295189b2012-06-20 16:38:30 -07002810 {
2811 pAdapter->sessionCtx.ap.apDisableIntraBssFwd = !!params->ap_isolate;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302812 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002813 }
2814
2815 EXIT();
2816 return 0;
2817}
2818
Kiet Lam10841362013-11-01 11:36:50 +05302819/* FUNCTION: wlan_hdd_change_country_code_cd
2820* to wait for contry code completion
2821*/
2822void* wlan_hdd_change_country_code_cb(void *pAdapter)
2823{
2824 hdd_adapter_t *call_back_pAdapter = pAdapter;
2825 complete(&call_back_pAdapter->change_country_code);
2826 return NULL;
2827}
2828
Jeff Johnson295189b2012-06-20 16:38:30 -07002829/*
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +05302830 * FUNCTION: __wlan_hdd_cfg80211_change_iface
Jeff Johnson295189b2012-06-20 16:38:30 -07002831 * This function is used to set the interface type (INFRASTRUCTURE/ADHOC)
2832 */
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +05302833int __wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07002834 struct net_device *ndev,
2835 enum nl80211_iftype type,
2836 u32 *flags,
2837 struct vif_params *params
2838 )
2839{
2840 struct wireless_dev *wdev;
2841 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Rajesh Chauhana0516c62014-01-30 16:11:18 -08002842 hdd_context_t *pHddCtx;
Mohit Khanna0f232092012-09-11 14:46:08 -07002843 hdd_adapter_t *pP2pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07002844 tCsrRoamProfile *pRoamProfile = NULL;
2845 eCsrRoamBssType LastBSSType;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302846 hdd_config_t *pConfig = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07002847 eMib_dot11DesiredBssType connectedBssType;
2848 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302849 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07002850
2851 ENTER();
2852
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302853 if (!pAdapter)
Rajesh Chauhana0516c62014-01-30 16:11:18 -08002854 {
2855 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2856 "%s: Adapter context is null", __func__);
2857 return VOS_STATUS_E_FAILURE;
2858 }
2859
2860 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2861 if (!pHddCtx)
2862 {
2863 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2864 "%s: HDD context is null", __func__);
2865 return VOS_STATUS_E_FAILURE;
2866 }
2867
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302868 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2869 TRACE_CODE_HDD_CFG80211_CHANGE_IFACE,
2870 pAdapter->sessionId, type));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302871 status = wlan_hdd_validate_context(pHddCtx);
2872
2873 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -07002874 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302875 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2876 "%s: HDD context is not valid", __func__);
2877 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -07002878 }
2879
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05302880 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
2881 __func__, hdd_device_modetoString(pAdapter->device_mode),
2882 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07002883
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302884 pConfig = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -07002885 wdev = ndev->ieee80211_ptr;
2886
2887#ifdef WLAN_BTAMP_FEATURE
2888 if((NL80211_IFTYPE_P2P_CLIENT == type)||
2889 (NL80211_IFTYPE_ADHOC == type)||
2890 (NL80211_IFTYPE_AP == type)||
2891 (NL80211_IFTYPE_P2P_GO == type))
2892 {
2893 pHddCtx->isAmpAllowed = VOS_FALSE;
2894 // stop AMP traffic
2895 status = WLANBAP_StopAmp();
2896 if(VOS_STATUS_SUCCESS != status )
2897 {
2898 pHddCtx->isAmpAllowed = VOS_TRUE;
2899 hddLog(VOS_TRACE_LEVEL_FATAL,
2900 "%s: Failed to stop AMP", __func__);
2901 return -EINVAL;
2902 }
2903 }
2904#endif //WLAN_BTAMP_FEATURE
2905 /* Reset the current device mode bit mask*/
2906 wlan_hdd_clear_concurrency_mode(pHddCtx, pAdapter->device_mode);
2907
2908 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -07002909 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnsone7245742012-09-05 17:12:55 -07002910 || (pAdapter->device_mode == WLAN_HDD_P2P_DEVICE)
Jeff Johnson295189b2012-06-20 16:38:30 -07002911 )
2912 {
2913 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -08002914 if (!pWextState)
2915 {
2916 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2917 "%s: pWextState is null", __func__);
2918 return VOS_STATUS_E_FAILURE;
2919 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002920 pRoamProfile = &pWextState->roamProfile;
2921 LastBSSType = pRoamProfile->BSSType;
2922
2923 switch (type)
2924 {
2925 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -07002926 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -07002927 hddLog(VOS_TRACE_LEVEL_INFO,
2928 "%s: setting interface Type to INFRASTRUCTURE", __func__);
2929 pRoamProfile->BSSType = eCSR_BSS_TYPE_INFRASTRUCTURE;
Jeff Johnsone7245742012-09-05 17:12:55 -07002930#ifdef WLAN_FEATURE_11AC
2931 if(pConfig->dot11Mode == eHDD_DOT11_MODE_AUTO)
2932 {
2933 pConfig->dot11Mode = eHDD_DOT11_MODE_11ac;
2934 }
2935#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302936 pRoamProfile->phyMode =
Jeff Johnsone7245742012-09-05 17:12:55 -07002937 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07002938 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08002939 //Check for sub-string p2p to confirm its a p2p interface
2940 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302941 {
Gopichand Nakkala864d3552012-12-31 16:08:51 -08002942 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
2943 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
2944 }
2945 else
2946 {
2947 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -07002948 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -08002949 }
Madan Mohan Koyyalamudi81746922013-07-17 14:38:51 +05302950#ifdef FEATURE_WLAN_TDLS
2951 /* The open adapter for the p2p shall skip initializations in
2952 * tdls_init if the device mode is WLAN_HDD_P2P_DEVICE, for
2953 * TDLS is supported only on WLAN_HDD_P2P_CLIENT. Hence invoke
2954 * tdls_init when the change_iface sets the device mode to
2955 * WLAN_HDD_P2P_CLIENT.
2956 */
2957
2958 if ( pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
2959 {
2960 if (0 != wlan_hdd_tdls_init (pAdapter))
2961 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302962 hddLog(VOS_TRACE_LEVEL_ERROR,
2963 "%s: tdls initialization failed", __func__);
Madan Mohan Koyyalamudi81746922013-07-17 14:38:51 +05302964 return -EINVAL;
2965 }
2966 }
2967#endif
2968
Jeff Johnson295189b2012-06-20 16:38:30 -07002969 break;
2970 case NL80211_IFTYPE_ADHOC:
2971 hddLog(VOS_TRACE_LEVEL_INFO,
2972 "%s: setting interface Type to ADHOC", __func__);
2973 pRoamProfile->BSSType = eCSR_BSS_TYPE_START_IBSS;
2974 pRoamProfile->phyMode =
2975 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Shailender Karmuchia734f332013-04-19 14:02:48 -07002976 pAdapter->device_mode = WLAN_HDD_IBSS;
Jeff Johnson295189b2012-06-20 16:38:30 -07002977 wdev->iftype = type;
2978 break;
2979
2980 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -07002981 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07002982 {
2983 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
2984 "%s: setting interface Type to %s", __func__,
2985 (type == NL80211_IFTYPE_AP) ? "SoftAP" : "P2pGo");
2986
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08002987 //Cancel any remain on channel for GO mode
2988 if (NL80211_IFTYPE_P2P_GO == type)
2989 {
2990 wlan_hdd_cancel_existing_remain_on_channel(pAdapter);
2991 }
Mohit Khanna0f232092012-09-11 14:46:08 -07002992 if (NL80211_IFTYPE_AP == type)
2993 {
2994 /* As Loading WLAN Driver one interface being created for p2p device
2995 * address. This will take one HW STA and the max number of clients
2996 * that can connect to softAP will be reduced by one. so while changing
2997 * the interface type to NL80211_IFTYPE_AP (SoftAP) remove p2p0
2998 * interface as it is not required in SoftAP mode.
2999 */
3000
3001 // Get P2P Adapter
3002 pP2pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_DEVICE);
3003
3004 if (pP2pAdapter)
3005 {
3006 hdd_stop_adapter(pHddCtx, pP2pAdapter);
3007 hdd_deinit_adapter(pHddCtx, pP2pAdapter);
3008 hdd_close_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
3009 }
3010 }
Swaroop Goltia2e32212014-04-09 23:37:33 +05303011 //Disable IMPS & BMPS for SAP/GO
3012 if(VOS_STATUS_E_FAILURE ==
3013 hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_P2P_GO))
3014 {
3015 //Fail to Exit BMPS
3016 VOS_ASSERT(0);
3017 }
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05303018#ifdef FEATURE_WLAN_TDLS
Mohit Khanna0f232092012-09-11 14:46:08 -07003019
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05303020 /* A Mutex Lock is introduced while changing the mode to
3021 * protect the concurrent access for the Adapters by TDLS
3022 * module.
3023 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05303024 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05303025#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07003026 //De-init the adapter.
3027 hdd_stop_adapter( pHddCtx, pAdapter );
3028 hdd_deinit_adapter( pHddCtx, pAdapter );
3029 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
Jeff Johnson295189b2012-06-20 16:38:30 -07003030 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
3031 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05303032#ifdef FEATURE_WLAN_TDLS
3033 mutex_unlock(&pHddCtx->tdls_lock);
3034#endif
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -07003035 if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) &&
3036 (pConfig->apRandomBssidEnabled))
3037 {
3038 /* To meet Android requirements create a randomized
3039 MAC address of the form 02:1A:11:Fx:xx:xx */
3040 get_random_bytes(&ndev->dev_addr[3], 3);
3041 ndev->dev_addr[0] = 0x02;
3042 ndev->dev_addr[1] = 0x1A;
3043 ndev->dev_addr[2] = 0x11;
3044 ndev->dev_addr[3] |= 0xF0;
3045 memcpy(pAdapter->macAddressCurrent.bytes, ndev->dev_addr,
3046 VOS_MAC_ADDR_SIZE);
Arif Hussain24bafea2013-11-15 15:10:03 -08003047 pr_info("wlan: Generated HotSpot BSSID " MAC_ADDRESS_STR"\n",
3048 MAC_ADDR_ARRAY(ndev->dev_addr));
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -07003049 }
3050
Jeff Johnson295189b2012-06-20 16:38:30 -07003051 hdd_set_ap_ops( pAdapter->dev );
3052
Kiet Lam10841362013-11-01 11:36:50 +05303053 /* This is for only SAP mode where users can
3054 * control country through ini.
3055 * P2P GO follows station country code
3056 * acquired during the STA scanning. */
3057 if((NL80211_IFTYPE_AP == type) &&
3058 (memcmp(pConfig->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0))
3059 {
3060 int status = 0;
3061 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_INFO,
3062 "%s: setting country code from INI ", __func__);
3063 init_completion(&pAdapter->change_country_code);
3064 status = (int)sme_ChangeCountryCode(pHddCtx->hHal,
3065 (void *)(tSmeChangeCountryCallback)
3066 wlan_hdd_change_country_code_cb,
3067 pConfig->apCntryCode, pAdapter,
3068 pHddCtx->pvosContext,
Abhishek Singha306a442013-11-07 18:39:01 +05303069 eSIR_FALSE,
3070 eSIR_TRUE);
Kiet Lam10841362013-11-01 11:36:50 +05303071 if (eHAL_STATUS_SUCCESS == status)
3072 {
3073 /* Wait for completion */
c_hpothu6ff1c3c2013-10-01 19:01:57 +05303074 ret = wait_for_completion_interruptible_timeout(
Kiet Lam10841362013-11-01 11:36:50 +05303075 &pAdapter->change_country_code,
3076 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05303077 if (ret <= 0)
Kiet Lam10841362013-11-01 11:36:50 +05303078 {
3079 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05303080 FL("SME Timed out while setting country code %ld"),
3081 ret);
Yue Ma4f55ef32014-01-23 16:45:33 -08003082
3083 if (pHddCtx->isLogpInProgress)
3084 {
3085 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3086 "%s: LOGP in Progress. Ignore!!!", __func__);
3087 return -EAGAIN;
3088 }
Kiet Lam10841362013-11-01 11:36:50 +05303089 }
3090 }
3091 else
3092 {
3093 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08003094 "%s: SME Change Country code failed",__func__);
Kiet Lam10841362013-11-01 11:36:50 +05303095 return -EINVAL;
3096 }
3097 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003098 status = hdd_init_ap_mode(pAdapter);
3099 if(status != VOS_STATUS_SUCCESS)
3100 {
3101 hddLog(VOS_TRACE_LEVEL_FATAL,
3102 "%s: Error initializing the ap mode", __func__);
3103 return -EINVAL;
3104 }
3105 hdd_set_conparam(1);
3106
Jeff Johnson295189b2012-06-20 16:38:30 -07003107 /*interface type changed update in wiphy structure*/
3108 if(wdev)
3109 {
3110 wdev->iftype = type;
3111 pHddCtx->change_iface = type;
3112 }
3113 else
3114 {
3115 hddLog(VOS_TRACE_LEVEL_ERROR,
3116 "%s: ERROR !!!! Wireless dev is NULL", __func__);
3117 return -EINVAL;
3118 }
3119 goto done;
3120 }
3121
3122 default:
3123 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
3124 __func__);
3125 return -EOPNOTSUPP;
3126 }
3127 }
3128 else if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07003129 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07003130 )
3131 {
3132 switch(type)
3133 {
3134 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -07003135 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -07003136 case NL80211_IFTYPE_ADHOC:
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05303137#ifdef FEATURE_WLAN_TDLS
3138
3139 /* A Mutex Lock is introduced while changing the mode to
3140 * protect the concurrent access for the Adapters by TDLS
3141 * module.
3142 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05303143 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05303144#endif
Jeff Johnson32d95a32012-09-10 13:15:23 -07003145 hdd_stop_adapter( pHddCtx, pAdapter );
3146 hdd_deinit_adapter( pHddCtx, pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07003147 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08003148 //Check for sub-string p2p to confirm its a p2p interface
3149 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala864d3552012-12-31 16:08:51 -08003150 {
3151 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
3152 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
3153 }
3154 else
3155 {
3156 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -07003157 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -08003158 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003159 hdd_set_conparam(0);
3160 pHddCtx->change_iface = type;
Jeff Johnson295189b2012-06-20 16:38:30 -07003161 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
3162 hdd_set_station_ops( pAdapter->dev );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05303163#ifdef FEATURE_WLAN_TDLS
3164 mutex_unlock(&pHddCtx->tdls_lock);
3165#endif
Sunil Dutt66485cb2013-12-19 19:05:03 +05303166 status = hdd_init_station_mode( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07003167 if( VOS_STATUS_SUCCESS != status )
3168 return -EOPNOTSUPP;
Jeff Johnsone7245742012-09-05 17:12:55 -07003169 /* In case of JB, for P2P-GO, only change interface will be called,
3170 * This is the right place to enable back bmps_imps()
3171 */
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05303172 if (pHddCtx->hdd_wlan_suspended)
3173 {
3174 hdd_set_pwrparams(pHddCtx);
3175 }
Jeff Johnsone7245742012-09-05 17:12:55 -07003176 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07003177 goto done;
3178 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -07003179 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07003180 wdev->iftype = type;
Jeff Johnson295189b2012-06-20 16:38:30 -07003181 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
3182 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Jeff Johnson295189b2012-06-20 16:38:30 -07003183 goto done;
3184 default:
3185 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
3186 __func__);
3187 return -EOPNOTSUPP;
3188
3189 }
3190
3191 }
3192 else
3193 {
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05303194 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: unsupported device mode(%s (%d))",
3195 __func__, hdd_device_modetoString(pAdapter->device_mode),
3196 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07003197 return -EOPNOTSUPP;
3198 }
3199
3200
3201 if(pRoamProfile)
3202 {
3203 if ( LastBSSType != pRoamProfile->BSSType )
3204 {
3205 /*interface type changed update in wiphy structure*/
3206 wdev->iftype = type;
3207
3208 /*the BSS mode changed, We need to issue disconnect
3209 if connected or in IBSS disconnect state*/
3210 if ( hdd_connGetConnectedBssType(
3211 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), &connectedBssType ) ||
3212 ( eCSR_BSS_TYPE_START_IBSS == LastBSSType ) )
3213 {
3214 /*need to issue a disconnect to CSR.*/
3215 INIT_COMPLETION(pAdapter->disconnect_comp_var);
3216 if( eHAL_STATUS_SUCCESS ==
3217 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
3218 pAdapter->sessionId,
3219 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
3220 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05303221 ret = wait_for_completion_interruptible_timeout(
3222 &pAdapter->disconnect_comp_var,
3223 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
3224 if (ret <= 0)
3225 {
3226 hddLog(VOS_TRACE_LEVEL_ERROR,
3227 FL("wait on disconnect_comp_var failed %ld"), ret);
3228 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003229 }
3230 }
3231 }
3232 }
3233
3234done:
3235 /*set bitmask based on updated value*/
3236 wlan_hdd_set_concurrency_mode(pHddCtx, pAdapter->device_mode);
Leo Chang6fe1f922013-06-07 19:21:24 -07003237
3238 /* Only STA mode support TM now
3239 * all other mode, TM feature should be disabled */
3240 if ( (pHddCtx->cfg_ini->thermalMitigationEnable) &&
3241 (~VOS_STA & pHddCtx->concurrency_mode) )
3242 {
3243 hddDevTmLevelChangedHandler(pHddCtx->parent_dev, 0);
3244 }
3245
Jeff Johnson295189b2012-06-20 16:38:30 -07003246#ifdef WLAN_BTAMP_FEATURE
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303247 if((NL80211_IFTYPE_STATION == type) && (pHddCtx->concurrency_mode <= 1) &&
Jeff Johnson295189b2012-06-20 16:38:30 -07003248 (pHddCtx->no_of_sessions[WLAN_HDD_INFRA_STATION] <=1))
3249 {
3250 //we are ok to do AMP
3251 pHddCtx->isAmpAllowed = VOS_TRUE;
3252 }
3253#endif //WLAN_BTAMP_FEATURE
3254 EXIT();
3255 return 0;
3256}
3257
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +05303258/*
3259 * FUNCTION: wlan_hdd_cfg80211_change_iface
3260 * wrapper function to protect the actual implementation from SSR.
3261 */
3262int wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
3263 struct net_device *ndev,
3264 enum nl80211_iftype type,
3265 u32 *flags,
3266 struct vif_params *params
3267 )
3268{
3269 int ret;
3270
3271 vos_ssr_protect(__func__);
3272 ret = __wlan_hdd_cfg80211_change_iface(wiphy, ndev, type, flags, params);
3273 vos_ssr_unprotect(__func__);
3274
3275 return ret;
3276}
3277
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003278#ifdef FEATURE_WLAN_TDLS
3279static int wlan_hdd_tdls_add_station(struct wiphy *wiphy,
3280 struct net_device *dev, u8 *mac, bool update, tCsrStaParams *StaParams)
3281{
3282 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3283 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3284 VOS_STATUS status;
Hoonki Lee5305c3a2013-04-29 23:28:59 -07003285 hddTdlsPeer_t *pTdlsPeer;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05303286 long ret;
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05303287 tANI_U16 numCurrTdlsPeers;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003288
3289 ENTER();
3290
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05303291 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003292 {
3293 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3294 "Invalid arguments");
3295 return -EINVAL;
3296 }
Hoonki Lee27511902013-03-14 18:19:06 -07003297
3298 if ((eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode) ||
3299 (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode))
3300 {
3301 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
3302 "%s: TDLS mode is disabled OR not enabled in FW."
3303 MAC_ADDRESS_STR " Request declined.",
3304 __func__, MAC_ADDR_ARRAY(mac));
3305 return -ENOTSUPP;
3306 }
3307
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003308 if (pHddCtx->isLogpInProgress)
3309 {
3310 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3311 "%s:LOGP in Progress. Ignore!!!", __func__);
Gopichand Nakkala05922802013-03-14 12:23:19 -07003312 wlan_hdd_tdls_set_link_status(pAdapter, mac, eTDLS_LINK_IDLE);
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003313 return -EBUSY;
3314 }
3315
Naresh Jayaram9c6f4462014-02-13 12:20:31 +05303316 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, mac);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07003317
3318 if ( NULL == pTdlsPeer ) {
3319 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
3320 "%s: " MAC_ADDRESS_STR " (update %d) not exist. return invalid",
3321 __func__, MAC_ADDR_ARRAY(mac), update);
3322 return -EINVAL;
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07003323 }
Hoonki Lee5305c3a2013-04-29 23:28:59 -07003324
3325 /* in add station, we accept existing valid staId if there is */
3326 if ((0 == update) &&
3327 ((pTdlsPeer->link_status >= eTDLS_LINK_CONNECTING) ||
3328 (TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003329 {
Hoonki Lee5305c3a2013-04-29 23:28:59 -07003330 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003331 "%s: " MAC_ADDRESS_STR
Hoonki Lee5305c3a2013-04-29 23:28:59 -07003332 " link_status %d. staId %d. add station ignored.",
3333 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, pTdlsPeer->staId);
3334 return 0;
3335 }
3336 /* in change station, we accept only when staId is valid */
3337 if ((1 == update) &&
3338 ((pTdlsPeer->link_status > eTDLS_LINK_CONNECTING) ||
3339 (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
3340 {
3341 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
3342 "%s: " MAC_ADDRESS_STR
3343 " link status %d. staId %d. change station %s.",
3344 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, pTdlsPeer->staId,
3345 (TDLS_STA_INDEX_VALID(pTdlsPeer->staId)) ? "ignored" : "declined");
3346 return (TDLS_STA_INDEX_VALID(pTdlsPeer->staId)) ? 0 : -EPERM;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003347 }
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07003348
3349 /* when others are on-going, we want to change link_status to idle */
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05303350 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, mac, TRUE))
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003351 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07003352 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3353 "%s: " MAC_ADDRESS_STR
3354 " TDLS setup is ongoing. Request declined.",
3355 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala05922802013-03-14 12:23:19 -07003356 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003357 }
3358
3359 /* first to check if we reached to maximum supported TDLS peer.
3360 TODO: for now, return -EPERM looks working fine,
3361 but need to check if any other errno fit into this category.*/
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05303362 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
3363 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003364 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07003365 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3366 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05303367 " TDLS Max peer already connected. Request declined."
3368 " Num of peers (%d), Max allowed (%d).",
3369 __func__, MAC_ADDR_ARRAY(mac), numCurrTdlsPeers,
3370 HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -07003371 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003372 }
3373 else
3374 {
3375 hddTdlsPeer_t *pTdlsPeer;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05303376 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, mac, TRUE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003377 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003378 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07003379 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3380 "%s: " MAC_ADDRESS_STR " already connected. Request declined.",
3381 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003382 return -EPERM;
3383 }
3384 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003385 if (0 == update)
3386 wlan_hdd_tdls_set_link_status(pAdapter, mac, eTDLS_LINK_CONNECTING);
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003387
Jeff Johnsond75fe012013-04-06 10:53:06 -07003388 /* debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05303389 if (NULL != StaParams)
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003390 {
3391 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
3392 "%s: TDLS Peer Parameters.", __func__);
Hoonki Lee66b75f32013-04-16 18:30:07 -07003393 if(StaParams->htcap_present)
3394 {
3395 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
3396 "ht_capa->cap_info: %0x", StaParams->HTCap.capInfo);
3397 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
3398 "ht_capa->extended_capabilities: %0x",
3399 StaParams->HTCap.extendedHtCapInfo);
3400 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003401 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
3402 "params->capability: %0x",StaParams->capability);
3403 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07003404 "params->ext_capab_len: %0x",StaParams->extn_capability[0]);
Hoonki Lee66b75f32013-04-16 18:30:07 -07003405 if(StaParams->vhtcap_present)
3406 {
3407 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
3408 "rxMcsMap %x rxHighest %x txMcsMap %x txHighest %x",
3409 StaParams->VHTCap.suppMcs.rxMcsMap, StaParams->VHTCap.suppMcs.rxHighest,
3410 StaParams->VHTCap.suppMcs.txMcsMap, StaParams->VHTCap.suppMcs.txHighest);
3411 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003412 {
3413 int i = 0;
Hoonki Lee5305c3a2013-04-29 23:28:59 -07003414 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "Supported rates:");
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003415 for (i = 0; i < sizeof(StaParams->supported_rates); i++)
3416 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
3417 "[%d]: %x ", i, StaParams->supported_rates[i]);
3418 }
Jeff Johnsond75fe012013-04-06 10:53:06 -07003419 } /* end debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05303420 else if ((1 == update) && (NULL == StaParams))
3421 {
3422 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3423 "%s : update is true, but staParams is NULL. Error!", __func__);
3424 return -EPERM;
3425 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003426
3427 INIT_COMPLETION(pAdapter->tdls_add_station_comp);
3428
3429 if (!update)
3430 {
3431 status = sme_AddTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
3432 pAdapter->sessionId, mac);
3433 }
3434 else
3435 {
3436 status = sme_ChangeTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
3437 pAdapter->sessionId, mac, StaParams);
3438 }
3439
c_hpothu6ff1c3c2013-10-01 19:01:57 +05303440 ret = wait_for_completion_interruptible_timeout(&pAdapter->tdls_add_station_comp,
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003441 msecs_to_jiffies(WAIT_TIME_TDLS_ADD_STA));
3442
c_hpothu6ff1c3c2013-10-01 19:01:57 +05303443 if (ret <= 0)
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003444 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07003445 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05303446 "%s: timeout waiting for tdls add station indication %ld",
3447 __func__, ret);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07003448 return -EPERM;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003449 }
c_hpothu6ff1c3c2013-10-01 19:01:57 +05303450
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003451 if ( eHAL_STATUS_SUCCESS != pAdapter->tdlsAddStaStatus)
3452 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07003453 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003454 "%s: Add Station is unsucessful", __func__);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07003455 return -EPERM;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003456 }
3457
3458 return 0;
Gopichand Nakkala05922802013-03-14 12:23:19 -07003459
3460error:
3461 wlan_hdd_tdls_set_link_status(pAdapter, mac, eTDLS_LINK_IDLE);
3462 return -EPERM;
3463
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003464}
3465#endif
3466
Jeff Johnson295189b2012-06-20 16:38:30 -07003467static int wlan_hdd_change_station(struct wiphy *wiphy,
3468 struct net_device *dev,
3469 u8 *mac,
3470 struct station_parameters *params)
3471{
3472 VOS_STATUS status = VOS_STATUS_SUCCESS;
3473 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Gopichand Nakkala29149562013-05-10 21:43:41 +05303474 hdd_context_t *pHddCtx;
3475 hdd_station_ctx_t *pHddStaCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07003476 v_MACADDR_t STAMacAddress;
Gopichand Nakkalab0856222013-03-12 22:39:05 -07003477#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003478 tCsrStaParams StaParams = {0};
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003479 tANI_U8 isBufSta = 0;
Naresh Jayaram3180aa42014-02-12 21:47:26 +05303480 tANI_U8 isOffChannelSupported = 0;
Gopichand Nakkalab0856222013-03-12 22:39:05 -07003481#endif
Jeff Johnsone7245742012-09-05 17:12:55 -07003482 ENTER();
3483
Gopichand Nakkala29149562013-05-10 21:43:41 +05303484 if ((NULL == pAdapter))
3485 {
3486 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
3487 "invalid adapter ");
3488 return -EINVAL;
3489 }
3490
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05303491 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
3492 TRACE_CODE_HDD_CHANGE_STATION,
3493 pAdapter->sessionId, params->listen_interval));
Gopichand Nakkala29149562013-05-10 21:43:41 +05303494 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
3495 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3496
3497 if ((NULL == pHddCtx) || (NULL == pHddStaCtx))
3498 {
3499 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
3500 "invalid HDD state or HDD station context");
3501 return -EINVAL;
3502 }
3503
3504 if (pHddCtx->isLogpInProgress)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07003505 {
3506 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3507 "%s:LOGP in Progress. Ignore!!!", __func__);
3508 return -EAGAIN;
3509 }
3510
Jeff Johnson295189b2012-06-20 16:38:30 -07003511 vos_mem_copy(STAMacAddress.bytes, mac, sizeof(v_MACADDR_t));
3512
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003513 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
3514 || (pAdapter->device_mode == WLAN_HDD_P2P_GO))
Jeff Johnson295189b2012-06-20 16:38:30 -07003515 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003516 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED))
Jeff Johnson295189b2012-06-20 16:38:30 -07003517 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303518 status = hdd_softap_change_STA_state( pAdapter, &STAMacAddress,
Jeff Johnson295189b2012-06-20 16:38:30 -07003519 WLANTL_STA_AUTHENTICATED);
3520
Gopichand Nakkala29149562013-05-10 21:43:41 +05303521 if (status != VOS_STATUS_SUCCESS)
3522 {
3523 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3524 "%s: Not able to change TL state to AUTHENTICATED", __func__);
3525 return -EINVAL;
3526 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003527 }
3528 }
Hoonki Leea6d49be2013-04-05 09:43:25 -07003529 else if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
3530 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)) {
Gopichand Nakkala29149562013-05-10 21:43:41 +05303531#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003532 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
3533 StaParams.capability = params->capability;
3534 StaParams.uapsd_queues = params->uapsd_queues;
3535 StaParams.max_sp = params->max_sp;
3536
Naresh Jayaram3180aa42014-02-12 21:47:26 +05303537 /* Convert (first channel , number of channels) tuple to
3538 * the total list of channels. This goes with the assumption
3539 * that if the first channel is < 14, then the next channels
3540 * are an incremental of 1 else an incremental of 4 till the number
3541 * of channels.
3542 */
3543 if (0 != params->supported_channels_len) {
3544 int i = 0,j = 0,k = 0, no_of_channels = 0 ;
3545 for ( i = 0 ; i < params->supported_channels_len ; i+=2)
3546 {
3547 int wifi_chan_index;
3548 StaParams.supported_channels[j] = params->supported_channels[i];
3549 wifi_chan_index =
3550 ((StaParams.supported_channels[j] <= HDD_CHANNEL_14 ) ? 1 : 4 );
3551 no_of_channels = params->supported_channels[i+1];
3552 for(k=1; k <= no_of_channels; k++)
3553 {
3554 StaParams.supported_channels[j+1] =
3555 StaParams.supported_channels[j] + wifi_chan_index;
3556 j+=1;
3557 }
3558 }
3559 StaParams.supported_channels_len = j;
3560 }
3561 vos_mem_copy(StaParams.supported_oper_classes,
3562 params->supported_oper_classes,
3563 params->supported_oper_classes_len);
3564 StaParams.supported_oper_classes_len =
3565 params->supported_oper_classes_len;
3566
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003567 if (0 != params->ext_capab_len)
3568 vos_mem_copy(StaParams.extn_capability, params->ext_capab,
3569 sizeof(StaParams.extn_capability));
3570
3571 if (NULL != params->ht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -07003572 {
3573 StaParams.htcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003574 vos_mem_copy(&StaParams.HTCap, params->ht_capa, sizeof(tSirHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -07003575 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003576
3577 StaParams.supported_rates_len = params->supported_rates_len;
3578
3579 /* Note : The Maximum sizeof supported_rates sent by the Supplicant is 32.
3580 * The supported_rates array , for all the structures propogating till Add Sta
3581 * to the firmware has to be modified , if the supplicant (ieee80211) is
3582 * modified to send more rates.
3583 */
3584
3585 /* To avoid Data Currption , set to max length to SIR_MAC_MAX_SUPP_RATES
3586 */
3587 if (StaParams.supported_rates_len > SIR_MAC_MAX_SUPP_RATES)
3588 StaParams.supported_rates_len = SIR_MAC_MAX_SUPP_RATES;
3589
3590 if (0 != StaParams.supported_rates_len) {
3591 int i = 0;
3592 vos_mem_copy(StaParams.supported_rates, params->supported_rates,
3593 StaParams.supported_rates_len);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07003594 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003595 "Supported Rates with Length %d", StaParams.supported_rates_len);
3596 for (i=0; i < StaParams.supported_rates_len; i++)
Hoonki Lee5305c3a2013-04-29 23:28:59 -07003597 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003598 "[%d]: %0x", i, StaParams.supported_rates[i]);
3599 }
3600
3601 if (NULL != params->vht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -07003602 {
3603 StaParams.vhtcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003604 vos_mem_copy(&StaParams.VHTCap, params->vht_capa, sizeof(tSirVHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -07003605 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003606
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003607 if (0 != params->ext_capab_len ) {
3608 /*Define A Macro : TODO Sunil*/
3609 if ((1<<4) & StaParams.extn_capability[3]) {
3610 isBufSta = 1;
3611 }
Naresh Jayaram3180aa42014-02-12 21:47:26 +05303612 /* TDLS Channel Switching Support */
3613 if ((1<<6) & StaParams.extn_capability[3]) {
3614 isOffChannelSupported = 1;
3615 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003616 }
Naresh Jayaram3180aa42014-02-12 21:47:26 +05303617 status = wlan_hdd_tdls_set_peer_caps( pAdapter, mac,
3618 &StaParams, isBufSta,
3619 isOffChannelSupported);
3620
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05303621 if (VOS_STATUS_SUCCESS != status) {
3622 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3623 "%s: wlan_hdd_tdls_set_peer_caps failed!", __func__);
3624 return -EINVAL;
3625 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003626 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 1, &StaParams);
3627
3628 if (VOS_STATUS_SUCCESS != status) {
3629 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3630 "%s: sme_ChangeTdlsPeerSta failed!", __func__);
3631 return -EINVAL;
3632 }
3633 }
Gopichand Nakkalab0856222013-03-12 22:39:05 -07003634#endif
Gopichand Nakkala6239acd2013-06-14 14:48:00 +05303635 }
Jeff Johnsone7245742012-09-05 17:12:55 -07003636 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07003637 return status;
3638}
3639
3640/*
Jeff Johnson295189b2012-06-20 16:38:30 -07003641 * FUNCTION: wlan_hdd_cfg80211_add_key
3642 * This function is used to initialize the key information
3643 */
3644#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003645static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07003646 struct net_device *ndev,
3647 u8 key_index, bool pairwise,
3648 const u8 *mac_addr,
3649 struct key_params *params
3650 )
3651#else
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003652static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07003653 struct net_device *ndev,
3654 u8 key_index, const u8 *mac_addr,
3655 struct key_params *params
3656 )
3657#endif
3658{
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003659 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -07003660 tCsrRoamSetKey setKey;
3661 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05303662 int status;
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003663 v_U32_t roamId= 0xFF;
3664 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07003665 hdd_hostapd_state_t *pHostapdState;
3666 VOS_STATUS vos_status;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07003667 eHalStatus halStatus;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05303668 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07003669
3670 ENTER();
3671
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05303672 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
3673 TRACE_CODE_HDD_CFG80211_ADD_KEY,
3674 pAdapter->sessionId, params->key_len));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05303675 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
3676 status = wlan_hdd_validate_context(pHddCtx);
3677
3678 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07003679 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05303680 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3681 "%s: HDD context is not valid", __func__);
3682 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07003683 }
3684
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05303685 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
3686 __func__, hdd_device_modetoString(pAdapter->device_mode),
3687 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07003688
3689 if (CSR_MAX_NUM_KEY <= key_index)
3690 {
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003691 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07003692 key_index);
3693
3694 return -EINVAL;
3695 }
3696
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003697 if (CSR_MAX_KEY_LEN < params->key_len)
3698 {
3699 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key length %d", __func__,
3700 params->key_len);
3701
3702 return -EINVAL;
3703 }
3704
3705 hddLog(VOS_TRACE_LEVEL_INFO,
3706 "%s: called with key index = %d & key length %d",
3707 __func__, key_index, params->key_len);
Jeff Johnson295189b2012-06-20 16:38:30 -07003708
3709 /*extract key idx, key len and key*/
3710 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
3711 setKey.keyId = key_index;
3712 setKey.keyLength = params->key_len;
3713 vos_mem_copy(&setKey.Key[0],params->key, params->key_len);
3714
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003715 switch (params->cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -07003716 {
3717 case WLAN_CIPHER_SUITE_WEP40:
3718 setKey.encType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
3719 break;
3720
3721 case WLAN_CIPHER_SUITE_WEP104:
3722 setKey.encType = eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
3723 break;
3724
3725 case WLAN_CIPHER_SUITE_TKIP:
3726 {
3727 u8 *pKey = &setKey.Key[0];
3728 setKey.encType = eCSR_ENCRYPT_TYPE_TKIP;
3729
3730 vos_mem_zero(pKey, CSR_MAX_KEY_LEN);
3731
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003732 /*Supplicant sends the 32bytes key in this order
Jeff Johnson295189b2012-06-20 16:38:30 -07003733
3734 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003735 | Tk1 |TX-MIC | RX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -07003736 |--------------|----------|----------|
3737 <---16bytes---><--8bytes--><--8bytes-->
3738
3739 */
3740 /*Sme expects the 32 bytes key to be in the below order
3741
3742 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003743 | Tk1 |RX-MIC | TX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -07003744 |--------------|----------|----------|
3745 <---16bytes---><--8bytes--><--8bytes-->
3746 */
3747 /* Copy the Temporal Key 1 (TK1) */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003748 vos_mem_copy(pKey, params->key, 16);
Jeff Johnson295189b2012-06-20 16:38:30 -07003749
3750 /*Copy the rx mic first*/
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003751 vos_mem_copy(&pKey[16], &params->key[24], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -07003752
3753 /*Copy the tx mic */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003754 vos_mem_copy(&pKey[24], &params->key[16], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -07003755
3756
3757 break;
3758 }
3759
3760 case WLAN_CIPHER_SUITE_CCMP:
3761 setKey.encType = eCSR_ENCRYPT_TYPE_AES;
3762 break;
3763
3764#ifdef FEATURE_WLAN_WAPI
3765 case WLAN_CIPHER_SUITE_SMS4:
3766 {
3767 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
3768 wlan_hdd_cfg80211_set_key_wapi(pAdapter, key_index, mac_addr,
3769 params->key, params->key_len);
3770 return 0;
3771 }
3772#endif
Chet Lanctot186b5732013-03-18 10:26:30 -07003773
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003774#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -07003775 case WLAN_CIPHER_SUITE_KRK:
3776 setKey.encType = eCSR_ENCRYPT_TYPE_KRK;
3777 break;
3778#endif
Chet Lanctot186b5732013-03-18 10:26:30 -07003779
3780#ifdef WLAN_FEATURE_11W
3781 case WLAN_CIPHER_SUITE_AES_CMAC:
3782 setKey.encType = eCSR_ENCRYPT_TYPE_AES_CMAC;
Chet Lanctot3b5158a2013-03-31 16:45:21 -07003783 break;
Chet Lanctot186b5732013-03-18 10:26:30 -07003784#endif
3785
Jeff Johnson295189b2012-06-20 16:38:30 -07003786 default:
Jeff Johnson0299d0a2013-10-30 12:37:43 -07003787 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unsupported cipher type %u",
Jeff Johnson295189b2012-06-20 16:38:30 -07003788 __func__, params->cipher);
3789 return -EOPNOTSUPP;
3790 }
3791
3792 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: encryption type %d",
3793 __func__, setKey.encType);
3794
Shailender Karmuchi642e9812013-05-30 14:34:49 -07003795 if (
Jeff Johnson295189b2012-06-20 16:38:30 -07003796#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
3797 (!pairwise)
3798#else
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003799 (!mac_addr || is_broadcast_ether_addr(mac_addr))
Jeff Johnson295189b2012-06-20 16:38:30 -07003800#endif
Shailender Karmuchi642e9812013-05-30 14:34:49 -07003801 )
3802 {
3803 /* set group key*/
3804 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3805 "%s- %d: setting Broadcast key",
3806 __func__, __LINE__);
3807 setKey.keyDirection = eSIR_RX_ONLY;
3808 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
3809 }
3810 else
3811 {
3812 /* set pairwise key*/
3813 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3814 "%s- %d: setting pairwise key",
3815 __func__, __LINE__);
3816 setKey.keyDirection = eSIR_TX_RX;
3817 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
3818 }
3819 if ((WLAN_HDD_IBSS == pAdapter->device_mode) && !pairwise)
3820 {
3821 setKey.keyDirection = eSIR_TX_RX;
3822 /*Set the group key*/
3823 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
3824 pAdapter->sessionId, &setKey, &roamId );
Jeff Johnson295189b2012-06-20 16:38:30 -07003825
Shailender Karmuchi642e9812013-05-30 14:34:49 -07003826 if ( 0 != status )
3827 {
3828 hddLog(VOS_TRACE_LEVEL_ERROR,
3829 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
3830 return -EINVAL;
3831 }
3832 /*Save the keys here and call sme_RoamSetKey for setting
3833 the PTK after peer joins the IBSS network*/
3834 vos_mem_copy(&pAdapter->sessionCtx.station.ibss_enc_key,
3835 &setKey, sizeof(tCsrRoamSetKey));
3836 return status;
3837 }
Gopichand Nakkala29149562013-05-10 21:43:41 +05303838 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP) ||
3839 (pAdapter->device_mode == WLAN_HDD_P2P_GO))
3840 {
Jeff Johnson295189b2012-06-20 16:38:30 -07003841 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003842 if( pHostapdState->bssState == BSS_START )
3843 {
c_hpothu7c55da62014-01-23 18:34:02 +05303844 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3845 vos_status = wlan_hdd_check_ula_done(pAdapter);
3846
3847 if ( vos_status != VOS_STATUS_SUCCESS )
3848 {
3849 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3850 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
3851 __LINE__, vos_status );
3852
3853 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
3854
3855 return -EINVAL;
3856 }
3857
Jeff Johnson295189b2012-06-20 16:38:30 -07003858 status = WLANSAP_SetKeySta( pVosContext, &setKey);
3859
3860 if ( status != eHAL_STATUS_SUCCESS )
3861 {
3862 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3863 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
3864 __LINE__, status );
3865 }
3866 }
3867
3868 /* Saving WEP keys */
3869 else if( eCSR_ENCRYPT_TYPE_WEP40_STATICKEY == setKey.encType ||
3870 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY == setKey.encType )
3871 {
3872 //Save the wep key in ap context. Issue setkey after the BSS is started.
3873 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
3874 vos_mem_copy(&pAPCtx->wepKey[key_index], &setKey, sizeof(tCsrRoamSetKey));
3875 }
3876 else
3877 {
3878 //Save the key in ap context. Issue setkey after the BSS is started.
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003879 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07003880 vos_mem_copy(&pAPCtx->groupKey, &setKey, sizeof(tCsrRoamSetKey));
3881 }
3882 }
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003883 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION) ||
3884 (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT) )
Jeff Johnson295189b2012-06-20 16:38:30 -07003885 {
3886 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
3887 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3888
Gopichand Nakkala3d295922013-05-07 16:19:14 +05303889#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
3890 if (!pairwise)
3891#else
3892 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
3893#endif
3894 {
3895 /* set group key*/
3896 if (pHddStaCtx->roam_info.deferKeyComplete)
3897 {
3898 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3899 "%s- %d: Perform Set key Complete",
3900 __func__, __LINE__);
3901 hdd_PerformRoamSetKeyComplete(pAdapter);
3902 }
3903 }
3904
Jeff Johnson295189b2012-06-20 16:38:30 -07003905 pWextState->roamProfile.Keys.KeyLength[key_index] = (u8)params->key_len;
3906
Venkata Prathyusha Kuntupalliee2ce712013-01-17 14:09:24 -08003907 pWextState->roamProfile.Keys.defaultIndex = key_index;
3908
3909
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003910 vos_mem_copy(&pWextState->roamProfile.Keys.KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -07003911 params->key, params->key_len);
3912
Gopichand Nakkala3d295922013-05-07 16:19:14 +05303913
Jeff Johnson295189b2012-06-20 16:38:30 -07003914 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
3915
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303916 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -07003917 "%s: set key for peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303918 __func__, setKey.peerMac[0], setKey.peerMac[1],
3919 setKey.peerMac[2], setKey.peerMac[3],
3920 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -07003921 setKey.keyDirection);
3922
3923 vos_status = wlan_hdd_check_ula_done(pAdapter);
3924
3925 if ( vos_status != VOS_STATUS_SUCCESS )
3926 {
3927 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3928 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
3929 __LINE__, vos_status );
3930
3931 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
3932
3933 return -EINVAL;
3934
3935 }
3936
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07003937#ifdef WLAN_FEATURE_VOWIFI_11R
Gopichand Nakkala3d295922013-05-07 16:19:14 +05303938 /* The supplicant may attempt to set the PTK once pre-authentication
3939 is done. Save the key in the UMAC and include it in the ADD BSS
3940 request */
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07003941 halStatus = sme_FTUpdateKey( WLAN_HDD_GET_HAL_CTX(pAdapter), &setKey);
Gopichand Nakkala3d295922013-05-07 16:19:14 +05303942 if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_SUCCESS )
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07003943 {
Gopichand Nakkala3d295922013-05-07 16:19:14 +05303944 hddLog(VOS_TRACE_LEVEL_INFO_MED,
3945 "%s: Update PreAuth Key success", __func__);
3946 return 0;
3947 }
3948 else if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_FAILED )
3949 {
3950 hddLog(VOS_TRACE_LEVEL_ERROR,
3951 "%s: Update PreAuth Key failed", __func__);
Gopichand Nakkalad7d13652013-02-15 01:48:00 +05303952 return -EINVAL;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07003953 }
3954#endif /* WLAN_FEATURE_VOWIFI_11R */
Jeff Johnson295189b2012-06-20 16:38:30 -07003955
3956 /* issue set key request to SME*/
3957 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
3958 pAdapter->sessionId, &setKey, &roamId );
3959
3960 if ( 0 != status )
3961 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303962 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07003963 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
3964 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
3965 return -EINVAL;
3966 }
3967
3968
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303969 /* in case of IBSS as there was no information available about WEP keys during
3970 * IBSS join, group key intialized with NULL key, so re-initialize group key
Jeff Johnson295189b2012-06-20 16:38:30 -07003971 * with correct value*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303972 if ( (eCSR_BSS_TYPE_START_IBSS == pWextState->roamProfile.BSSType) &&
3973 !( ( IW_AUTH_KEY_MGMT_802_1X
3974 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X))
Jeff Johnson295189b2012-06-20 16:38:30 -07003975 && (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType)
3976 )
3977 &&
3978 ( (WLAN_CIPHER_SUITE_WEP40 == params->cipher)
3979 || (WLAN_CIPHER_SUITE_WEP104 == params->cipher)
3980 )
3981 )
3982 {
3983 setKey.keyDirection = eSIR_RX_ONLY;
3984 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
3985
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303986 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -07003987 "%s: set key peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303988 __func__, setKey.peerMac[0], setKey.peerMac[1],
3989 setKey.peerMac[2], setKey.peerMac[3],
3990 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -07003991 setKey.keyDirection);
3992
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303993 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07003994 pAdapter->sessionId, &setKey, &roamId );
3995
3996 if ( 0 != status )
3997 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303998 hddLog(VOS_TRACE_LEVEL_ERROR,
3999 "%s: sme_RoamSetKey failed for group key (IBSS), returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07004000 __func__, status);
4001 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
4002 return -EINVAL;
4003 }
4004 }
4005 }
4006
4007 return 0;
4008}
4009
4010/*
4011 * FUNCTION: wlan_hdd_cfg80211_get_key
4012 * This function is used to get the key information
4013 */
4014#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304015static int wlan_hdd_cfg80211_get_key(
4016 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07004017 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304018 u8 key_index, bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -07004019 const u8 *mac_addr, void *cookie,
4020 void (*callback)(void *cookie, struct key_params*)
4021 )
4022#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304023static int wlan_hdd_cfg80211_get_key(
4024 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07004025 struct net_device *ndev,
4026 u8 key_index, const u8 *mac_addr, void *cookie,
4027 void (*callback)(void *cookie, struct key_params*)
4028 )
4029#endif
4030{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304031 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -07004032 hdd_wext_state_t *pWextState= WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
4033 tCsrRoamProfile *pRoamProfile = &(pWextState->roamProfile);
4034 struct key_params params;
4035
4036 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304037
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05304038 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
4039 TRACE_CODE_HDD_CFG80211_GET_KEY,
4040 pAdapter->sessionId, params.cipher));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05304041 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
4042 __func__, hdd_device_modetoString(pAdapter->device_mode),
4043 pAdapter->device_mode);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304044
Jeff Johnson295189b2012-06-20 16:38:30 -07004045 memset(&params, 0, sizeof(params));
4046
4047 if (CSR_MAX_NUM_KEY <= key_index)
4048 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05304049 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid key index %d"), key_index);
Jeff Johnson295189b2012-06-20 16:38:30 -07004050 return -EINVAL;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304051 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004052
4053 switch(pRoamProfile->EncryptionType.encryptionType[0])
4054 {
4055 case eCSR_ENCRYPT_TYPE_NONE:
4056 params.cipher = IW_AUTH_CIPHER_NONE;
4057 break;
4058
4059 case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY:
4060 case eCSR_ENCRYPT_TYPE_WEP40:
4061 params.cipher = WLAN_CIPHER_SUITE_WEP40;
4062 break;
4063
4064 case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY:
4065 case eCSR_ENCRYPT_TYPE_WEP104:
4066 params.cipher = WLAN_CIPHER_SUITE_WEP104;
4067 break;
4068
4069 case eCSR_ENCRYPT_TYPE_TKIP:
4070 params.cipher = WLAN_CIPHER_SUITE_TKIP;
4071 break;
4072
4073 case eCSR_ENCRYPT_TYPE_AES:
4074 params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
4075 break;
4076
4077 default:
4078 params.cipher = IW_AUTH_CIPHER_NONE;
4079 break;
4080 }
4081
4082 params.key_len = pRoamProfile->Keys.KeyLength[key_index];
4083 params.seq_len = 0;
4084 params.seq = NULL;
4085 params.key = &pRoamProfile->Keys.KeyMaterial[key_index][0];
4086 callback(cookie, &params);
4087 return 0;
4088}
4089
4090/*
4091 * FUNCTION: wlan_hdd_cfg80211_del_key
4092 * This function is used to delete the key information
4093 */
4094#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304095static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07004096 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304097 u8 key_index,
4098 bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -07004099 const u8 *mac_addr
4100 )
4101#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304102static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07004103 struct net_device *ndev,
4104 u8 key_index,
4105 const u8 *mac_addr
4106 )
4107#endif
4108{
4109 int status = 0;
4110
4111 //This code needs to be revisited. There is sme_removeKey API, we should
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304112 //plan to use that. After the change to use correct index in setkey,
Jeff Johnson295189b2012-06-20 16:38:30 -07004113 //it is observed that this is invalidating peer
4114 //key index whenever re-key is done. This is affecting data link.
4115 //It should be ok to ignore del_key.
4116#if 0
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304117 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
4118 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07004119 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
4120 tCsrRoamSetKey setKey;
4121 v_U32_t roamId= 0xFF;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304122
Jeff Johnson295189b2012-06-20 16:38:30 -07004123 ENTER();
4124
4125 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device_mode = %d\n",
4126 __func__,pAdapter->device_mode);
4127
4128 if (CSR_MAX_NUM_KEY <= key_index)
4129 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304130 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07004131 key_index);
4132
4133 return -EINVAL;
4134 }
4135
4136 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
4137 setKey.keyId = key_index;
4138
4139 if (mac_addr)
4140 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
4141 else
4142 vos_mem_copy(setKey.peerMac, groupmacaddr, WNI_CFG_BSSID_LEN);
4143
4144 setKey.encType = eCSR_ENCRYPT_TYPE_NONE;
4145
4146 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07004147 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304148 )
4149 {
4150
4151 hdd_hostapd_state_t *pHostapdState =
Jeff Johnson295189b2012-06-20 16:38:30 -07004152 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
4153 if( pHostapdState->bssState == BSS_START)
4154 {
4155 status = WLANSAP_SetKeySta( pVosContext, &setKey);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304156
Jeff Johnson295189b2012-06-20 16:38:30 -07004157 if ( status != eHAL_STATUS_SUCCESS )
4158 {
4159 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4160 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
4161 __LINE__, status );
4162 }
4163 }
4164 }
4165 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304166 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnson295189b2012-06-20 16:38:30 -07004167 )
4168 {
4169 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4170
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304171 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
4172
4173 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -07004174 "%s: delete key for peerMac %2x:%2x:%2x:%2x:%2x:%2x",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304175 __func__, setKey.peerMac[0], setKey.peerMac[1],
4176 setKey.peerMac[2], setKey.peerMac[3],
Jeff Johnson295189b2012-06-20 16:38:30 -07004177 setKey.peerMac[4], setKey.peerMac[5]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304178 if(pAdapter->sessionCtx.station.conn_info.connState ==
4179 eConnectionState_Associated)
Jeff Johnson295189b2012-06-20 16:38:30 -07004180 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304181 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07004182 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304183
Jeff Johnson295189b2012-06-20 16:38:30 -07004184 if ( 0 != status )
4185 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304186 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07004187 "%s: sme_RoamSetKey failure, returned %d",
4188 __func__, status);
4189 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
4190 return -EINVAL;
4191 }
4192 }
4193 }
4194#endif
Jeff Johnsone7245742012-09-05 17:12:55 -07004195 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07004196 return status;
4197}
4198
4199/*
4200 * FUNCTION: wlan_hdd_cfg80211_set_default_key
4201 * This function is used to set the default tx key index
4202 */
4203#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
4204static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
4205 struct net_device *ndev,
4206 u8 key_index,
4207 bool unicast, bool multicast)
4208#else
4209static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
4210 struct net_device *ndev,
4211 u8 key_index)
4212#endif
4213{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304214 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05304215 int status;
Gopichand Nakkala29149562013-05-10 21:43:41 +05304216 hdd_wext_state_t *pWextState;
4217 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05304218 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07004219
4220 ENTER();
4221
Gopichand Nakkala29149562013-05-10 21:43:41 +05304222 if ((NULL == pAdapter))
4223 {
4224 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
4225 "invalid adapter");
4226 return -EINVAL;
4227 }
4228
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05304229 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
4230 TRACE_CODE_HDD_CFG80211_SET_DEFAULT_KEY,
4231 pAdapter->sessionId, key_index));
4232
Gopichand Nakkala29149562013-05-10 21:43:41 +05304233 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
4234 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4235
4236 if ((NULL == pWextState) || (NULL == pHddStaCtx))
4237 {
4238 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
4239 "invalid Wext state or HDD context");
4240 return -EINVAL;
4241 }
4242
Arif Hussain6d2a3322013-11-17 19:50:10 -08004243 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d key_index = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07004244 __func__,pAdapter->device_mode, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304245
Jeff Johnson295189b2012-06-20 16:38:30 -07004246 if (CSR_MAX_NUM_KEY <= key_index)
4247 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304248 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07004249 key_index);
4250
4251 return -EINVAL;
4252 }
4253
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05304254 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
4255 status = wlan_hdd_validate_context(pHddCtx);
4256
4257 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004258 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05304259 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4260 "%s: HDD context is not valid", __func__);
4261 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004262 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304263
Jeff Johnson295189b2012-06-20 16:38:30 -07004264 if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -07004265 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304266 )
Jeff Johnson295189b2012-06-20 16:38:30 -07004267 {
Gopichand Nakkala29149562013-05-10 21:43:41 +05304268 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
Arif Hussain6943f522013-11-04 20:10:10 -08004269 pHddStaCtx->conn_info.ucEncryptionType) &&
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304270 (eCSR_ENCRYPT_TYPE_AES !=
Arif Hussain6943f522013-11-04 20:10:10 -08004271 pHddStaCtx->conn_info.ucEncryptionType)
Jeff Johnson295189b2012-06-20 16:38:30 -07004272 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304273 {
4274 /* if default key index is not same as previous one,
Jeff Johnson295189b2012-06-20 16:38:30 -07004275 * then update the default key index */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304276
Jeff Johnson295189b2012-06-20 16:38:30 -07004277 tCsrRoamSetKey setKey;
4278 v_U32_t roamId= 0xFF;
4279 tCsrKeys *Keys = &pWextState->roamProfile.Keys;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304280
4281 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: default tx key index %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07004282 __func__, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304283
Jeff Johnson295189b2012-06-20 16:38:30 -07004284 Keys->defaultIndex = (u8)key_index;
4285 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
4286 setKey.keyId = key_index;
4287 setKey.keyLength = Keys->KeyLength[key_index];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304288
4289 vos_mem_copy(&setKey.Key[0],
4290 &Keys->KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -07004291 Keys->KeyLength[key_index]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304292
Gopichand Nakkala29149562013-05-10 21:43:41 +05304293 setKey.keyDirection = eSIR_TX_RX;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304294
4295 vos_mem_copy(setKey.peerMac,
Jeff Johnson295189b2012-06-20 16:38:30 -07004296 &pHddStaCtx->conn_info.bssId[0],
4297 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304298
Gopichand Nakkala29149562013-05-10 21:43:41 +05304299 if (Keys->KeyLength[key_index] == CSR_WEP40_KEY_LEN &&
4300 pWextState->roamProfile.EncryptionType.encryptionType[0] ==
4301 eCSR_ENCRYPT_TYPE_WEP104)
4302 {
4303 /*In the case of dynamic wep supplicant hardcodes DWEP type to eCSR_ENCRYPT_TYPE_WEP104
4304 even though ap is configured for WEP-40 encryption. In this canse the key length
4305 is 5 but the encryption type is 104 hence checking the key langht(5) and encryption
4306 type(104) and switching encryption type to 40*/
4307 pWextState->roamProfile.EncryptionType.encryptionType[0] =
4308 eCSR_ENCRYPT_TYPE_WEP40;
4309 pWextState->roamProfile.mcEncryptionType.encryptionType[0] =
4310 eCSR_ENCRYPT_TYPE_WEP40;
4311 }
4312
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304313 setKey.encType =
Jeff Johnson295189b2012-06-20 16:38:30 -07004314 pWextState->roamProfile.EncryptionType.encryptionType[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304315
Jeff Johnson295189b2012-06-20 16:38:30 -07004316 /* issue set key request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304317 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07004318 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304319
Jeff Johnson295189b2012-06-20 16:38:30 -07004320 if ( 0 != status )
4321 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304322 hddLog(VOS_TRACE_LEVEL_ERROR,
4323 "%s: sme_RoamSetKey failed, returned %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07004324 status);
4325 return -EINVAL;
4326 }
4327 }
4328 }
4329
4330 /* In SoftAp mode setting key direction for default mode */
4331 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
4332 {
4333 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
4334 pWextState->roamProfile.EncryptionType.encryptionType[0]) &&
4335 (eCSR_ENCRYPT_TYPE_AES !=
4336 pWextState->roamProfile.EncryptionType.encryptionType[0])
4337 )
4338 {
4339 /* Saving key direction for default key index to TX default */
4340 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
4341 pAPCtx->wepKey[key_index].keyDirection = eSIR_TX_DEFAULT;
4342 }
4343 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304344
Jeff Johnson295189b2012-06-20 16:38:30 -07004345 return status;
4346}
4347
Jeff Johnson295189b2012-06-20 16:38:30 -07004348/*
4349 * FUNCTION: wlan_hdd_cfg80211_inform_bss
4350 * This function is used to inform the BSS details to nl80211 interface.
4351 */
4352static struct cfg80211_bss* wlan_hdd_cfg80211_inform_bss(
4353 hdd_adapter_t *pAdapter, tCsrRoamConnectedProfile *roamProfile)
4354{
4355 struct net_device *dev = pAdapter->dev;
4356 struct wireless_dev *wdev = dev->ieee80211_ptr;
4357 struct wiphy *wiphy = wdev->wiphy;
4358 tSirBssDescription *pBssDesc = roamProfile->pBssDesc;
4359 int chan_no;
4360 int ie_length;
4361 const char *ie;
4362 unsigned int freq;
4363 struct ieee80211_channel *chan;
4364 int rssi = 0;
4365 struct cfg80211_bss *bss = NULL;
4366
4367 ENTER();
4368
4369 if( NULL == pBssDesc )
4370 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08004371 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pBssDesc is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004372 return bss;
4373 }
4374
4375 chan_no = pBssDesc->channelId;
4376 ie_length = GET_IE_LEN_IN_BSS_DESC( pBssDesc->length );
4377 ie = ((ie_length != 0) ? (const char *)&pBssDesc->ieFields: NULL);
4378
4379 if( NULL == ie )
4380 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08004381 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: IE of BSS descriptor is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004382 return bss;
4383 }
4384
4385#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
4386 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
4387 {
4388 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
4389 }
4390 else
4391 {
4392 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
4393 }
4394#else
4395 freq = ieee80211_channel_to_frequency(chan_no);
4396#endif
4397
4398 chan = __ieee80211_get_channel(wiphy, freq);
4399
Santhosh Kumar Padmaa45fdb12014-04-15 15:54:38 +05304400 if (!chan) {
4401 hddLog(VOS_TRACE_LEVEL_ERROR, "%s chan pointer is NULL", __func__);
4402 return NULL;
4403 }
4404
Jeff Johnson295189b2012-06-20 16:38:30 -07004405 bss = cfg80211_get_bss(wiphy, chan, pBssDesc->bssId,
4406 &roamProfile->SSID.ssId[0], roamProfile->SSID.length,
4407 WLAN_CAPABILITY_ESS, WLAN_CAPABILITY_ESS);
4408 if (bss == NULL)
4409 {
4410 rssi = (VOS_MIN ((pBssDesc->rssi + pBssDesc->sinr), 0))*100;
4411
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304412 return (cfg80211_inform_bss(wiphy, chan, pBssDesc->bssId,
4413 le64_to_cpu(*(__le64 *)pBssDesc->timeStamp),
Jeff Johnson295189b2012-06-20 16:38:30 -07004414 pBssDesc->capabilityInfo,
4415 pBssDesc->beaconInterval, ie, ie_length,
4416 rssi, GFP_KERNEL ));
4417}
4418 else
4419 {
4420 return bss;
4421 }
4422}
4423
4424
4425
4426/*
4427 * FUNCTION: wlan_hdd_cfg80211_inform_bss_frame
4428 * This function is used to inform the BSS details to nl80211 interface.
4429 */
4430struct cfg80211_bss*
4431wlan_hdd_cfg80211_inform_bss_frame( hdd_adapter_t *pAdapter,
4432 tSirBssDescription *bss_desc
4433 )
4434{
4435 /*
4436 cfg80211_inform_bss() is not updating ie field of bss entry, if entry
4437 already exists in bss data base of cfg80211 for that particular BSS ID.
4438 Using cfg80211_inform_bss_frame to update the bss entry instead of
4439 cfg80211_inform_bss, But this call expects mgmt packet as input. As of
4440 now there is no possibility to get the mgmt(probe response) frame from PE,
4441 converting bss_desc to ieee80211_mgmt(probe response) and passing to
4442 cfg80211_inform_bss_frame.
4443 */
4444 struct net_device *dev = pAdapter->dev;
4445 struct wireless_dev *wdev = dev->ieee80211_ptr;
4446 struct wiphy *wiphy = wdev->wiphy;
4447 int chan_no = bss_desc->channelId;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08004448#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
4449 qcom_ie_age *qie_age = NULL;
4450 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length ) + sizeof(qcom_ie_age);
4451#else
Jeff Johnson295189b2012-06-20 16:38:30 -07004452 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length );
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08004453#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07004454 const char *ie =
4455 ((ie_length != 0) ? (const char *)&bss_desc->ieFields: NULL);
4456 unsigned int freq;
4457 struct ieee80211_channel *chan;
Abhishek Singh1e2bfa32014-01-02 15:44:15 +05304458 struct ieee80211_mgmt *mgmt = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07004459 struct cfg80211_bss *bss_status = NULL;
4460 size_t frame_len = sizeof (struct ieee80211_mgmt) + ie_length;
4461 int rssi = 0;
Wilson Yangf80a0542013-10-07 13:02:37 -07004462 hdd_context_t *pHddCtx;
4463 int status;
Jeff Johnsone7245742012-09-05 17:12:55 -07004464#ifdef WLAN_OPEN_SOURCE
4465 struct timespec ts;
4466#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07004467
Wilson Yangf80a0542013-10-07 13:02:37 -07004468 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
4469 status = wlan_hdd_validate_context(pHddCtx);
4470
4471 /*bss_update is not allowed during wlan driver loading or unloading*/
Mihir Shete18156292014-03-11 15:38:30 +05304472 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Wilson Yangf80a0542013-10-07 13:02:37 -07004473 {
4474 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4475 "%s:Loading_unloading in Progress. Ignore!!!",__func__);
4476 return NULL;
4477 }
4478
4479
4480 if (0 != status)
4481 {
4482 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4483 "%s: HDD context is not valid", __func__);
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -07004484 return NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -07004485 }
4486
Abhishek Singh1e2bfa32014-01-02 15:44:15 +05304487 mgmt = kzalloc((sizeof (struct ieee80211_mgmt) + ie_length), GFP_KERNEL);
Wilson Yangf80a0542013-10-07 13:02:37 -07004488 if (!mgmt)
4489 {
4490 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4491 "%s: memory allocation failed ", __func__);
4492 return NULL;
4493 }
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -07004494
Jeff Johnson295189b2012-06-20 16:38:30 -07004495 memcpy(mgmt->bssid, bss_desc->bssId, ETH_ALEN);
Jeff Johnsone7245742012-09-05 17:12:55 -07004496
4497#ifdef WLAN_OPEN_SOURCE
4498 /* Android does not want the timestamp from the frame.
4499 Instead it wants a monotonic increasing value */
4500 get_monotonic_boottime(&ts);
4501 mgmt->u.probe_resp.timestamp =
4502 ((u64)ts.tv_sec * 1000000) + (ts.tv_nsec / 1000);
4503#else
4504 /* keep old behavior for non-open source (for now) */
Jeff Johnson295189b2012-06-20 16:38:30 -07004505 memcpy(&mgmt->u.probe_resp.timestamp, bss_desc->timeStamp,
4506 sizeof (bss_desc->timeStamp));
Jeff Johnsone7245742012-09-05 17:12:55 -07004507
4508#endif
4509
Jeff Johnson295189b2012-06-20 16:38:30 -07004510 mgmt->u.probe_resp.beacon_int = bss_desc->beaconInterval;
4511 mgmt->u.probe_resp.capab_info = bss_desc->capabilityInfo;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08004512
4513#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
4514 /* GPS Requirement: need age ie per entry. Using vendor specific. */
4515 /* Assuming this is the last IE, copy at the end */
4516 ie_length -=sizeof(qcom_ie_age);
4517 qie_age = (qcom_ie_age *)(mgmt->u.probe_resp.variable + ie_length);
4518 qie_age->element_id = QCOM_VENDOR_IE_ID;
4519 qie_age->len = QCOM_VENDOR_IE_AGE_LEN;
4520 qie_age->oui_1 = QCOM_OUI1;
4521 qie_age->oui_2 = QCOM_OUI2;
4522 qie_age->oui_3 = QCOM_OUI3;
4523 qie_age->type = QCOM_VENDOR_IE_AGE_TYPE;
4524 qie_age->age = vos_timer_get_system_ticks() - bss_desc->nReceivedTime;
4525#endif
4526
Jeff Johnson295189b2012-06-20 16:38:30 -07004527 memcpy(mgmt->u.probe_resp.variable, ie, ie_length);
Gopichand Nakkalad908ec82013-05-16 19:32:19 +05304528 if (bss_desc->fProbeRsp)
4529 {
4530 mgmt->frame_control |=
4531 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_RESP);
4532 }
4533 else
4534 {
4535 mgmt->frame_control |=
4536 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_BEACON);
4537 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004538
4539#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304540 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ) &&
Jeff Johnson295189b2012-06-20 16:38:30 -07004541 (wiphy->bands[IEEE80211_BAND_2GHZ] != NULL))
4542 {
4543 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
4544 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304545 else if ((chan_no > ARRAY_SIZE(hdd_channels_2_4_GHZ)) &&
Jeff Johnson295189b2012-06-20 16:38:30 -07004546 (wiphy->bands[IEEE80211_BAND_5GHZ] != NULL))
4547
4548 {
4549 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
4550 }
4551 else
4552 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05304553 hddLog(VOS_TRACE_LEVEL_ERROR, "%s Invalid chan_no:%d",
4554 __func__, chan_no);
Jeff Johnson295189b2012-06-20 16:38:30 -07004555 kfree(mgmt);
4556 return NULL;
4557 }
4558#else
4559 freq = ieee80211_channel_to_frequency(chan_no);
4560#endif
4561 chan = __ieee80211_get_channel(wiphy, freq);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -08004562 /*when the band is changed on the fly using the GUI, three things are done
4563 * 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)
4564 * as part of the scan abort, message willbe queued to PE and we proceed with flushing and changinh the band.
4565 * pe will stop the scanning further and report back the results what ever it had till now by calling the call back function.
4566 * if the time between update band and scandone call back is sufficent enough the band change reflects in SME, SME validates the channels
4567 * and discards the channels correponding to previous band and calls back with zero bss results.
4568 * 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
4569 * all the channels correponding to previous band.this is due to race condition.but those channels are invalid to the new band and so
4570 * this function __ieee80211_get_channel will return NULL.Each time we report scan result with this pointer null warning kernel trace is printed.
4571 * if the scan results contain large number of APs continuosly kernel warning trace is printed and it will lead to apps watch dog bark.
4572 * So drop the bss and continue to next bss.
4573 */
4574 if(chan == NULL)
4575 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05304576 hddLog(VOS_TRACE_LEVEL_ERROR, "%s chan pointer is NULL", __func__);
Chilam Ngc4244af2013-04-01 15:37:32 -07004577 kfree(mgmt);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -08004578 return NULL;
4579 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004580 /*To keep the rssi icon of the connected AP in the scan window
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304581 *and the rssi icon of the wireless networks in sync
Jeff Johnson295189b2012-06-20 16:38:30 -07004582 * */
4583 if (( eConnectionState_Associated ==
4584 pAdapter->sessionCtx.station.conn_info.connState ) &&
4585 ( VOS_TRUE == vos_mem_compare(bss_desc->bssId,
4586 pAdapter->sessionCtx.station.conn_info.bssId,
4587 WNI_CFG_BSSID_LEN)))
4588 {
4589 /* supplicant takes the signal strength in terms of mBm(100*dBm) */
4590 rssi = (pAdapter->rssi * 100);
4591 }
4592 else
4593 {
4594 rssi = (VOS_MIN ((bss_desc->rssi + bss_desc->sinr), 0))*100;
4595 }
4596
Nirav Shah20ac06f2013-12-12 18:14:06 +05304597 hddLog(VOS_TRACE_LEVEL_INFO, "%s: BSSID:" MAC_ADDRESS_STR " Channel:%d"
4598 "RSSI:%d", __func__, MAC_ADDR_ARRAY(mgmt->bssid),
4599 chan->center_freq, (int)(rssi/100));
4600
Jeff Johnson295189b2012-06-20 16:38:30 -07004601 bss_status = cfg80211_inform_bss_frame(wiphy, chan, mgmt,
4602 frame_len, rssi, GFP_KERNEL);
4603 kfree(mgmt);
4604 return bss_status;
4605}
4606
4607/*
4608 * FUNCTION: wlan_hdd_cfg80211_update_bss_db
4609 * This function is used to update the BSS data base of CFG8011
4610 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304611struct cfg80211_bss* wlan_hdd_cfg80211_update_bss_db( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07004612 tCsrRoamInfo *pRoamInfo
4613 )
4614{
4615 tCsrRoamConnectedProfile roamProfile;
4616 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
4617 struct cfg80211_bss *bss = NULL;
4618
4619 ENTER();
4620
4621 memset(&roamProfile, 0, sizeof(tCsrRoamConnectedProfile));
4622 sme_RoamGetConnectProfile(hHal, pAdapter->sessionId, &roamProfile);
4623
4624 if (NULL != roamProfile.pBssDesc)
4625 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304626 bss = wlan_hdd_cfg80211_inform_bss(pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07004627 &roamProfile);
4628
4629 if (NULL == bss)
4630 {
4631 hddLog(VOS_TRACE_LEVEL_INFO, "%s: cfg80211_inform_bss return NULL",
4632 __func__);
4633 }
4634
4635 sme_RoamFreeConnectProfile(hHal, &roamProfile);
4636 }
4637 else
4638 {
4639 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: roamProfile.pBssDesc is NULL",
4640 __func__);
4641 }
4642 return bss;
4643}
4644
4645/*
4646 * FUNCTION: wlan_hdd_cfg80211_update_bss
4647 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304648static int wlan_hdd_cfg80211_update_bss( struct wiphy *wiphy,
4649 hdd_adapter_t *pAdapter
Jeff Johnson295189b2012-06-20 16:38:30 -07004650 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304651{
Jeff Johnson295189b2012-06-20 16:38:30 -07004652 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
4653 tCsrScanResultInfo *pScanResult;
4654 eHalStatus status = 0;
4655 tScanResultHandle pResult;
4656 struct cfg80211_bss *bss_status = NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -07004657 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07004658
4659 ENTER();
4660
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05304661 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
4662 TRACE_CODE_HDD_CFG80211_UPDATE_BSS,
4663 NO_SESSION, pAdapter->sessionId));
4664
Wilson Yangf80a0542013-10-07 13:02:37 -07004665 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
4666
4667 if (pHddCtx->isLogpInProgress)
Jeff Johnson295189b2012-06-20 16:38:30 -07004668 {
Wilson Yangf80a0542013-10-07 13:02:37 -07004669 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
4670 "%s:LOGP in Progress. Ignore!!!",__func__);
4671 return -EAGAIN;
Jeff Johnson295189b2012-06-20 16:38:30 -07004672 }
4673
Wilson Yangf80a0542013-10-07 13:02:37 -07004674
4675 /*bss_update is not allowed during wlan driver loading or unloading*/
Mihir Shete18156292014-03-11 15:38:30 +05304676 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Wilson Yangf80a0542013-10-07 13:02:37 -07004677 {
4678 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4679 "%s:Loading_unloading in Progress. Ignore!!!",__func__);
4680 return VOS_STATUS_E_PERM;
4681 }
4682
4683
Jeff Johnson295189b2012-06-20 16:38:30 -07004684 /*
4685 * start getting scan results and populate cgf80211 BSS database
4686 */
4687 status = sme_ScanGetResult(hHal, pAdapter->sessionId, NULL, &pResult);
4688
4689 /* no scan results */
4690 if (NULL == pResult)
4691 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05304692 hddLog(VOS_TRACE_LEVEL_INFO, "%s: No scan result Status %d",
4693 __func__, status);
Jeff Johnson295189b2012-06-20 16:38:30 -07004694 return status;
4695 }
4696
4697 pScanResult = sme_ScanResultGetFirst(hHal, pResult);
4698
4699 while (pScanResult)
4700 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304701 /*
4702 * cfg80211_inform_bss() is not updating ie field of bss entry, if
4703 * entry already exists in bss data base of cfg80211 for that
4704 * particular BSS ID. Using cfg80211_inform_bss_frame to update the
4705 * bss entry instead of cfg80211_inform_bss, But this call expects
4706 * mgmt packet as input. As of now there is no possibility to get
4707 * the mgmt(probe response) frame from PE, converting bss_desc to
Jeff Johnson295189b2012-06-20 16:38:30 -07004708 * ieee80211_mgmt(probe response) and passing to c
4709 * fg80211_inform_bss_frame.
4710 * */
4711
4712 bss_status = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
4713 &pScanResult->BssDescriptor);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304714
Jeff Johnson295189b2012-06-20 16:38:30 -07004715
4716 if (NULL == bss_status)
4717 {
4718 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -08004719 "%s: NULL returned by cfg80211_inform_bss", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004720 }
4721 else
4722 {
Yue Maf49ba872013-08-19 12:04:25 -07004723 cfg80211_put_bss(
4724#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0))
4725 wiphy,
4726#endif
4727 bss_status);
Jeff Johnson295189b2012-06-20 16:38:30 -07004728 }
4729
4730 pScanResult = sme_ScanResultGetNext(hHal, pResult);
4731 }
4732
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304733 sme_ScanResultPurge(hHal, pResult);
Jeff Johnson295189b2012-06-20 16:38:30 -07004734
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304735 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07004736}
4737
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004738void
4739hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel)
4740{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304741 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussaina7c8e412013-11-20 11:06:42 -08004742 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(macAddr));
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004743} /****** end hddPrintMacAddr() ******/
4744
4745void
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07004746hddPrintPmkId(tANI_U8 *pmkId, tANI_U8 logLevel)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004747{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304748 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussain6d2a3322013-11-17 19:50:10 -08004749 "%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X",
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07004750 pmkId[0], pmkId[1], pmkId[2], pmkId[3], pmkId[4],
4751 pmkId[5], pmkId[6], pmkId[7], pmkId[8], pmkId[9], pmkId[10],
4752 pmkId[11], pmkId[12], pmkId[13], pmkId[14], pmkId[15]);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004753} /****** end hddPrintPmkId() ******/
4754
4755//hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel);
4756//hddPrintMacAddr(macAddr, VOS_TRACE_LEVEL_FATAL);
4757
4758//void sirDumpBuf(tpAniSirGlobal pMac, tANI_U8 modId, tANI_U32 level, tANI_U8 *buf, tANI_U32 size);
4759//sirDumpBuf(pMac, VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, pmkid, 16);
4760
4761#define dump_bssid(bssid) \
4762 { \
Jeff Johnsone7245742012-09-05 17:12:55 -07004763 hddLog(VOS_TRACE_LEVEL_INFO, "BSSID (MAC) address:\t"); \
4764 hddPrintMacAddr(bssid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004765 }
4766
4767#define dump_pmkid(pMac, pmkid) \
4768 { \
Jeff Johnsone7245742012-09-05 17:12:55 -07004769 hddLog(VOS_TRACE_LEVEL_INFO, "PMKSA-ID:\t"); \
4770 hddPrintPmkId(pmkid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004771 }
4772
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -07004773#if defined(FEATURE_WLAN_LFR) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004774/*
4775 * FUNCTION: wlan_hdd_cfg80211_pmksa_candidate_notify
4776 * This function is used to notify the supplicant of a new PMKSA candidate.
4777 */
4778int wlan_hdd_cfg80211_pmksa_candidate_notify(
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304779 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004780 int index, bool preauth )
4781{
Jeff Johnsone7245742012-09-05 17:12:55 -07004782#ifdef FEATURE_WLAN_OKC
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004783 struct net_device *dev = pAdapter->dev;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004784 hdd_context_t *pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004785
4786 ENTER();
Jeff Johnsone7245742012-09-05 17:12:55 -07004787 hddLog(VOS_TRACE_LEVEL_INFO, "%s is going to notify supplicant of:", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004788
4789 if( NULL == pRoamInfo )
4790 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08004791 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pRoamInfo is NULL", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004792 return -EINVAL;
4793 }
4794
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004795 if (eANI_BOOLEAN_TRUE == hdd_is_okc_mode_enabled(pHddCtx))
4796 {
4797 dump_bssid(pRoamInfo->bssid);
4798 cfg80211_pmksa_candidate_notify(dev, index,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004799 pRoamInfo->bssid, preauth, GFP_KERNEL);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004800 }
Jeff Johnsone7245742012-09-05 17:12:55 -07004801#endif /* FEATURE_WLAN_OKC */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304802 return 0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004803}
4804#endif //FEATURE_WLAN_LFR
4805
Yue Maef608272013-04-08 23:09:17 -07004806#ifdef FEATURE_WLAN_LFR_METRICS
4807/*
4808 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth
4809 * 802.11r/LFR metrics reporting function to report preauth initiation
4810 *
4811 */
4812#define MAX_LFR_METRICS_EVENT_LENGTH 100
4813VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth(hdd_adapter_t *pAdapter,
4814 tCsrRoamInfo *pRoamInfo)
4815{
4816 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
4817 union iwreq_data wrqu;
4818
4819 ENTER();
4820
4821 if (NULL == pAdapter)
4822 {
4823 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
4824 return VOS_STATUS_E_FAILURE;
4825 }
4826
4827 /* create the event */
4828 memset(&wrqu, 0, sizeof(wrqu));
4829 memset(metrics_notification, 0, sizeof(metrics_notification));
4830
4831 wrqu.data.pointer = metrics_notification;
4832 wrqu.data.length = scnprintf(metrics_notification,
4833 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_INIT "
4834 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
4835
4836 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
4837
4838 EXIT();
4839
4840 return VOS_STATUS_SUCCESS;
4841}
4842
4843/*
4844 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth_status
4845 * 802.11r/LFR metrics reporting function to report preauth completion
4846 * or failure
4847 */
4848VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth_status(
4849 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo, bool preauth_status)
4850{
4851 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
4852 union iwreq_data wrqu;
4853
4854 ENTER();
4855
4856 if (NULL == pAdapter)
4857 {
4858 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
4859 return VOS_STATUS_E_FAILURE;
4860 }
4861
4862 /* create the event */
4863 memset(&wrqu, 0, sizeof(wrqu));
4864 memset(metrics_notification, 0, sizeof(metrics_notification));
4865
4866 scnprintf(metrics_notification, sizeof(metrics_notification),
4867 "QCOM: LFR_PREAUTH_STATUS "MAC_ADDRESS_STR,
4868 MAC_ADDR_ARRAY(pRoamInfo->bssid));
4869
4870 if (1 == preauth_status)
4871 strncat(metrics_notification, " TRUE", 5);
4872 else
4873 strncat(metrics_notification, " FALSE", 6);
4874
4875 wrqu.data.pointer = metrics_notification;
4876 wrqu.data.length = strlen(metrics_notification);
4877
4878 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
4879
4880 EXIT();
4881
4882 return VOS_STATUS_SUCCESS;
4883}
4884
4885/*
4886 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_handover
4887 * 802.11r/LFR metrics reporting function to report handover initiation
4888 *
4889 */
4890VOS_STATUS wlan_hdd_cfg80211_roam_metrics_handover(hdd_adapter_t * pAdapter,
4891 tCsrRoamInfo *pRoamInfo)
4892{
4893 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
4894 union iwreq_data wrqu;
4895
4896 ENTER();
4897
4898 if (NULL == pAdapter)
4899 {
4900 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
4901 return VOS_STATUS_E_FAILURE;
4902 }
4903
4904 /* create the event */
4905 memset(&wrqu, 0, sizeof(wrqu));
4906 memset(metrics_notification, 0, sizeof(metrics_notification));
4907
4908 wrqu.data.pointer = metrics_notification;
4909 wrqu.data.length = scnprintf(metrics_notification,
4910 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_HANDOVER "
4911 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
4912
4913 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
4914
4915 EXIT();
4916
4917 return VOS_STATUS_SUCCESS;
4918}
4919#endif
4920
Jeff Johnson295189b2012-06-20 16:38:30 -07004921/*
4922 * FUNCTION: hdd_cfg80211_scan_done_callback
4923 * scanning callback function, called after finishing scan
4924 *
4925 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304926static eHalStatus hdd_cfg80211_scan_done_callback(tHalHandle halHandle,
Jeff Johnson295189b2012-06-20 16:38:30 -07004927 void *pContext, tANI_U32 scanId, eCsrScanStatus status)
4928{
4929 struct net_device *dev = (struct net_device *) pContext;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304930 //struct wireless_dev *wdev = dev->ieee80211_ptr;
Jeff Johnson295189b2012-06-20 16:38:30 -07004931 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07004932 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
4933 hdd_scaninfo_t *pScanInfo = &pHddCtx->scan_info;
Jeff Johnson295189b2012-06-20 16:38:30 -07004934 struct cfg80211_scan_request *req = NULL;
4935 int ret = 0;
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +05304936 bool aborted = false;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05304937 long waitRet = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07004938
4939 ENTER();
4940
4941 hddLog(VOS_TRACE_LEVEL_INFO,
4942 "%s called with halHandle = %p, pContext = %p,"
Arif Hussain6d2a3322013-11-17 19:50:10 -08004943 "scanID = %d, returned status = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07004944 __func__, halHandle, pContext, (int) scanId, (int) status);
4945
Kiet Lamac06e2c2013-10-23 16:25:07 +05304946 pScanInfo->mScanPendingCounter = 0;
4947
Jeff Johnson295189b2012-06-20 16:38:30 -07004948 //Block on scan req completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +05304949 waitRet = wait_for_completion_interruptible_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07004950 &pScanInfo->scan_req_completion_event,
4951 msecs_to_jiffies(WLAN_WAIT_TIME_SCAN_REQ));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05304952 if (waitRet <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -07004953 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05304954 hddLog(VOS_TRACE_LEVEL_ERROR,
4955 "%s wait on scan_req_completion_event failed %ld",__func__, waitRet);
Jeff Johnson295189b2012-06-20 16:38:30 -07004956 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -07004957 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -07004958 }
4959
Yue Maef608272013-04-08 23:09:17 -07004960 if (pScanInfo->mScanPending != VOS_TRUE)
Jeff Johnson295189b2012-06-20 16:38:30 -07004961 {
4962 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -07004963 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -07004964 }
4965
4966 /* Check the scanId */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304967 if (pScanInfo->scanId != scanId)
Jeff Johnson295189b2012-06-20 16:38:30 -07004968 {
4969 hddLog(VOS_TRACE_LEVEL_INFO,
4970 "%s called with mismatched scanId pScanInfo->scanId = %d "
Arif Hussain6d2a3322013-11-17 19:50:10 -08004971 "scanId = %d", __func__, (int) pScanInfo->scanId,
Jeff Johnson295189b2012-06-20 16:38:30 -07004972 (int) scanId);
4973 }
4974
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304975 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07004976 pAdapter);
4977
4978 if (0 > ret)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304979 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004980
4981
4982 /* If any client wait scan result through WEXT
4983 * send scan done event to client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07004984 if (pHddCtx->scan_info.waitScanResult)
Jeff Johnson295189b2012-06-20 16:38:30 -07004985 {
4986 /* The other scan request waiting for current scan finish
4987 * Send event to notify current scan finished */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07004988 if(WEXT_SCAN_PENDING_DELAY == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -07004989 {
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07004990 vos_event_set(&pHddCtx->scan_info.scan_finished_event);
Jeff Johnson295189b2012-06-20 16:38:30 -07004991 }
4992 /* Send notify to WEXT client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07004993 else if(WEXT_SCAN_PENDING_PIGGYBACK == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -07004994 {
4995 struct net_device *dev = pAdapter->dev;
4996 union iwreq_data wrqu;
4997 int we_event;
4998 char *msg;
4999
5000 memset(&wrqu, '\0', sizeof(wrqu));
5001 we_event = SIOCGIWSCAN;
5002 msg = NULL;
5003 wireless_send_event(dev, we_event, &wrqu, msg);
5004 }
5005 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07005006 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07005007
5008 /* Get the Scan Req */
5009 req = pAdapter->request;
5010
5011 if (!req)
5012 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08005013 hddLog(VOS_TRACE_LEVEL_ERROR, "request is became NULL");
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07005014 pScanInfo->mScanPending = VOS_FALSE;
Jeff Johnsone7245742012-09-05 17:12:55 -07005015 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -07005016 }
5017
5018 /*
5019 * setting up 0, just in case.
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305020 */
Jeff Johnson295189b2012-06-20 16:38:30 -07005021 req->n_ssids = 0;
5022 req->n_channels = 0;
5023 req->ie = 0;
5024
Jeff Johnson295189b2012-06-20 16:38:30 -07005025 pAdapter->request = NULL;
Jeff Johnsone7245742012-09-05 17:12:55 -07005026 /* Scan is no longer pending */
5027 pScanInfo->mScanPending = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07005028
Madan Mohan Koyyalamudib764bf82012-10-11 16:38:51 -07005029 /*
5030 * cfg80211_scan_done informing NL80211 about completion
5031 * of scanning
5032 */
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +05305033 if (status == eCSR_SCAN_ABORT || status == eCSR_SCAN_FAILURE)
5034 {
5035 aborted = true;
5036 }
5037 cfg80211_scan_done(req, aborted);
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -08005038 complete(&pScanInfo->abortscan_event_var);
Jeff Johnson295189b2012-06-20 16:38:30 -07005039
Jeff Johnsone7245742012-09-05 17:12:55 -07005040allow_suspend:
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07005041 /* release the wake lock at the end of the scan*/
5042 hdd_allow_suspend();
Jeff Johnsone7245742012-09-05 17:12:55 -07005043
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -07005044 /* Acquire wakelock to handle the case where APP's tries to suspend
5045 * immediatly after the driver gets connect request(i.e after scan)
5046 * from supplicant, this result in app's is suspending and not able
5047 * to process the connect request to AP */
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +05305048 hdd_prevent_suspend_timeout(1000);
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -07005049
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07005050#ifdef FEATURE_WLAN_TDLS
5051 wlan_hdd_tdls_scan_done_callback(pAdapter);
5052#endif
5053
Jeff Johnson295189b2012-06-20 16:38:30 -07005054 EXIT();
5055 return 0;
5056}
5057
5058/*
Rashmi Ramannab1429032014-04-26 14:59:09 +05305059 * FUNCTION: hdd_isConnectionInProgress
5060 * Go through each adapter and check if Connection is in progress
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08005061 *
5062 */
Rashmi Ramannab1429032014-04-26 14:59:09 +05305063v_BOOL_t hdd_isConnectionInProgress( hdd_context_t *pHddCtx )
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08005064{
5065 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
5066 hdd_station_ctx_t *pHddStaCtx = NULL;
5067 hdd_adapter_t *pAdapter = NULL;
5068 VOS_STATUS status = 0;
5069 v_U8_t staId = 0;
5070 v_U8_t *staMac = NULL;
5071
c_hpothu9b781ba2013-12-30 20:57:45 +05305072 if (TRUE == pHddCtx->btCoexModeSet)
5073 {
5074 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Rashmi Ramannab1429032014-04-26 14:59:09 +05305075 FL("BTCoex Mode operation in progress"));
5076 return VOS_TRUE;
c_hpothu9b781ba2013-12-30 20:57:45 +05305077 }
5078
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08005079 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
5080
5081 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
5082 {
5083 pAdapter = pAdapterNode->pAdapter;
5084
5085 if( pAdapter )
5086 {
5087 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05305088 "%s: Adapter with device mode %s (%d) exists",
5089 __func__, hdd_device_modetoString(pAdapter->device_mode),
5090 pAdapter->device_mode);
Rashmi Ramannab1429032014-04-26 14:59:09 +05305091 if (((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
5092 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
5093 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode)) &&
5094 (eConnectionState_Connecting ==
5095 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
5096 {
5097 hddLog(VOS_TRACE_LEVEL_ERROR,
5098 "%s: %p(%d) Connection is in progress", __func__,
5099 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
5100 return VOS_TRUE;
5101 }
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08005102 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05305103 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
5104 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08005105 {
5106 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
5107 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05305108 (VOS_FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08005109 {
5110 staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]);
5111 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain24bafea2013-11-15 15:10:03 -08005112 "%s: client " MAC_ADDRESS_STR
5113 " is in the middle of WPS/EAPOL exchange.", __func__,
5114 MAC_ADDR_ARRAY(staMac));
Rashmi Ramannab1429032014-04-26 14:59:09 +05305115 return VOS_TRUE;
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08005116 }
5117 }
5118 else if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) ||
5119 (WLAN_HDD_P2P_GO == pAdapter->device_mode))
5120 {
5121 for (staId = 0; staId < WLAN_MAX_STA_COUNT; staId++)
5122 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305123 if ((pAdapter->aStaInfo[staId].isUsed) &&
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08005124 (WLANTL_STA_CONNECTED == pAdapter->aStaInfo[staId].tlSTAState))
5125 {
5126 staMac = (v_U8_t *) &(pAdapter->aStaInfo[staId].macAddrSTA.bytes[0]);
5127
5128 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain24bafea2013-11-15 15:10:03 -08005129 "%s: client " MAC_ADDRESS_STR " of SoftAP/P2P-GO is in the "
5130 "middle of WPS/EAPOL exchange.", __func__,
5131 MAC_ADDR_ARRAY(staMac));
Rashmi Ramannab1429032014-04-26 14:59:09 +05305132 return VOS_TRUE;
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08005133 }
5134 }
5135 }
5136 }
5137 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
5138 pAdapterNode = pNext;
5139 }
Rashmi Ramannab1429032014-04-26 14:59:09 +05305140 return VOS_FALSE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305141}
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08005142
5143/*
Jeff Johnson295189b2012-06-20 16:38:30 -07005144 * FUNCTION: wlan_hdd_cfg80211_scan
5145 * this scan respond to scan trigger and update cfg80211 scan database
5146 * later, scan dump command can be used to recieve scan results
5147 */
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -08005148int wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
5149#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
5150 struct net_device *dev,
5151#endif
5152 struct cfg80211_scan_request *request)
5153{
5154#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
5155 struct net_device *dev = request->wdev->netdev;
5156#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305157 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Jeff Johnson295189b2012-06-20 16:38:30 -07005158 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
5159 hdd_wext_state_t *pwextBuf = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305160 hdd_config_t *cfg_param = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07005161 tCsrScanRequest scanRequest;
5162 tANI_U8 *channelList = NULL, i;
5163 v_U32_t scanId = 0;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305164 int status;
5165 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07005166 v_U8_t* pP2pIe = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07005167
5168 ENTER();
5169
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05305170 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
5171 TRACE_CODE_HDD_CFG80211_SCAN,
5172 pAdapter->sessionId, request->n_channels));
5173
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05305174 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
5175 __func__, hdd_device_modetoString(pAdapter->device_mode),
5176 pAdapter->device_mode);
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08005177
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305178 status = wlan_hdd_validate_context(pHddCtx);
5179
5180 if (0 != status)
5181 {
5182 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5183 "%s: HDD context is not valid", __func__);
5184 return status;
5185 }
5186
5187 cfg_param = pHddCtx->cfg_ini;
5188 pScanInfo = &pHddCtx->scan_info;
5189
Jeff Johnson295189b2012-06-20 16:38:30 -07005190#ifdef WLAN_BTAMP_FEATURE
5191 //Scan not supported when AMP traffic is on.
Gopichand Nakkala681989c2013-03-06 22:27:48 -08005192 if (VOS_TRUE == WLANBAP_AmpSessionOn())
Jeff Johnson295189b2012-06-20 16:38:30 -07005193 {
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08005194 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07005195 "%s: No scanning when AMP is on", __func__);
5196 return -EOPNOTSUPP;
5197 }
5198#endif
5199 //Scan on any other interface is not supported.
Gopichand Nakkala681989c2013-03-06 22:27:48 -08005200 if (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07005201 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -08005202 hddLog(VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05305203 "%s: Not scanning on device_mode = %s (%d)",
5204 __func__, hdd_device_modetoString(pAdapter->device_mode),
5205 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07005206 return -EOPNOTSUPP;
5207 }
5208
5209 if (TRUE == pScanInfo->mScanPending)
5210 {
Kiet Lamac06e2c2013-10-23 16:25:07 +05305211 if ( MAX_PENDING_LOG > pScanInfo->mScanPendingCounter++ )
5212 {
5213 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: mScanPending is TRUE", __func__);
5214 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08005215 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -07005216 }
5217
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305218 //Don't Allow Scan and return busy if Remain On
Jeff Johnson32d95a32012-09-10 13:15:23 -07005219 //Channel and action frame is pending
5220 //Otherwise Cancel Remain On Channel and allow Scan
5221 //If no action frame pending
Gopichand Nakkala681989c2013-03-06 22:27:48 -08005222 if (0 != wlan_hdd_check_remain_on_channel(pAdapter))
Jeff Johnson32d95a32012-09-10 13:15:23 -07005223 {
Kiet Lamac06e2c2013-10-23 16:25:07 +05305224 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Remain On Channel Pending", __func__);
Jeff Johnson32d95a32012-09-10 13:15:23 -07005225 return -EBUSY;
5226 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08005227#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07005228 /* if tdls disagree scan right now, return immediately.
5229 tdls will schedule the scan when scan is allowed. (return SUCCESS)
5230 or will reject the scan if any TDLS is in progress. (return -EBUSY)
5231 */
5232 status = wlan_hdd_tdls_scan_callback (pAdapter,
5233 wiphy,
5234#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
5235 dev,
Gopichand Nakkalac3c42b92013-03-20 19:42:34 -07005236#endif
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07005237 request);
5238 if(status <= 0)
5239 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05305240 if(!status)
5241 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS in progress."
5242 "scan rejected %d", __func__, status);
5243 else
5244 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS teardown is ongoing %d",
5245 __func__, status);
5246
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07005247 return status;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08005248 }
5249#endif
Jeff Johnson32d95a32012-09-10 13:15:23 -07005250
Jeff Johnson295189b2012-06-20 16:38:30 -07005251 if (mutex_lock_interruptible(&pHddCtx->tmInfo.tmOperationLock))
5252 {
5253 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_ERROR,
Jeff Johnson1250df42012-12-10 14:31:52 -08005254 "%s: Acquire lock fail", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005255 return -EAGAIN;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305256 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005257 if (TRUE == pHddCtx->tmInfo.tmAction.enterImps)
5258 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05305259 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07005260 "%s: MAX TM Level Scan not allowed", __func__);
5261 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305262 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -07005263 }
5264 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
5265
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08005266 /* Check if scan is allowed at this point of time.
5267 */
Rashmi Ramannab1429032014-04-26 14:59:09 +05305268 if (hdd_isConnectionInProgress(pHddCtx))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08005269 {
5270 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Scan not allowed", __func__);
5271 return -EBUSY;
5272 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305273
Jeff Johnson295189b2012-06-20 16:38:30 -07005274 vos_mem_zero( &scanRequest, sizeof(scanRequest));
5275
5276 if (NULL != request)
5277 {
5278 hddLog(VOS_TRACE_LEVEL_INFO, "scan request for ssid = %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305279 (int)request->n_ssids);
Jeff Johnson295189b2012-06-20 16:38:30 -07005280
5281 /* Even though supplicant doesn't provide any SSIDs, n_ssids is set to 1.
5282 * Becasue of this, driver is assuming that this is not wildcard scan and so
5283 * is not aging out the scan results.
5284 */
Jeff Johnson32d95a32012-09-10 13:15:23 -07005285 if (request->ssids && '\0' == request->ssids->ssid[0])
Jeff Johnson295189b2012-06-20 16:38:30 -07005286 {
5287 request->n_ssids = 0;
5288 }
5289
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07005290 if ((request->ssids) && (0 < request->n_ssids))
Jeff Johnson295189b2012-06-20 16:38:30 -07005291 {
5292 tCsrSSIDInfo *SsidInfo;
5293 int j;
5294 scanRequest.SSIDs.numOfSSIDs = request->n_ssids;
5295 /* Allocate num_ssid tCsrSSIDInfo structure */
5296 SsidInfo = scanRequest.SSIDs.SSIDList =
5297 ( tCsrSSIDInfo *)vos_mem_malloc(
5298 request->n_ssids*sizeof(tCsrSSIDInfo));
5299
5300 if(NULL == scanRequest.SSIDs.SSIDList)
5301 {
5302 hddLog(VOS_TRACE_LEVEL_ERROR,
Nirav Shah20ac06f2013-12-12 18:14:06 +05305303 "%s: memory alloc failed SSIDInfo buffer", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005304 return -ENOMEM;
5305 }
5306
5307 /* copy all the ssid's and their length */
5308 for(j = 0; j < request->n_ssids; j++, SsidInfo++)
5309 {
5310 /* get the ssid length */
5311 SsidInfo->SSID.length = request->ssids[j].ssid_len;
5312 vos_mem_copy(SsidInfo->SSID.ssId, &request->ssids[j].ssid[0],
5313 SsidInfo->SSID.length);
5314 SsidInfo->SSID.ssId[SsidInfo->SSID.length] = '\0';
Nirav Shah20ac06f2013-12-12 18:14:06 +05305315 hddLog(VOS_TRACE_LEVEL_INFO, "SSID number %d: %s",
Jeff Johnson295189b2012-06-20 16:38:30 -07005316 j, SsidInfo->SSID.ssId);
5317 }
5318 /* set the scan type to active */
5319 scanRequest.scanType = eSIR_ACTIVE_SCAN;
5320 }
5321 else if(WLAN_HDD_P2P_GO == pAdapter->device_mode)
5322 {
5323 /* set the scan type to active */
5324 scanRequest.scanType = eSIR_ACTIVE_SCAN;
5325 }
5326 else
5327 {
5328 /*Set the scan type to default type, in this case it is ACTIVE*/
5329 scanRequest.scanType = pScanInfo->scan_mode;
5330 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305331 scanRequest.minChnTime = cfg_param->nActiveMinChnTime;
Jeff Johnson295189b2012-06-20 16:38:30 -07005332 scanRequest.maxChnTime = cfg_param->nActiveMaxChnTime;
5333 }
5334 else
5335 {
5336 /* set the scan type to active */
5337 scanRequest.scanType = eSIR_ACTIVE_SCAN;
5338 vos_mem_set( scanRequest.bssid, sizeof( tCsrBssid ), 0xff );
5339
5340 /* set min and max channel time to zero */
5341 scanRequest.minChnTime = 0;
5342 scanRequest.maxChnTime = 0;
5343 }
5344
5345 /* set BSSType to default type */
5346 scanRequest.BSSType = eCSR_BSS_TYPE_ANY;
5347
5348 /*TODO: scan the requested channels only*/
5349
5350 /*Right now scanning all the channels */
5351 if( request )
5352 {
c_hpothu53512302014-04-15 18:49:53 +05305353 if (MAX_CHANNEL < request->n_channels)
5354 {
5355 hddLog(VOS_TRACE_LEVEL_WARN,
5356 "No of Scan Channels exceeded limit: %d", request->n_channels);
5357 request->n_channels = MAX_CHANNEL;
5358 }
Nirav Shah20ac06f2013-12-12 18:14:06 +05305359 hddLog(VOS_TRACE_LEVEL_INFO,
5360 "No of Scan Channels: %d", request->n_channels);
c_hpothu53512302014-04-15 18:49:53 +05305361
Jeff Johnson295189b2012-06-20 16:38:30 -07005362 if( request->n_channels )
5363 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05305364 char chList [(request->n_channels*5)+1];
5365 int len;
Jeff Johnson295189b2012-06-20 16:38:30 -07005366 channelList = vos_mem_malloc( request->n_channels );
5367 if( NULL == channelList )
5368 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305369 hddLog(VOS_TRACE_LEVEL_ERROR,
Nirav Shah20ac06f2013-12-12 18:14:06 +05305370 "%s: memory alloc failed channelList", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005371 status = -ENOMEM;
5372 goto free_mem;
5373 }
5374
Nirav Shah20ac06f2013-12-12 18:14:06 +05305375 for( i = 0, len = 0; i < request->n_channels ; i++ )
5376 {
Jeff Johnson295189b2012-06-20 16:38:30 -07005377 channelList[i] = request->channels[i]->hw_value;
Nirav Shah20ac06f2013-12-12 18:14:06 +05305378 len += snprintf(chList+len, 5, "%d ", channelList[i]);
5379 }
5380
5381 hddLog(VOS_TRACE_LEVEL_INFO,
5382 "Channel-List: %s ", chList);
Jeff Johnson295189b2012-06-20 16:38:30 -07005383 }
5384
5385 scanRequest.ChannelInfo.numOfChannels = request->n_channels;
5386 scanRequest.ChannelInfo.ChannelList = channelList;
5387
5388 /* set requestType to full scan */
5389 scanRequest.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305390
5391 /* Flush the scan results(only p2p beacons) for STA scan and P2P
Madan Mohan Koyyalamudi8d50f312012-11-27 15:48:57 -08005392 * search (Flush on both full scan and social scan but not on single
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305393 * channel scan).P2P search happens on 3 social channels (1, 6, 11)
Madan Mohan Koyyalamudi8d50f312012-11-27 15:48:57 -08005394 */
5395
5396 /* Supplicant does single channel scan after 8-way handshake
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305397 * and in that case driver shoudnt flush scan results. If
5398 * driver flushes the scan results here and unfortunately if
5399 * the AP doesnt respond to our probe req then association
Madan Mohan Koyyalamudi8d50f312012-11-27 15:48:57 -08005400 * fails which is not desired
5401 */
5402
5403 if( request->n_channels != WLAN_HDD_P2P_SINGLE_CHANNEL_SCAN )
5404 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05305405 hddLog(VOS_TRACE_LEVEL_DEBUG, "Flushing P2P Results");
Madan Mohan Koyyalamudi8d50f312012-11-27 15:48:57 -08005406 sme_ScanFlushP2PResult( WLAN_HDD_GET_HAL_CTX(pAdapter),
5407 pAdapter->sessionId );
5408 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005409
5410 if( request->ie_len )
5411 {
5412 /* save this for future association (join requires this) */
Agarwal Ashish4f616132013-12-30 23:32:50 +05305413 /*TODO: Array needs to be converted to dynamic allocation,
5414 * as multiple ie.s can be sent in cfg80211_scan_request structure
5415 * CR 597966
5416 */
Jeff Johnson295189b2012-06-20 16:38:30 -07005417 memset( &pScanInfo->scanAddIE, 0, sizeof(pScanInfo->scanAddIE) );
5418 memcpy( pScanInfo->scanAddIE.addIEdata, request->ie, request->ie_len);
5419 pScanInfo->scanAddIE.length = request->ie_len;
5420
Agarwal Ashish4f616132013-12-30 23:32:50 +05305421 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Jeff Johnsone7245742012-09-05 17:12:55 -07005422 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
Agarwal Ashish4f616132013-12-30 23:32:50 +05305423 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -07005424 {
Agarwal Ashish4f616132013-12-30 23:32:50 +05305425 if ( request->ie_len <= SIR_MAC_MAX_IE_LENGTH)
5426 {
5427 pwextBuf->roamProfile.nAddIEScanLength = request->ie_len;
5428 memcpy( pwextBuf->roamProfile.addIEScan,
5429 request->ie, request->ie_len);
5430 }
5431 else
5432 {
5433 hddLog(VOS_TRACE_LEVEL_ERROR, "Scan Ie length is invalid:"
Arun Kumar Khandavalli75eeb122014-03-27 21:43:12 +05305434 "%zu", request->ie_len);
Agarwal Ashish4f616132013-12-30 23:32:50 +05305435 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005436
Agarwal Ashish4f616132013-12-30 23:32:50 +05305437 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005438 scanRequest.uIEFieldLen = pScanInfo->scanAddIE.length;
5439 scanRequest.pIEField = pScanInfo->scanAddIE.addIEdata;
5440
Jeff Johnson295189b2012-06-20 16:38:30 -07005441 pP2pIe = wlan_hdd_get_p2p_ie_ptr((v_U8_t*)request->ie,
5442 request->ie_len);
5443 if (pP2pIe != NULL)
5444 {
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07005445#ifdef WLAN_FEATURE_P2P_DEBUG
5446 if (((globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED) ||
5447 (globalP2PConnectionStatus == P2P_GO_NEG_PROCESS)) &&
5448 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
5449 {
5450 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_1;
5451 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
5452 "Go nego completed to Connection is started");
5453 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
5454 "for 8way Handshake");
5455 }
5456 else if((globalP2PConnectionStatus == P2P_CLIENT_DISCONNECTED_STATE) &&
5457 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
5458 {
5459 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_2;
5460 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
5461 "Disconnected state to Connection is started");
5462 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
5463 "for 4way Handshake");
5464 }
5465#endif
5466
Jeff Johnsone7245742012-09-05 17:12:55 -07005467 /* no_cck will be set during p2p find to disable 11b rates */
5468 if(TRUE == request->no_cck)
Jeff Johnson295189b2012-06-20 16:38:30 -07005469 {
Jeff Johnson295189b2012-06-20 16:38:30 -07005470 hddLog(VOS_TRACE_LEVEL_INFO,
5471 "%s: This is a P2P Search", __func__);
5472 scanRequest.p2pSearch = 1;
Jeff Johnsone7245742012-09-05 17:12:55 -07005473
Jeff Johnsone7245742012-09-05 17:12:55 -07005474 if( request->n_channels == WLAN_HDD_P2P_SOCIAL_CHANNELS )
5475 {
Madan Mohan Koyyalamudi1b1d9e82012-10-21 11:38:33 -07005476 /* set requestType to P2P Discovery */
5477 scanRequest.requestType = eCSR_SCAN_P2P_DISCOVERY;
Jeff Johnsone7245742012-09-05 17:12:55 -07005478 }
5479
5480 /*
5481 Skip Dfs Channel in case of P2P Search
5482 if it is set in ini file
5483 */
5484 if(cfg_param->skipDfsChnlInP2pSearch)
5485 {
5486 scanRequest.skipDfsChnlInP2pSearch = 1;
5487 }
5488 else
5489 {
5490 scanRequest.skipDfsChnlInP2pSearch = 0;
5491 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005492
Jeff Johnson295189b2012-06-20 16:38:30 -07005493 }
5494 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005495 }
5496 }
5497
5498 INIT_COMPLETION(pScanInfo->scan_req_completion_event);
5499
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07005500 /* acquire the wakelock to avoid the apps suspend during the scan. To
5501 * address the following issues.
5502 * 1) Disconnected scenario: we are not allowing the suspend as WLAN is not in
5503 * BMPS/IMPS this result in android trying to suspend aggressively and backing off
5504 * for long time, this result in apps running at full power for long time.
5505 * 2) Connected scenario: If we allow the suspend during the scan, RIVA will
5506 * be stuck in full power because of resume BMPS
5507 */
5508 hdd_prevent_suspend();
Jeff Johnsone7245742012-09-05 17:12:55 -07005509
Nirav Shah20ac06f2013-12-12 18:14:06 +05305510 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
5511 "requestType %d, scanType %d, minChnTime %d, maxChnTime %d,"
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05305512 "p2pSearch %d, skipDfsChnlInP2pSearch %d",
5513 scanRequest.requestType, scanRequest.scanType,
5514 scanRequest.minChnTime, scanRequest.maxChnTime,
Nirav Shah20ac06f2013-12-12 18:14:06 +05305515 scanRequest.p2pSearch, scanRequest.skipDfsChnlInP2pSearch);
5516
Jeff Johnsone7245742012-09-05 17:12:55 -07005517 status = sme_ScanRequest( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07005518 pAdapter->sessionId, &scanRequest, &scanId,
5519 &hdd_cfg80211_scan_done_callback, dev );
Jeff Johnsone7245742012-09-05 17:12:55 -07005520
Jeff Johnson295189b2012-06-20 16:38:30 -07005521 if (eHAL_STATUS_SUCCESS != status)
5522 {
5523 hddLog(VOS_TRACE_LEVEL_ERROR,
5524 "%s: sme_ScanRequest returned error %d", __func__, status);
5525 complete(&pScanInfo->scan_req_completion_event);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -07005526 if(eHAL_STATUS_RESOURCES == status)
5527 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05305528 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: HO is in progress."
5529 "So defer the scan by informing busy",__func__);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -07005530 status = -EBUSY;
5531 } else {
5532 status = -EIO;
5533 }
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07005534 hdd_allow_suspend();
Jeff Johnson295189b2012-06-20 16:38:30 -07005535 goto free_mem;
5536 }
5537
5538 pScanInfo->mScanPending = TRUE;
5539 pAdapter->request = request;
5540 pScanInfo->scanId = scanId;
5541
5542 complete(&pScanInfo->scan_req_completion_event);
5543
5544free_mem:
5545 if( scanRequest.SSIDs.SSIDList )
5546 {
5547 vos_mem_free(scanRequest.SSIDs.SSIDList);
5548 }
5549
5550 if( channelList )
5551 vos_mem_free( channelList );
5552
5553 EXIT();
5554
5555 return status;
5556}
5557
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07005558
5559void hdd_select_cbmode( hdd_adapter_t *pAdapter,v_U8_t operationChannel)
5560{
5561 v_U8_t iniDot11Mode =
5562 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->dot11Mode;
5563 eHddDot11Mode hddDot11Mode = iniDot11Mode;
5564
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +05305565 hddLog(LOG1, FL("Channel Bonding Mode Selected is %u"),
5566 iniDot11Mode);
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07005567 switch ( iniDot11Mode )
5568 {
5569 case eHDD_DOT11_MODE_AUTO:
5570 case eHDD_DOT11_MODE_11ac:
5571 case eHDD_DOT11_MODE_11ac_ONLY:
5572#ifdef WLAN_FEATURE_11AC
5573 hddDot11Mode = eHDD_DOT11_MODE_11ac;
5574#else
5575 hddDot11Mode = eHDD_DOT11_MODE_11n;
5576#endif
5577 break;
5578 case eHDD_DOT11_MODE_11n:
5579 case eHDD_DOT11_MODE_11n_ONLY:
5580 hddDot11Mode = eHDD_DOT11_MODE_11n;
5581 break;
5582 default:
5583 hddDot11Mode = iniDot11Mode;
5584 break;
5585 }
5586 /* This call decides required channel bonding mode */
5587 sme_SelectCBMode((WLAN_HDD_GET_CTX(pAdapter)->hHal),
5588 hdd_cfg_xlate_to_csr_phy_mode(hddDot11Mode),
5589 operationChannel);
5590}
5591
Jeff Johnson295189b2012-06-20 16:38:30 -07005592/*
5593 * FUNCTION: wlan_hdd_cfg80211_connect_start
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305594 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -07005595 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305596int wlan_hdd_cfg80211_connect_start( hdd_adapter_t *pAdapter,
Jeff Johnson32d95a32012-09-10 13:15:23 -07005597 const u8 *ssid, size_t ssid_len, const u8 *bssid, u8 operatingChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -07005598{
5599 int status = 0;
5600 hdd_wext_state_t *pWextState;
Yue Mae36e3552014-03-05 17:06:20 -08005601 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07005602 v_U32_t roamId;
5603 tCsrRoamProfile *pRoamProfile;
Jeff Johnson295189b2012-06-20 16:38:30 -07005604 eCsrAuthType RSNAuthType;
5605
5606 ENTER();
5607
5608 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Yue Mae36e3552014-03-05 17:06:20 -08005609 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
5610
5611 status = wlan_hdd_validate_context(pHddCtx);
5612 if (status)
5613 {
5614 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5615 "%s: HDD context is not valid!", __func__);
5616 return status;
5617 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305618
Jeff Johnson295189b2012-06-20 16:38:30 -07005619 if (SIR_MAC_MAX_SSID_LENGTH < ssid_len)
5620 {
5621 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wrong SSID len", __func__);
5622 return -EINVAL;
5623 }
5624
5625 pRoamProfile = &pWextState->roamProfile;
5626
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305627 if (pRoamProfile)
Jeff Johnson295189b2012-06-20 16:38:30 -07005628 {
Jeff Johnsone7245742012-09-05 17:12:55 -07005629 hdd_station_ctx_t *pHddStaCtx;
5630 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07005631
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305632 if (HDD_WMM_USER_MODE_NO_QOS ==
Jeff Johnson295189b2012-06-20 16:38:30 -07005633 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->WmmMode)
5634 {
5635 /*QoS not enabled in cfg file*/
5636 pRoamProfile->uapsd_mask = 0;
5637 }
5638 else
5639 {
5640 /*QoS enabled, update uapsd mask from cfg file*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305641 pRoamProfile->uapsd_mask =
Jeff Johnson295189b2012-06-20 16:38:30 -07005642 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask;
5643 }
5644
5645 pRoamProfile->SSIDs.numOfSSIDs = 1;
5646 pRoamProfile->SSIDs.SSIDList->SSID.length = ssid_len;
5647 vos_mem_zero(pRoamProfile->SSIDs.SSIDList->SSID.ssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305648 sizeof(pRoamProfile->SSIDs.SSIDList->SSID.ssId));
Jeff Johnson295189b2012-06-20 16:38:30 -07005649 vos_mem_copy((void *)(pRoamProfile->SSIDs.SSIDList->SSID.ssId),
5650 ssid, ssid_len);
5651
5652 if (bssid)
5653 {
5654 pRoamProfile->BSSIDs.numOfBSSIDs = 1;
5655 vos_mem_copy((void *)(pRoamProfile->BSSIDs.bssid), bssid,
5656 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305657 /* Save BSSID in seperate variable as well, as RoamProfile
5658 BSSID is getting zeroed out in the association process. And in
Jeff Johnson295189b2012-06-20 16:38:30 -07005659 case of join failure we should send valid BSSID to supplicant
5660 */
5661 vos_mem_copy((void *)(pWextState->req_bssId), bssid,
5662 WNI_CFG_BSSID_LEN);
5663 }
Dhanashri Atre51981c62013-06-13 11:47:57 -07005664 else
5665 {
5666 vos_mem_zero((void *)(pRoamProfile->BSSIDs.bssid),WNI_CFG_BSSID_LEN);
5667 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005668
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +05305669 hddLog(LOG1, FL("Connect to SSID: %s opertating Channel: %u"),
5670 pRoamProfile->SSIDs.SSIDList->SSID.ssId, operatingChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -07005671 if ((IW_AUTH_WPA_VERSION_WPA == pWextState->wpaVersion) ||
5672 (IW_AUTH_WPA_VERSION_WPA2 == pWextState->wpaVersion))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305673 {
Jeff Johnson295189b2012-06-20 16:38:30 -07005674 /*set gen ie*/
5675 hdd_SetGENIEToCsr(pAdapter, &RSNAuthType);
5676 /*set auth*/
5677 hdd_set_csr_auth_type(pAdapter, RSNAuthType);
5678 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005679#ifdef FEATURE_WLAN_WAPI
5680 if (pAdapter->wapi_info.nWapiMode)
5681 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005682 hddLog(LOG1, "%s: Setting WAPI AUTH Type and Encryption Mode values", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005683 switch (pAdapter->wapi_info.wapiAuthMode)
5684 {
5685 case WAPI_AUTH_MODE_PSK:
5686 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005687 hddLog(LOG1, "%s: WAPI AUTH TYPE: PSK: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07005688 pAdapter->wapi_info.wapiAuthMode);
5689 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_PSK;
5690 break;
5691 }
5692 case WAPI_AUTH_MODE_CERT:
5693 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005694 hddLog(LOG1, "%s: WAPI AUTH TYPE: CERT: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07005695 pAdapter->wapi_info.wapiAuthMode);
5696 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE;
5697 break;
5698 }
5699 } // End of switch
5700 if ( pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_PSK ||
5701 pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_CERT)
5702 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005703 hddLog(LOG1, "%s: WAPI PAIRWISE/GROUP ENCRYPTION: WPI", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005704 pRoamProfile->AuthType.numEntries = 1;
5705 pRoamProfile->EncryptionType.numEntries = 1;
5706 pRoamProfile->EncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
5707 pRoamProfile->mcEncryptionType.numEntries = 1;
5708 pRoamProfile->mcEncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
5709 }
5710 }
5711#endif /* FEATURE_WLAN_WAPI */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05305712#ifdef WLAN_FEATURE_GTK_OFFLOAD
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05305713 /* Initializing gtkOffloadReqParams */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05305714 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
5715 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
5716 {
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05305717 memset(&pHddStaCtx->gtkOffloadReqParams, 0,
5718 sizeof (tSirGtkOffloadParams));
5719 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_DISABLE;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05305720 }
5721#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005722 pRoamProfile->csrPersona = pAdapter->device_mode;
5723
Jeff Johnson32d95a32012-09-10 13:15:23 -07005724 if( operatingChannel )
5725 {
5726 pRoamProfile->ChannelInfo.ChannelList = &operatingChannel;
5727 pRoamProfile->ChannelInfo.numOfChannels = 1;
5728 }
Chet Lanctot186b5732013-03-18 10:26:30 -07005729 else
5730 {
5731 pRoamProfile->ChannelInfo.ChannelList = NULL;
5732 pRoamProfile->ChannelInfo.numOfChannels = 0;
5733 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07005734 if ( (WLAN_HDD_IBSS == pAdapter->device_mode) && operatingChannel)
5735 {
5736 hdd_select_cbmode(pAdapter,operatingChannel);
5737 }
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +05305738
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08005739 /* change conn_state to connecting before sme_RoamConnect(), because sme_RoamConnect()
5740 * has a direct path to call hdd_smeRoamCallback(), which will change the conn_state
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305741 * If direct path, conn_state will be accordingly changed to NotConnected or Associated
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08005742 * by either hdd_AssociationCompletionHandler() or hdd_DisConnectHandler() in sme_RoamCallback()
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -08005743 * if sme_RomConnect is to be queued, Connecting state will remain until it is completed.
5744 */
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05305745 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
5746 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode)
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -08005747 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
5748 eConnectionState_Connecting);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305749
5750 status = sme_RoamConnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07005751 pAdapter->sessionId, pRoamProfile, &roamId);
5752
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05305753 if ((eHAL_STATUS_SUCCESS != status) &&
5754 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
5755 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +05305756
5757 {
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08005758 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: sme_RoamConnect (session %d) failed with "
5759 "status %d. -> NotConnected", __func__, pAdapter->sessionId, status);
5760 /* change back to NotAssociated */
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +05305761 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08005762 eConnectionState_NotConnected);
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +05305763 }
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -08005764
5765 pRoamProfile->ChannelInfo.ChannelList = NULL;
5766 pRoamProfile->ChannelInfo.numOfChannels = 0;
5767
Jeff Johnson295189b2012-06-20 16:38:30 -07005768 }
5769 else
5770 {
5771 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid Roam profile", __func__);
5772 return -EINVAL;
5773 }
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08005774 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07005775 return status;
5776}
5777
5778/*
5779 * FUNCTION: wlan_hdd_set_cfg80211_auth_type
5780 * This function is used to set the authentication type (OPEN/SHARED).
5781 *
5782 */
5783static int wlan_hdd_cfg80211_set_auth_type(hdd_adapter_t *pAdapter,
5784 enum nl80211_auth_type auth_type)
5785{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305786 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07005787 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
5788
5789 ENTER();
5790
5791 /*set authentication type*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305792 switch (auth_type)
Jeff Johnson295189b2012-06-20 16:38:30 -07005793 {
Jeff Johnson295189b2012-06-20 16:38:30 -07005794 case NL80211_AUTHTYPE_AUTOMATIC:
Gopichand Nakkala29149562013-05-10 21:43:41 +05305795 hddLog(VOS_TRACE_LEVEL_INFO,
5796 "%s: set authentication type to AUTOSWITCH", __func__);
5797 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_AUTOSWITCH;
5798 break;
5799
5800 case NL80211_AUTHTYPE_OPEN_SYSTEM:
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07005801#ifdef WLAN_FEATURE_VOWIFI_11R
5802 case NL80211_AUTHTYPE_FT:
5803#endif /* WLAN_FEATURE_VOWIFI_11R */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305804 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -07005805 "%s: set authentication type to OPEN", __func__);
5806 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
5807 break;
5808
5809 case NL80211_AUTHTYPE_SHARED_KEY:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305810 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -07005811 "%s: set authentication type to SHARED", __func__);
5812 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_SHARED_KEY;
5813 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005814#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -07005815 case NL80211_AUTHTYPE_NETWORK_EAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305816 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -07005817 "%s: set authentication type to CCKM WPA", __func__);
5818 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_CCKM_WPA;//eCSR_AUTH_TYPE_CCKM_RSN needs to be handled as well if required.
5819 break;
5820#endif
5821
5822
5823 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305824 hddLog(VOS_TRACE_LEVEL_ERROR,
5825 "%s: Unsupported authentication type %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07005826 auth_type);
5827 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_UNKNOWN;
5828 return -EINVAL;
5829 }
5830
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305831 pWextState->roamProfile.AuthType.authType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -07005832 pHddStaCtx->conn_info.authType;
5833 return 0;
5834}
5835
5836/*
5837 * FUNCTION: wlan_hdd_set_akm_suite
5838 * This function is used to set the key mgmt type(PSK/8021x).
5839 *
5840 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305841static int wlan_hdd_set_akm_suite( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07005842 u32 key_mgmt
5843 )
5844{
5845 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
5846 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305847
Jeff Johnson295189b2012-06-20 16:38:30 -07005848 /*set key mgmt type*/
5849 switch(key_mgmt)
5850 {
5851 case WLAN_AKM_SUITE_PSK:
Gopichand Nakkala356fb102013-03-06 12:34:04 +05305852#ifdef WLAN_FEATURE_VOWIFI_11R
5853 case WLAN_AKM_SUITE_FT_PSK:
5854#endif
5855 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to PSK",
Jeff Johnson295189b2012-06-20 16:38:30 -07005856 __func__);
5857 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_PSK;
5858 break;
5859
5860 case WLAN_AKM_SUITE_8021X:
Gopichand Nakkala356fb102013-03-06 12:34:04 +05305861#ifdef WLAN_FEATURE_VOWIFI_11R
5862 case WLAN_AKM_SUITE_FT_8021X:
5863#endif
5864 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to 8021x",
Jeff Johnson295189b2012-06-20 16:38:30 -07005865 __func__);
5866 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
5867 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005868#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -07005869#define WLAN_AKM_SUITE_CCKM 0x00409600 /* Should be in ieee802_11_defs.h */
5870#define IW_AUTH_KEY_MGMT_CCKM 8 /* Should be in linux/wireless.h */
5871 case WLAN_AKM_SUITE_CCKM:
5872 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to CCKM",
5873 __func__);
5874 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_CCKM;
5875 break;
5876#endif
Leela Venkata Kiran Kumar Reddy Chiralae208a832014-04-27 22:34:25 -07005877#ifndef WLAN_AKM_SUITE_OSEN
5878#define WLAN_AKM_SUITE_OSEN 0x506f9a01 /* Should be in ieee802_11_defs.h */
5879 case WLAN_AKM_SUITE_OSEN:
5880 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to OSEN",
5881 __func__);
5882 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
5883 break;
5884#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005885
5886 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305887 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported key mgmt type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07005888 __func__, key_mgmt);
5889 return -EINVAL;
5890
5891 }
5892 return 0;
5893}
5894
5895/*
5896 * FUNCTION: wlan_hdd_cfg80211_set_cipher
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305897 * This function is used to set the encryption type
Jeff Johnson295189b2012-06-20 16:38:30 -07005898 * (NONE/WEP40/WEP104/TKIP/CCMP).
5899 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305900static int wlan_hdd_cfg80211_set_cipher( hdd_adapter_t *pAdapter,
5901 u32 cipher,
Jeff Johnson295189b2012-06-20 16:38:30 -07005902 bool ucast
5903 )
5904{
5905 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305906 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07005907 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
5908
5909 ENTER();
5910
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305911 if (!cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -07005912 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305913 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: received cipher %d - considering none",
Jeff Johnson295189b2012-06-20 16:38:30 -07005914 __func__, cipher);
5915 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
5916 }
5917 else
5918 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305919
Jeff Johnson295189b2012-06-20 16:38:30 -07005920 /*set encryption method*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305921 switch (cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -07005922 {
5923 case IW_AUTH_CIPHER_NONE:
5924 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
5925 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305926
Jeff Johnson295189b2012-06-20 16:38:30 -07005927 case WLAN_CIPHER_SUITE_WEP40:
Gopichand Nakkala29149562013-05-10 21:43:41 +05305928 encryptionType = eCSR_ENCRYPT_TYPE_WEP40;
Jeff Johnson295189b2012-06-20 16:38:30 -07005929 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305930
Jeff Johnson295189b2012-06-20 16:38:30 -07005931 case WLAN_CIPHER_SUITE_WEP104:
Gopichand Nakkala29149562013-05-10 21:43:41 +05305932 encryptionType = eCSR_ENCRYPT_TYPE_WEP104;
Jeff Johnson295189b2012-06-20 16:38:30 -07005933 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305934
Jeff Johnson295189b2012-06-20 16:38:30 -07005935 case WLAN_CIPHER_SUITE_TKIP:
5936 encryptionType = eCSR_ENCRYPT_TYPE_TKIP;
5937 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305938
Jeff Johnson295189b2012-06-20 16:38:30 -07005939 case WLAN_CIPHER_SUITE_CCMP:
5940 encryptionType = eCSR_ENCRYPT_TYPE_AES;
5941 break;
5942#ifdef FEATURE_WLAN_WAPI
5943 case WLAN_CIPHER_SUITE_SMS4:
5944 encryptionType = eCSR_ENCRYPT_TYPE_WPI;
5945 break;
5946#endif
5947
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005948#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -07005949 case WLAN_CIPHER_SUITE_KRK:
5950 encryptionType = eCSR_ENCRYPT_TYPE_KRK;
5951 break;
5952#endif
5953 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305954 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported cipher type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07005955 __func__, cipher);
5956 return -EOPNOTSUPP;
5957 }
5958 }
5959
5960 if (ucast)
5961 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305962 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting unicast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07005963 __func__, encryptionType);
5964 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
5965 pWextState->roamProfile.EncryptionType.numEntries = 1;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305966 pWextState->roamProfile.EncryptionType.encryptionType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -07005967 encryptionType;
5968 }
5969 else
5970 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305971 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting mcast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07005972 __func__, encryptionType);
5973 pHddStaCtx->conn_info.mcEncryptionType = encryptionType;
5974 pWextState->roamProfile.mcEncryptionType.numEntries = 1;
5975 pWextState->roamProfile.mcEncryptionType.encryptionType[0] = encryptionType;
5976 }
5977
5978 return 0;
5979}
5980
5981
5982/*
5983 * FUNCTION: wlan_hdd_cfg80211_set_ie
5984 * This function is used to parse WPA/RSN IE's.
5985 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305986int wlan_hdd_cfg80211_set_ie( hdd_adapter_t *pAdapter,
5987 u8 *ie,
Jeff Johnson295189b2012-06-20 16:38:30 -07005988 size_t ie_len
5989 )
5990{
5991 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
5992 u8 *genie = ie;
5993 v_U16_t remLen = ie_len;
5994#ifdef FEATURE_WLAN_WAPI
5995 v_U32_t akmsuite[MAX_NUM_AKM_SUITES];
5996 u16 *tmp;
5997 v_U16_t akmsuiteCount;
5998 int *akmlist;
5999#endif
6000 ENTER();
6001
6002 /* clear previous assocAddIE */
6003 pWextState->assocAddIE.length = 0;
6004 pWextState->roamProfile.bWPSAssociation = VOS_FALSE;
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -07006005 pWextState->roamProfile.bOSENAssociation = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07006006
6007 while (remLen >= 2)
6008 {
6009 v_U16_t eLen = 0;
6010 v_U8_t elementId;
6011 elementId = *genie++;
6012 eLen = *genie++;
6013 remLen -= 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306014
Arif Hussain6d2a3322013-11-17 19:50:10 -08006015 hddLog(VOS_TRACE_LEVEL_INFO, "%s: IE[0x%X], LEN[%d]",
Jeff Johnson295189b2012-06-20 16:38:30 -07006016 __func__, elementId, eLen);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306017
6018 switch ( elementId )
Jeff Johnson295189b2012-06-20 16:38:30 -07006019 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306020 case DOT11F_EID_WPA:
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07006021 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 -07006022 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306023 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07006024 "%s: Invalid WPA IE", __func__);
6025 return -EINVAL;
6026 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306027 else if (0 == memcmp(&genie[0], "\x00\x50\xf2\x04", 4))
Jeff Johnson295189b2012-06-20 16:38:30 -07006028 {
6029 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306030 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPS IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -07006031 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306032
Jeff Johnson295189b2012-06-20 16:38:30 -07006033 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
6034 {
Jeff Johnson902c9832012-12-10 14:28:09 -08006035 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE. "
6036 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -07006037 VOS_ASSERT(0);
6038 return -ENOMEM;
6039 }
6040 // WSC IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
6041 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
6042 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306043
Jeff Johnson295189b2012-06-20 16:38:30 -07006044 pWextState->roamProfile.bWPSAssociation = VOS_TRUE;
6045 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
6046 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
6047 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306048 else if (0 == memcmp(&genie[0], "\x00\x50\xf2", 3))
6049 {
Jeff Johnson295189b2012-06-20 16:38:30 -07006050 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPA IE (len %d)",__func__, eLen + 2);
6051 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
6052 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2) /*ie_len*/);
6053 pWextState->roamProfile.pWPAReqIE = pWextState->WPARSNIE;
6054 pWextState->roamProfile.nWPAReqIELength = eLen + 2;//ie_len;
6055 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306056 else if ( (0 == memcmp(&genie[0], P2P_OUI_TYPE,
Kiet Lam8da98992013-11-21 15:59:07 +05306057 P2P_OUI_TYPE_SIZE)))
Jeff Johnson295189b2012-06-20 16:38:30 -07006058 {
6059 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306060 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set P2P IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -07006061 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306062
Jeff Johnson295189b2012-06-20 16:38:30 -07006063 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
6064 {
Jeff Johnson902c9832012-12-10 14:28:09 -08006065 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
6066 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -07006067 VOS_ASSERT(0);
6068 return -ENOMEM;
6069 }
6070 // P2P IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
6071 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
6072 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306073
Jeff Johnson295189b2012-06-20 16:38:30 -07006074 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
6075 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
6076 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006077#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306078 else if ( (0 == memcmp(&genie[0], WFD_OUI_TYPE,
6079 WFD_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07006080 /*Consider WFD IE, only for P2P Client */
6081 && (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
6082 {
6083 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306084 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WFD IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -07006085 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306086
Jeff Johnson295189b2012-06-20 16:38:30 -07006087 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
6088 {
Jeff Johnson902c9832012-12-10 14:28:09 -08006089 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
6090 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -07006091 VOS_ASSERT(0);
6092 return -ENOMEM;
6093 }
6094 // WFD IE is saved to Additional IE ; it should be accumulated to handle
6095 // WPS IE + P2P IE + WFD IE
6096 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
6097 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306098
Jeff Johnson295189b2012-06-20 16:38:30 -07006099 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
6100 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
6101 }
6102#endif
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07006103 /* Appending HS 2.0 Indication Element in Assiciation Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306104 else if ( (0 == memcmp(&genie[0], HS20_OUI_TYPE,
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07006105 HS20_OUI_TYPE_SIZE)) )
6106 {
6107 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306108 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set HS20 IE(len %d)",
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07006109 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07006110
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07006111 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
6112 {
Jeff Johnson902c9832012-12-10 14:28:09 -08006113 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
6114 "Need bigger buffer space");
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07006115 VOS_ASSERT(0);
6116 return -ENOMEM;
6117 }
6118 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
6119 pWextState->assocAddIE.length += eLen + 2;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07006120
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07006121 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
6122 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
6123 }
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -07006124 /* Appending OSEN Information Element in Assiciation Request */
6125 else if ( (0 == memcmp(&genie[0], OSEN_OUI_TYPE,
6126 OSEN_OUI_TYPE_SIZE)) )
6127 {
6128 v_U16_t curAddIELen = pWextState->assocAddIE.length;
6129 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set OSEN IE(len %d)",
6130 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07006131
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -07006132 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
6133 {
6134 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
6135 "Need bigger buffer space");
6136 VOS_ASSERT(0);
6137 return -ENOMEM;
6138 }
6139 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
6140 pWextState->assocAddIE.length += eLen + 2;
6141
6142 pWextState->roamProfile.bOSENAssociation = VOS_TRUE;
6143 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
6144 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
6145 }
6146
6147 break;
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -07006148 if (WLAN_HDD_IBSS == pAdapter->device_mode) {
6149
6150 /* populating as ADDIE in beacon frames */
6151 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
6152 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, genie - 2, eLen + 2,
6153 NULL, eANI_BOOLEAN_FALSE)== eHAL_STATUS_SUCCESS)
6154 {
6155 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
6156 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
6157 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
6158 {
6159 hddLog(LOGE,
6160 "Coldn't pass "
6161 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
6162 }
6163 }/* ccmCfgSetStr(,WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, , )*/
6164 else
6165 hddLog(LOGE,
6166 "Could not pass on "
6167 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
6168
6169 /* IBSS mode doesn't contain params->proberesp_ies still
6170 beaconIE's need to be populated in probe response frames */
6171 if ( (NULL != (genie - 2)) && (0 != eLen + 2) )
6172 {
6173 u16 rem_probe_resp_ie_len = eLen + 2;
6174 u8 probe_rsp_ie_len[3] = {0};
6175 u8 counter = 0;
6176
6177 /* Check Probe Resp Length if it is greater then 255 then
6178 Store Probe Rsp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1
6179 & WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are
6180 not able Store More then 255 bytes into One Variable */
6181
6182 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
6183 {
6184 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
6185 {
6186 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
6187 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
6188 }
6189 else
6190 {
6191 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
6192 rem_probe_resp_ie_len = 0;
6193 }
6194 }
6195
6196 rem_probe_resp_ie_len = 0;
6197
6198 if (probe_rsp_ie_len[0] > 0)
6199 {
6200 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
6201 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
6202 (tANI_U8*)(genie - 2),
6203 probe_rsp_ie_len[0], NULL,
6204 eANI_BOOLEAN_FALSE)
6205 == eHAL_STATUS_FAILURE)
6206 {
6207 hddLog(LOGE,
6208 "Could not pass"
6209 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
6210 }
6211 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
6212 }
6213
6214 if (probe_rsp_ie_len[1] > 0)
6215 {
6216 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
6217 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
6218 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
6219 probe_rsp_ie_len[1], NULL,
6220 eANI_BOOLEAN_FALSE)
6221 == eHAL_STATUS_FAILURE)
6222 {
6223 hddLog(LOGE,
6224 "Could not pass"
6225 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
6226 }
6227 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
6228 }
6229
6230 if (probe_rsp_ie_len[2] > 0)
6231 {
6232 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
6233 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
6234 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
6235 probe_rsp_ie_len[2], NULL,
6236 eANI_BOOLEAN_FALSE)
6237 == eHAL_STATUS_FAILURE)
6238 {
6239 hddLog(LOGE,
6240 "Could not pass"
6241 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
6242 }
6243 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
6244 }
6245
6246 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
6247 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
6248 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
6249 {
6250 hddLog(LOGE,
6251 "Could not pass"
6252 "on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
6253 }
6254 }
6255 else
6256 {
6257 // Reset WNI_CFG_PROBE_RSP Flags
6258 wlan_hdd_reset_prob_rspies(pAdapter);
6259
6260 hddLog(VOS_TRACE_LEVEL_INFO,
6261 "%s: No Probe Response IE received in set beacon",
6262 __func__);
6263 }
6264 } /* end of if (WLAN_HDD_IBSS == pAdapter->device_mode) */
Jeff Johnson295189b2012-06-20 16:38:30 -07006265 break;
6266 case DOT11F_EID_RSN:
6267 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set RSN IE(len %d)",__func__, eLen + 2);
6268 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
6269 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2)/*ie_len*/);
6270 pWextState->roamProfile.pRSNReqIE = pWextState->WPARSNIE;
6271 pWextState->roamProfile.nRSNReqIELength = eLen + 2; //ie_len;
6272 break;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07006273 /* Appending Extended Capabilities with Interworking bit set in Assoc Req */
6274 case DOT11F_EID_EXTCAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306275 {
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07006276 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306277 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set Extended CAPS IE(len %d)",
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07006278 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306279
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07006280 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
6281 {
Jeff Johnson902c9832012-12-10 14:28:09 -08006282 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
6283 "Need bigger buffer space");
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07006284 VOS_ASSERT(0);
6285 return -ENOMEM;
6286 }
6287 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
6288 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306289
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07006290 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
6291 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
6292 break;
6293 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006294#ifdef FEATURE_WLAN_WAPI
6295 case WLAN_EID_WAPI:
6296 pAdapter->wapi_info.nWapiMode = 1; //Setting WAPI Mode to ON=1
Jeff Johnson0299d0a2013-10-30 12:37:43 -07006297 hddLog(VOS_TRACE_LEVEL_INFO, "WAPI MODE IS %u",
Jeff Johnson295189b2012-06-20 16:38:30 -07006298 pAdapter->wapi_info.nWapiMode);
6299 tmp = (u16 *)ie;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306300 tmp = tmp + 2; // Skip element Id and Len, Version
Jeff Johnson295189b2012-06-20 16:38:30 -07006301 akmsuiteCount = WPA_GET_LE16(tmp);
6302 tmp = tmp + 1;
6303 akmlist = (int *)(tmp);
6304 if(akmsuiteCount <= MAX_NUM_AKM_SUITES)
6305 {
6306 memcpy(akmsuite, akmlist, (4*akmsuiteCount));
6307 }
6308 else
6309 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08006310 hddLog(VOS_TRACE_LEVEL_FATAL, "Invalid akmSuite count");
Jeff Johnson295189b2012-06-20 16:38:30 -07006311 VOS_ASSERT(0);
6312 return -EINVAL;
6313 }
6314
6315 if (WAPI_PSK_AKM_SUITE == akmsuite[0])
6316 {
6317 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO PSK",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006318 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006319 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_PSK;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306320 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006321 if (WAPI_CERT_AKM_SUITE == akmsuite[0])
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306322 {
Jeff Johnson295189b2012-06-20 16:38:30 -07006323 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO CERTIFICATE",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006324 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006325 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_CERT;
6326 }
6327 break;
6328#endif
6329 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306330 hddLog (VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07006331 "%s Set UNKNOWN IE %X", __func__, elementId);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07006332 /* when Unknown IE is received we should break and continue
6333 * to the next IE in the buffer instead we were returning
6334 * so changing this to break */
6335 break;
Jeff Johnson295189b2012-06-20 16:38:30 -07006336 }
6337 genie += eLen;
6338 remLen -= eLen;
6339 }
6340 EXIT();
6341 return 0;
6342}
6343
6344/*
Gopichand Nakkala18f0c262013-05-07 23:25:08 +05306345 * FUNCTION: hdd_isWPAIEPresent
6346 * Parse the received IE to find the WPA IE
6347 *
6348 */
6349static bool hdd_isWPAIEPresent(u8 *ie, u8 ie_len)
6350{
6351 v_U8_t eLen = 0;
6352 v_U16_t remLen = ie_len;
6353 v_U8_t elementId = 0;
6354
6355 while (remLen >= 2)
6356 {
6357 elementId = *ie++;
6358 eLen = *ie++;
6359 remLen -= 2;
6360 if (eLen > remLen)
6361 {
6362 hddLog(VOS_TRACE_LEVEL_ERROR,
6363 "%s: IE length is wrong %d", __func__, eLen);
6364 return FALSE;
6365 }
6366 if ((elementId == DOT11F_EID_WPA) && (remLen > 5))
6367 {
6368 /* OUI - 0x00 0X50 0XF2
6369 WPA Information Element - 0x01
6370 WPA version - 0x01*/
6371 if (0 == memcmp(&ie[0], "\x00\x50\xf2\x01\x01", 5))
6372 return TRUE;
6373 }
6374 ie += eLen;
6375 remLen -= eLen;
6376 }
6377 return FALSE;
6378}
6379
6380/*
Jeff Johnson295189b2012-06-20 16:38:30 -07006381 * FUNCTION: wlan_hdd_cfg80211_set_privacy
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306382 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -07006383 * parameters during connect operation.
6384 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306385int wlan_hdd_cfg80211_set_privacy( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07006386 struct cfg80211_connect_params *req
6387 )
6388{
6389 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306390 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07006391 ENTER();
6392
6393 /*set wpa version*/
6394 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
6395
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306396 if (req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -07006397 {
Gopichand Nakkala781ded42013-06-28 12:10:45 +05306398 if (NL80211_WPA_VERSION_1 == req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -07006399 {
6400 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
6401 }
6402 else if (NL80211_WPA_VERSION_2 == req->crypto.wpa_versions)
6403 {
6404 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
6405 }
6406 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306407
6408 hddLog(VOS_TRACE_LEVEL_INFO, "%s: set wpa version to %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07006409 pWextState->wpaVersion);
6410
6411 /*set authentication type*/
6412 status = wlan_hdd_cfg80211_set_auth_type(pAdapter, req->auth_type);
6413
6414 if (0 > status)
6415 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306416 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07006417 "%s: failed to set authentication type ", __func__);
6418 return status;
6419 }
6420
6421 /*set key mgmt type*/
6422 if (req->crypto.n_akm_suites)
6423 {
6424 status = wlan_hdd_set_akm_suite(pAdapter, req->crypto.akm_suites[0]);
6425 if (0 > status)
6426 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306427 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set akm suite",
Jeff Johnson295189b2012-06-20 16:38:30 -07006428 __func__);
6429 return status;
6430 }
6431 }
6432
6433 /*set pairwise cipher type*/
6434 if (req->crypto.n_ciphers_pairwise)
6435 {
6436 status = wlan_hdd_cfg80211_set_cipher(pAdapter,
6437 req->crypto.ciphers_pairwise[0], true);
6438 if (0 > status)
6439 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306440 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07006441 "%s: failed to set unicast cipher type", __func__);
6442 return status;
6443 }
6444 }
6445 else
6446 {
6447 /*Reset previous cipher suite to none*/
6448 status = wlan_hdd_cfg80211_set_cipher(pAdapter, 0, true);
6449 if (0 > status)
6450 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306451 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07006452 "%s: failed to set unicast cipher type", __func__);
6453 return status;
6454 }
6455 }
6456
6457 /*set group cipher type*/
6458 status = wlan_hdd_cfg80211_set_cipher(pAdapter, req->crypto.cipher_group,
6459 false);
6460
6461 if (0 > status)
6462 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306463 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set mcast cipher type",
Jeff Johnson295189b2012-06-20 16:38:30 -07006464 __func__);
6465 return status;
6466 }
6467
Chet Lanctot186b5732013-03-18 10:26:30 -07006468#ifdef WLAN_FEATURE_11W
6469 pWextState->roamProfile.MFPEnabled = (req->mfp == NL80211_MFP_REQUIRED);
6470#endif
6471
Jeff Johnson295189b2012-06-20 16:38:30 -07006472 /*parse WPA/RSN IE, and set the correspoing fileds in Roam profile*/
6473 if (req->ie_len)
6474 {
6475 status = wlan_hdd_cfg80211_set_ie(pAdapter, req->ie, req->ie_len);
6476 if ( 0 > status)
6477 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306478 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse the WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -07006479 __func__);
6480 return status;
6481 }
6482 }
6483
6484 /*incase of WEP set default key information*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306485 if (req->key && req->key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -07006486 {
6487 if ( (WLAN_CIPHER_SUITE_WEP40 == req->crypto.ciphers_pairwise[0])
6488 || (WLAN_CIPHER_SUITE_WEP104 == req->crypto.ciphers_pairwise[0])
6489 )
6490 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306491 if ( IW_AUTH_KEY_MGMT_802_1X
Jeff Johnson295189b2012-06-20 16:38:30 -07006492 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X ))
6493 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306494 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Dynamic WEP not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -07006495 __func__);
6496 return -EOPNOTSUPP;
6497 }
6498 else
6499 {
6500 u8 key_len = req->key_len;
6501 u8 key_idx = req->key_idx;
6502
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306503 if ((eCSR_SECURITY_WEP_KEYSIZE_MAX_BYTES >= key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -07006504 && (CSR_MAX_NUM_KEY > key_idx)
6505 )
6506 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306507 hddLog(VOS_TRACE_LEVEL_INFO,
6508 "%s: setting default wep key, key_idx = %hu key_len %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07006509 __func__, key_idx, key_len);
6510 vos_mem_copy(
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306511 &pWextState->roamProfile.Keys.KeyMaterial[key_idx][0],
Jeff Johnson295189b2012-06-20 16:38:30 -07006512 req->key, key_len);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306513 pWextState->roamProfile.Keys.KeyLength[key_idx] =
Jeff Johnson295189b2012-06-20 16:38:30 -07006514 (u8)key_len;
6515 pWextState->roamProfile.Keys.defaultIndex = (u8)key_idx;
6516 }
6517 }
6518 }
6519 }
6520
6521 return status;
6522}
6523
6524/*
Vinay Krishna Eranna21042322014-01-08 19:21:39 +05306525 * FUNCTION: wlan_hdd_try_disconnect
6526 * This function is used to disconnect from previous
6527 * connection
6528 */
6529static int wlan_hdd_try_disconnect( hdd_adapter_t *pAdapter )
6530{
6531 long ret = 0;
6532 hdd_station_ctx_t *pHddStaCtx;
6533 eMib_dot11DesiredBssType connectedBssType;
6534
6535 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6536
6537 hdd_connGetConnectedBssType(pHddStaCtx,&connectedBssType );
6538
6539 if((eMib_dot11DesiredBssType_independent == connectedBssType) ||
6540 (eConnectionState_Associated == pHddStaCtx->conn_info.connState) ||
6541 (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState))
6542 {
6543 /* Issue disconnect to CSR */
6544 INIT_COMPLETION(pAdapter->disconnect_comp_var);
6545 if( eHAL_STATUS_SUCCESS ==
6546 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
6547 pAdapter->sessionId,
6548 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
6549 {
6550 ret = wait_for_completion_interruptible_timeout(
6551 &pAdapter->disconnect_comp_var,
6552 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
6553 if (0 >= ret)
6554 {
6555 hddLog(LOGE, FL("Failed to receive disconnect event"));
6556 return -EALREADY;
6557 }
6558 }
6559 }
6560 else if(eConnectionState_Disconnecting == pHddStaCtx->conn_info.connState)
6561 {
6562 ret = wait_for_completion_interruptible_timeout(
6563 &pAdapter->disconnect_comp_var,
6564 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
6565 if (0 >= ret)
6566 {
6567 hddLog(LOGE, FL("Failed to receive disconnect event"));
6568 return -EALREADY;
6569 }
6570 }
6571
6572 return 0;
6573}
6574
6575/*
Jeff Johnson295189b2012-06-20 16:38:30 -07006576 * FUNCTION: wlan_hdd_cfg80211_set_privacy
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306577 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -07006578 * parameters during connect operation.
6579 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306580static int wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07006581 struct net_device *ndev,
6582 struct cfg80211_connect_params *req
6583 )
6584{
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306585 int status;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306586 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -07006587 VOS_STATUS exitbmpsStatus = VOS_STATUS_E_INVAL;
Rajesh Chauhana0516c62014-01-30 16:11:18 -08006588 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07006589
6590 ENTER();
6591
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05306592 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
6593 TRACE_CODE_HDD_CFG80211_CONNECT,
6594 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306595 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05306596 "%s: device_mode = %s (%d)", __func__,
6597 hdd_device_modetoString(pAdapter->device_mode),
6598 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07006599
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306600 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -08006601 if (!pHddCtx)
6602 {
6603 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6604 "%s: HDD context is null", __func__);
6605 return VOS_STATUS_E_FAILURE;
6606 }
6607
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306608 status = wlan_hdd_validate_context(pHddCtx);
6609
6610 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -07006611 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306612 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6613 "%s: HDD context is not valid", __func__);
6614 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -07006615 }
6616
6617#ifdef WLAN_BTAMP_FEATURE
6618 //Infra connect not supported when AMP traffic is on.
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306619 if( VOS_TRUE == WLANBAP_AmpSessionOn() )
Jeff Johnson295189b2012-06-20 16:38:30 -07006620 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306621 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07006622 "%s: No connection when AMP is on", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08006623 return -ECONNREFUSED;
Jeff Johnson295189b2012-06-20 16:38:30 -07006624 }
6625#endif
Vinay Krishna Eranna21042322014-01-08 19:21:39 +05306626
6627 //If Device Mode is Station Concurrent Sessions Exit BMps
6628 //P2P Mode will be taken care in Open/close adapter
6629 if((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
6630 (vos_concurrent_sessions_running()))
6631 {
6632 exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
6633 }
6634
6635 /*Try disconnecting if already in connected state*/
6636 status = wlan_hdd_try_disconnect(pAdapter);
6637 if ( 0 > status)
6638 {
6639 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
6640 " connection"));
6641 return -EALREADY;
6642 }
6643
Jeff Johnson295189b2012-06-20 16:38:30 -07006644 /*initialise security parameters*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306645 status = wlan_hdd_cfg80211_set_privacy(pAdapter, req);
Jeff Johnson295189b2012-06-20 16:38:30 -07006646
6647 if ( 0 > status)
6648 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306649 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security params",
Jeff Johnson295189b2012-06-20 16:38:30 -07006650 __func__);
6651 return status;
6652 }
6653
Mohit Khanna765234a2012-09-11 15:08:35 -07006654 if ( req->channel )
6655 {
6656 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
6657 req->ssid_len, req->bssid,
6658 req->channel->hw_value);
6659 }
6660 else
6661 {
6662 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306663 req->ssid_len, req->bssid, 0);
Mohit Khanna765234a2012-09-11 15:08:35 -07006664 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006665
6666 if (0 > status)
6667 {
6668 //ReEnable BMPS if disabled
6669 if((VOS_STATUS_SUCCESS == exitbmpsStatus) &&
6670 (NULL != pHddCtx))
6671 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306672 if (pHddCtx->hdd_wlan_suspended)
6673 {
6674 hdd_set_pwrparams(pHddCtx);
6675 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006676 //ReEnable Bmps and Imps back
6677 hdd_enable_bmps_imps(pHddCtx);
6678 }
6679
6680 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: connect failed", __func__);
6681 return status;
6682 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306683 pHddCtx->isAmpAllowed = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07006684 EXIT();
6685 return status;
6686}
6687
6688
6689/*
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05306690 * FUNCTION: wlan_hdd_disconnect
6691 * This function is used to issue a disconnect request to SME
6692 */
6693int wlan_hdd_disconnect( hdd_adapter_t *pAdapter, u16 reason )
6694{
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306695 int status;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05306696 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306697 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
6698
6699 status = wlan_hdd_validate_context(pHddCtx);
6700
6701 if (0 != status)
6702 {
6703 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6704 "%s: HDD context is not valid", __func__);
6705 return status;
6706 }
6707
6708 pHddCtx->isAmpAllowed = VOS_TRUE;
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +05306709 pHddStaCtx->conn_info.connState = eConnectionState_Disconnecting;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05306710 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306711
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05306712 /*issue disconnect*/
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +05306713
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05306714 status = sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
6715 pAdapter->sessionId, reason);
6716
6717 if ( 0 != status )
6718 {
6719 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006720 "%s csrRoamDisconnect failure, returned %d",
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05306721 __func__, (int)status );
6722 return -EINVAL;
6723 }
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +05306724 status = wait_for_completion_interruptible_timeout(
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05306725 &pAdapter->disconnect_comp_var,
6726 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +05306727 if (!status)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306728 {
6729 hddLog(VOS_TRACE_LEVEL_ERROR,
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +05306730 "%s: Failed to disconnect, timed out", __func__);
6731 return -ETIMEDOUT;
6732 }
6733 else if (status == -ERESTARTSYS)
6734 {
6735 hddLog(VOS_TRACE_LEVEL_ERROR,
6736 "%s: Failed to disconnect, wait interrupted", __func__);
6737 return status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306738 }
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05306739 /*stop tx queues*/
6740 netif_tx_disable(pAdapter->dev);
6741 netif_carrier_off(pAdapter->dev);
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +05306742 return 0;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05306743}
6744
6745
6746/*
Jeff Johnson295189b2012-06-20 16:38:30 -07006747 * FUNCTION: wlan_hdd_cfg80211_disconnect
6748 * This function is used to issue a disconnect request to SME
6749 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306750static int wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07006751 struct net_device *dev,
6752 u16 reason
6753 )
6754{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306755 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
6756 tCsrRoamProfile *pRoamProfile =
Jeff Johnson295189b2012-06-20 16:38:30 -07006757 &(WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter))->roamProfile;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306758 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07006759 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkala4327a152013-03-04 23:22:42 -08006760 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaaa353782013-05-17 20:36:22 +05306761#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08006762 tANI_U8 staIdx;
6763#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306764
Jeff Johnson295189b2012-06-20 16:38:30 -07006765 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306766
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05306767 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
6768 TRACE_CODE_HDD_CFG80211_DISCONNECT,
6769 pAdapter->sessionId, reason));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05306770 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s(%d)",
6771 __func__, hdd_device_modetoString(pAdapter->device_mode),
6772 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07006773
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306774 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Disconnect called with reason code %d",
6775 __func__, reason);
Jeff Johnson295189b2012-06-20 16:38:30 -07006776
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306777 status = wlan_hdd_validate_context(pHddCtx);
6778
6779 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -07006780 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306781 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6782 "%s: HDD context is not valid", __func__);
6783 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -07006784 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306785
Jeff Johnson295189b2012-06-20 16:38:30 -07006786 if (NULL != pRoamProfile)
6787 {
6788 /*issue disconnect request to SME, if station is in connected state*/
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +05306789 if ((pHddStaCtx->conn_info.connState == eConnectionState_Associated) ||
6790 (pHddStaCtx->conn_info.connState == eConnectionState_Connecting))
Jeff Johnson295189b2012-06-20 16:38:30 -07006791 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306792 eCsrRoamDisconnectReason reasonCode =
Jeff Johnson295189b2012-06-20 16:38:30 -07006793 eCSR_DISCONNECT_REASON_UNSPECIFIED;
Gopichand Nakkalaaa353782013-05-17 20:36:22 +05306794 hdd_scaninfo_t *pScanInfo;
Jeff Johnson295189b2012-06-20 16:38:30 -07006795 switch(reason)
6796 {
6797 case WLAN_REASON_MIC_FAILURE:
6798 reasonCode = eCSR_DISCONNECT_REASON_MIC_ERROR;
6799 break;
6800
6801 case WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY:
6802 case WLAN_REASON_DISASSOC_AP_BUSY:
6803 case WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA:
6804 reasonCode = eCSR_DISCONNECT_REASON_DISASSOC;
6805 break;
6806
6807 case WLAN_REASON_PREV_AUTH_NOT_VALID:
6808 case WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA:
6809 reasonCode = eCSR_DISCONNECT_REASON_DEAUTH;
6810 break;
6811
6812 case WLAN_REASON_DEAUTH_LEAVING:
6813 default:
6814 reasonCode = eCSR_DISCONNECT_REASON_UNSPECIFIED;
6815 break;
6816 }
Gopichand Nakkalaaa353782013-05-17 20:36:22 +05306817 pScanInfo = &pHddCtx->scan_info;
6818 if (pScanInfo->mScanPending)
6819 {
Srinivas, Dasari138af4f2014-02-07 11:13:45 +05306820 hddLog(VOS_TRACE_LEVEL_INFO, "Disconnect is in progress, "
Gopichand Nakkalaaa353782013-05-17 20:36:22 +05306821 "Aborting Scan");
Srinivas, Dasari138af4f2014-02-07 11:13:45 +05306822 hdd_abort_mac_scan(pHddCtx, pAdapter->sessionId,
6823 eCSR_SCAN_ABORT_DEFAULT);
Gopichand Nakkalaaa353782013-05-17 20:36:22 +05306824 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006825
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08006826#ifdef FEATURE_WLAN_TDLS
6827 /* First clean up the tdls peers if any */
Gopichand Nakkala4327a152013-03-04 23:22:42 -08006828 for (staIdx = 0 ; staIdx < HDD_MAX_NUM_TDLS_STA; staIdx++)
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08006829 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -08006830 if ((pHddCtx->tdlsConnInfo[staIdx].sessionId == pAdapter->sessionId) &&
6831 (pHddCtx->tdlsConnInfo[staIdx].staId))
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08006832 {
Hoonki Lee11f7dda2013-02-14 16:55:44 -08006833 uint8 *mac;
Gopichand Nakkala4327a152013-03-04 23:22:42 -08006834 mac = pHddCtx->tdlsConnInfo[staIdx].peerMac.bytes;
Hoonki Lee11f7dda2013-02-14 16:55:44 -08006835 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07006836 "%s: call sme_DeleteTdlsPeerSta staId %d sessionId %d " MAC_ADDRESS_STR,
Gopichand Nakkala4327a152013-03-04 23:22:42 -08006837 __func__, pHddCtx->tdlsConnInfo[staIdx].staId, pAdapter->sessionId,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07006838 MAC_ADDR_ARRAY(mac));
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08006839 sme_DeleteTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala4327a152013-03-04 23:22:42 -08006840 pAdapter->sessionId,
6841 mac);
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08006842 }
6843 }
6844#endif
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +05306845 hddLog(LOG1, FL("Disconnecting with reasoncode:%u"), reasonCode);
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05306846 status = wlan_hdd_disconnect(pAdapter, reasonCode);
6847 if ( 0 != status )
Jeff Johnson295189b2012-06-20 16:38:30 -07006848 {
6849 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006850 "%s wlan_hdd_disconnect failure, returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07006851 __func__, (int)status );
6852 return -EINVAL;
6853 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006854 }
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +05306855 else
6856 {
6857 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unexpected cfg disconnect API"
6858 "called while in %d state", __func__,
6859 pHddStaCtx->conn_info.connState);
6860 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006861 }
6862 else
6863 {
6864 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid roam profile", __func__);
6865 }
6866
6867 return status;
6868}
6869
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05306870
Jeff Johnson295189b2012-06-20 16:38:30 -07006871/*
6872 * FUNCTION: wlan_hdd_cfg80211_set_privacy_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306873 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -07006874 * settings in IBSS mode.
6875 */
6876static int wlan_hdd_cfg80211_set_privacy_ibss(
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306877 hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07006878 struct cfg80211_ibss_params *params
6879 )
6880{
6881 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306882 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07006883 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
6884 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306885
Jeff Johnson295189b2012-06-20 16:38:30 -07006886 ENTER();
6887
6888 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
Ravi Joshib58ca0d2013-10-29 09:50:23 -07006889 vos_mem_zero(&pHddStaCtx->ibss_enc_key, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -07006890
6891 if (params->ie_len && ( NULL != params->ie) )
6892 {
Shailender Karmuchi67edd312013-06-18 16:30:48 -07006893 if (wlan_hdd_cfg80211_get_ie_ptr (params->ie,
6894 params->ie_len, WLAN_EID_RSN ))
Jeff Johnson295189b2012-06-20 16:38:30 -07006895 {
6896 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
6897 encryptionType = eCSR_ENCRYPT_TYPE_AES;
6898 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -07006899 else if ( hdd_isWPAIEPresent (params->ie, params->ie_len ))
Jeff Johnson295189b2012-06-20 16:38:30 -07006900 {
Shailender Karmuchi642e9812013-05-30 14:34:49 -07006901 tDot11fIEWPA dot11WPAIE;
6902 tHalHandle halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
Shailender Karmuchi67edd312013-06-18 16:30:48 -07006903 u8 *ie;
Shailender Karmuchi642e9812013-05-30 14:34:49 -07006904
Wilson Yang00256342013-10-10 23:13:38 -07006905 memset(&dot11WPAIE, 0, sizeof(dot11WPAIE));
Shailender Karmuchi67edd312013-06-18 16:30:48 -07006906 ie = wlan_hdd_cfg80211_get_ie_ptr (params->ie,
6907 params->ie_len, DOT11F_EID_WPA);
6908 if ( NULL != ie )
6909 {
6910 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
6911 // Unpack the WPA IE
6912 //Skip past the EID byte and length byte - and four byte WiFi OUI
6913 dot11fUnpackIeWPA((tpAniSirGlobal) halHandle,
6914 &ie[2+4],
6915 ie[1] - 4,
6916 &dot11WPAIE);
6917 /*Extract the multicast cipher, the encType for unicast
6918 cipher for wpa-none is none*/
6919 encryptionType =
6920 hdd_TranslateWPAToCsrEncryptionType(dot11WPAIE.multicast_cipher);
6921 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006922 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -07006923
Jeff Johnson295189b2012-06-20 16:38:30 -07006924 status = wlan_hdd_cfg80211_set_ie(pAdapter, params->ie, params->ie_len);
6925
6926 if (0 > status)
6927 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306928 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -07006929 __func__);
6930 return status;
6931 }
6932 }
6933
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306934 pWextState->roamProfile.AuthType.authType[0] =
6935 pHddStaCtx->conn_info.authType =
Jeff Johnson295189b2012-06-20 16:38:30 -07006936 eCSR_AUTH_TYPE_OPEN_SYSTEM;
6937
6938 if (params->privacy)
6939 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306940 /* Security enabled IBSS, At this time there is no information available
6941 * about the security paramters, so initialise the encryption type to
Jeff Johnson295189b2012-06-20 16:38:30 -07006942 * eCSR_ENCRYPT_TYPE_WEP40_STATICKEY.
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306943 * The correct security parameters will be updated later in
Jeff Johnson295189b2012-06-20 16:38:30 -07006944 * wlan_hdd_cfg80211_add_key */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306945 /* Hal expects encryption type to be set inorder
Jeff Johnson295189b2012-06-20 16:38:30 -07006946 *enable privacy bit in beacons */
6947
6948 encryptionType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
6949 }
Shailender Karmuchi642e9812013-05-30 14:34:49 -07006950 VOS_TRACE (VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
6951 "encryptionType=%d", encryptionType);
Jeff Johnson295189b2012-06-20 16:38:30 -07006952 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
6953 pWextState->roamProfile.EncryptionType.numEntries = 1;
6954 pWextState->roamProfile.EncryptionType.encryptionType[0] = encryptionType;
Jeff Johnson295189b2012-06-20 16:38:30 -07006955 return status;
6956}
6957
6958/*
6959 * FUNCTION: wlan_hdd_cfg80211_join_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306960 * This function is used to create/join an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -07006961 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306962static int wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07006963 struct net_device *dev,
6964 struct cfg80211_ibss_params *params
6965 )
6966{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306967 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Jeff Johnson295189b2012-06-20 16:38:30 -07006968 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
6969 tCsrRoamProfile *pRoamProfile;
6970 int status;
krunal sonie9002db2013-11-25 14:24:17 -08006971 bool alloc_bssid = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07006972 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306973 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07006974
6975 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306976
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05306977 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
6978 TRACE_CODE_HDD_CFG80211_JOIN_IBSS,
6979 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306980 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05306981 "%s: device_mode = %s (%d)", __func__,
6982 hdd_device_modetoString(pAdapter->device_mode),
6983 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07006984
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306985 status = wlan_hdd_validate_context(pHddCtx);
6986
6987 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -07006988 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306989 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6990 "%s: HDD context is not valid", __func__);
6991 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -07006992 }
6993
6994 if (NULL == pWextState)
6995 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08006996 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -07006997 __func__);
6998 return -EIO;
6999 }
7000
Vinay Krishna Eranna21042322014-01-08 19:21:39 +05307001 /*Try disconnecting if already in connected state*/
7002 status = wlan_hdd_try_disconnect(pAdapter);
7003 if ( 0 > status)
7004 {
7005 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
7006 " IBSS connection"));
7007 return -EALREADY;
7008 }
7009
Jeff Johnson295189b2012-06-20 16:38:30 -07007010 pRoamProfile = &pWextState->roamProfile;
7011
7012 if ( eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType )
7013 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307014 hddLog (VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007015 "%s Interface type is not set to IBSS", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007016 return -EINVAL;
7017 }
7018
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -07007019 /* BSSID is provided by upper layers hence no need to AUTO generate */
7020 if (NULL != params->bssid) {
7021 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
7022 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) {
7023 hddLog (VOS_TRACE_LEVEL_ERROR,
7024 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
7025 return -EIO;
7026 }
7027 }
krunal sonie9002db2013-11-25 14:24:17 -08007028 else if(pHddCtx->cfg_ini->isCoalesingInIBSSAllowed == 0)
7029 {
7030 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
7031 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
7032 {
7033 hddLog (VOS_TRACE_LEVEL_ERROR,
7034 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
7035 return -EIO;
7036 }
7037 params->bssid = vos_mem_malloc(sizeof(VOS_MAC_ADDR_SIZE));
7038 if (!params->bssid)
7039 {
7040 hddLog (VOS_TRACE_LEVEL_ERROR,
7041 "%s:Failed memory allocation", __func__);
7042 return -EIO;
7043 }
7044 vos_mem_copy((v_U8_t *)params->bssid,
7045 (v_U8_t *)&pHddCtx->cfg_ini->IbssBssid.bytes[0],
7046 VOS_MAC_ADDR_SIZE);
7047 alloc_bssid = VOS_TRUE;
7048 }
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -07007049
Jeff Johnson295189b2012-06-20 16:38:30 -07007050 /* Set Channel */
Yue Maf49ba872013-08-19 12:04:25 -07007051 if (NULL !=
7052#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
7053 params->chandef.chan)
7054#else
7055 params->channel)
7056#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007057 {
7058 u8 channelNum;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07007059 v_U32_t numChans = WNI_CFG_VALID_CHANNEL_LIST_LEN;
7060 v_U8_t validChan[WNI_CFG_VALID_CHANNEL_LIST_LEN];
7061 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
7062 int indx;
Jeff Johnson295189b2012-06-20 16:38:30 -07007063
7064 /* Get channel number */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307065 channelNum =
Yue Maf49ba872013-08-19 12:04:25 -07007066 ieee80211_frequency_to_channel(
7067#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
7068 params->chandef.chan->center_freq);
7069#else
7070 params->channel->center_freq);
7071#endif
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07007072
7073 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
7074 validChan, &numChans))
Jeff Johnson295189b2012-06-20 16:38:30 -07007075 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07007076 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid channel list",
7077 __func__);
7078 return -EOPNOTSUPP;
Jeff Johnson295189b2012-06-20 16:38:30 -07007079 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07007080
7081 for (indx = 0; indx < numChans; indx++)
Jeff Johnson295189b2012-06-20 16:38:30 -07007082 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07007083 if (channelNum == validChan[indx])
7084 {
7085 break;
7086 }
7087 }
7088 if (indx >= numChans)
7089 {
7090 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Not valid Channel %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07007091 __func__, channelNum);
7092 return -EINVAL;
7093 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07007094 /* Set the Operational Channel */
7095 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: set channel %d", __func__,
7096 channelNum);
7097 pRoamProfile->ChannelInfo.numOfChannels = 1;
7098 pHddStaCtx->conn_info.operationChannel = channelNum;
7099 pRoamProfile->ChannelInfo.ChannelList =
7100 &pHddStaCtx->conn_info.operationChannel;
Jeff Johnson295189b2012-06-20 16:38:30 -07007101 }
7102
7103 /* Initialize security parameters */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307104 status = wlan_hdd_cfg80211_set_privacy_ibss(pAdapter, params);
Jeff Johnson295189b2012-06-20 16:38:30 -07007105 if (status < 0)
7106 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307107 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security parameters",
Jeff Johnson295189b2012-06-20 16:38:30 -07007108 __func__);
7109 return status;
7110 }
7111
7112 /* Issue connect start */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307113 status = wlan_hdd_cfg80211_connect_start(pAdapter, params->ssid,
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07007114 params->ssid_len, params->bssid,
7115 pHddStaCtx->conn_info.operationChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -07007116
7117 if (0 > status)
7118 {
7119 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: connect failed", __func__);
7120 return status;
7121 }
7122
krunal sonie9002db2013-11-25 14:24:17 -08007123 if (NULL != params->bssid &&
7124 pHddCtx->cfg_ini->isCoalesingInIBSSAllowed == 0 &&
7125 alloc_bssid == VOS_TRUE)
7126 {
7127 vos_mem_free(params->bssid);
7128 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007129 return 0;
7130}
7131
7132/*
7133 * FUNCTION: wlan_hdd_cfg80211_leave_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307134 * This function is used to leave an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -07007135 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307136static int wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07007137 struct net_device *dev
7138 )
7139{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307140 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Jeff Johnson295189b2012-06-20 16:38:30 -07007141 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
7142 tCsrRoamProfile *pRoamProfile;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307143 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7144 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07007145
7146 ENTER();
7147
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307148 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7149 TRACE_CODE_HDD_CFG80211_LEAVE_IBSS,
7150 pAdapter->sessionId, eCSR_DISCONNECT_REASON_IBSS_LEAVE));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307151 status = wlan_hdd_validate_context(pHddCtx);
7152
7153 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007154 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307155 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7156 "%s: HDD context is not valid", __func__);
7157 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007158 }
7159
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05307160 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)", __func__,
7161 hdd_device_modetoString(pAdapter->device_mode),
7162 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07007163 if (NULL == pWextState)
7164 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08007165 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -07007166 __func__);
7167 return -EIO;
7168 }
7169
7170 pRoamProfile = &pWextState->roamProfile;
7171
7172 /* Issue disconnect only if interface type is set to IBSS */
7173 if (eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType)
7174 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307175 hddLog (VOS_TRACE_LEVEL_ERROR, "%s: BSS Type is not set to IBSS",
Jeff Johnson295189b2012-06-20 16:38:30 -07007176 __func__);
7177 return -EINVAL;
7178 }
7179
7180 /* Issue Disconnect request */
7181 INIT_COMPLETION(pAdapter->disconnect_comp_var);
7182 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
7183 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
7184
7185 return 0;
7186}
7187
7188/*
7189 * FUNCTION: wlan_hdd_cfg80211_set_wiphy_params
7190 * This function is used to set the phy parameters
7191 * (RTS Threshold/FRAG Threshold/Retry Count etc ...)
7192 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307193static int wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07007194 u32 changed)
7195{
7196 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
7197 tHalHandle hHal = pHddCtx->hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307198 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07007199
7200 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307201 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7202 TRACE_CODE_HDD_CFG80211_SET_WIPHY_PARAMS,
7203 NO_SESSION, wiphy->rts_threshold));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307204 status = wlan_hdd_validate_context(pHddCtx);
7205
7206 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007207 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307208 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7209 "%s: HDD context is not valid", __func__);
7210 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007211 }
7212
Jeff Johnson295189b2012-06-20 16:38:30 -07007213 if (changed & WIPHY_PARAM_RTS_THRESHOLD)
7214 {
7215 u16 rts_threshold = (wiphy->rts_threshold == -1) ?
7216 WNI_CFG_RTS_THRESHOLD_STAMAX :
7217 wiphy->rts_threshold;
7218
7219 if ((WNI_CFG_RTS_THRESHOLD_STAMIN > rts_threshold) ||
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307220 (WNI_CFG_RTS_THRESHOLD_STAMAX < rts_threshold))
Jeff Johnson295189b2012-06-20 16:38:30 -07007221 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307222 hddLog(VOS_TRACE_LEVEL_ERROR,
7223 "%s: Invalid RTS Threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07007224 __func__, rts_threshold);
7225 return -EINVAL;
7226 }
7227
7228 if (0 != ccmCfgSetInt(hHal, WNI_CFG_RTS_THRESHOLD,
7229 rts_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307230 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -07007231 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307232 hddLog(VOS_TRACE_LEVEL_ERROR,
7233 "%s: ccmCfgSetInt failed for rts_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07007234 __func__, rts_threshold);
7235 return -EIO;
7236 }
7237
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307238 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set rts threshold %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07007239 rts_threshold);
7240 }
7241
7242 if (changed & WIPHY_PARAM_FRAG_THRESHOLD)
7243 {
7244 u16 frag_threshold = (wiphy->frag_threshold == -1) ?
7245 WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX :
7246 wiphy->frag_threshold;
7247
7248 if ((WNI_CFG_FRAGMENTATION_THRESHOLD_STAMIN > frag_threshold)||
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307249 (WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX < frag_threshold) )
Jeff Johnson295189b2012-06-20 16:38:30 -07007250 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307251 hddLog(VOS_TRACE_LEVEL_ERROR,
7252 "%s: Invalid frag_threshold value %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07007253 frag_threshold);
7254 return -EINVAL;
7255 }
7256
7257 if (0 != ccmCfgSetInt(hHal, WNI_CFG_FRAGMENTATION_THRESHOLD,
7258 frag_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307259 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -07007260 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307261 hddLog(VOS_TRACE_LEVEL_ERROR,
7262 "%s: ccmCfgSetInt failed for frag_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07007263 __func__, frag_threshold);
7264 return -EIO;
7265 }
7266
7267 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set frag threshold %hu", __func__,
7268 frag_threshold);
7269 }
7270
7271 if ((changed & WIPHY_PARAM_RETRY_SHORT)
7272 || (changed & WIPHY_PARAM_RETRY_LONG))
7273 {
7274 u8 retry_value = (changed & WIPHY_PARAM_RETRY_SHORT) ?
7275 wiphy->retry_short :
7276 wiphy->retry_long;
7277
7278 if ((WNI_CFG_LONG_RETRY_LIMIT_STAMIN > retry_value) ||
7279 (WNI_CFG_LONG_RETRY_LIMIT_STAMAX < retry_value))
7280 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307281 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07007282 __func__, retry_value);
7283 return -EINVAL;
7284 }
7285
7286 if (changed & WIPHY_PARAM_RETRY_SHORT)
7287 {
7288 if (0 != ccmCfgSetInt(hHal, WNI_CFG_LONG_RETRY_LIMIT,
7289 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307290 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -07007291 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307292 hddLog(VOS_TRACE_LEVEL_ERROR,
7293 "%s: ccmCfgSetInt failed for long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07007294 __func__, retry_value);
7295 return -EIO;
7296 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307297 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07007298 __func__, retry_value);
7299 }
7300 else if (changed & WIPHY_PARAM_RETRY_SHORT)
7301 {
7302 if (0 != ccmCfgSetInt(hHal, WNI_CFG_SHORT_RETRY_LIMIT,
7303 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307304 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -07007305 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307306 hddLog(VOS_TRACE_LEVEL_ERROR,
7307 "%s: ccmCfgSetInt failed for short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07007308 __func__, retry_value);
7309 return -EIO;
7310 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307311 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07007312 __func__, retry_value);
7313 }
7314 }
7315
7316 return 0;
7317}
7318
7319/*
7320 * FUNCTION: wlan_hdd_cfg80211_set_txpower
7321 * This function is used to set the txpower
7322 */
7323static int wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
Yue Maf49ba872013-08-19 12:04:25 -07007324#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
7325 struct wireless_dev *wdev,
7326#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007327#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307328 enum tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -07007329#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307330 enum nl80211_tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -07007331#endif
7332 int dbm)
7333{
7334 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307335 tHalHandle hHal = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07007336 tSirMacAddr bssid = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
7337 tSirMacAddr selfMac = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307338 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07007339
7340 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307341 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7342 TRACE_CODE_HDD_CFG80211_SET_TXPOWER,
7343 NO_SESSION, type ));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307344 status = wlan_hdd_validate_context(pHddCtx);
7345
7346 if (0 != status)
7347 {
7348 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7349 "%s: HDD context is not valid", __func__);
7350 return status;
7351 }
7352
7353 hHal = pHddCtx->hHal;
7354
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307355 if (0 != ccmCfgSetInt(hHal, WNI_CFG_CURRENT_TX_POWER_LEVEL,
7356 dbm, ccmCfgSetCallback,
7357 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -07007358 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307359 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07007360 "%s: ccmCfgSetInt failed for tx power %hu", __func__, dbm);
7361 return -EIO;
7362 }
7363
7364 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set tx power level %d dbm", __func__,
7365 dbm);
7366
7367 switch(type)
7368 {
7369 case NL80211_TX_POWER_AUTOMATIC: /*automatically determine transmit power*/
7370 /* Fall through */
7371 case NL80211_TX_POWER_LIMITED: /*limit TX power by the mBm parameter*/
7372 if( sme_SetMaxTxPower(hHal, bssid, selfMac, dbm) != eHAL_STATUS_SUCCESS )
7373 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307374 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Setting maximum tx power failed",
7375 __func__);
7376 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -07007377 }
7378 break;
7379 case NL80211_TX_POWER_FIXED: /*fix TX power to the mBm parameter*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307380 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: NL80211_TX_POWER_FIXED not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -07007381 __func__);
7382 return -EOPNOTSUPP;
7383 break;
7384 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307385 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid power setting type %d",
7386 __func__, type);
Jeff Johnson295189b2012-06-20 16:38:30 -07007387 return -EIO;
7388 }
7389
7390 return 0;
7391}
7392
7393/*
7394 * FUNCTION: wlan_hdd_cfg80211_get_txpower
7395 * This function is used to read the txpower
7396 */
Yue Maf49ba872013-08-19 12:04:25 -07007397static int wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy,
7398#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
7399 struct wireless_dev *wdev,
7400#endif
7401 int *dbm)
Jeff Johnson295189b2012-06-20 16:38:30 -07007402{
7403
7404 hdd_adapter_t *pAdapter;
7405 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307406 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07007407
Jeff Johnsone7245742012-09-05 17:12:55 -07007408 ENTER();
7409
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307410 status = wlan_hdd_validate_context(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07007411
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307412 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007413 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307414 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7415 "%s: HDD context is not valid", __func__);
7416 *dbm = 0;
7417 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007418 }
7419
Jeff Johnson295189b2012-06-20 16:38:30 -07007420 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
7421 if (NULL == pAdapter)
7422 {
7423 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Not in station context " ,__func__);
7424 return -ENOENT;
7425 }
7426
7427 wlan_hdd_get_classAstats(pAdapter);
7428 *dbm = pAdapter->hdd_stats.ClassA_stat.max_pwr;
7429
Jeff Johnsone7245742012-09-05 17:12:55 -07007430 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07007431 return 0;
7432}
7433
7434static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
7435 u8* mac, struct station_info *sinfo)
7436{
7437 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
7438 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7439 int ssidlen = pHddStaCtx->conn_info.SSID.SSID.length;
c_hpothu44ff4e02014-05-08 00:13:57 +05307440 tANI_U32 rate_flags;
Jeff Johnson295189b2012-06-20 16:38:30 -07007441
7442 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
7443 hdd_config_t *pCfg = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -07007444
7445 tANI_U8 OperationalRates[CSR_DOT11_SUPPORTED_RATES_MAX];
7446 tANI_U32 ORLeng = CSR_DOT11_SUPPORTED_RATES_MAX;
7447 tANI_U8 ExtendedRates[CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX];
7448 tANI_U32 ERLeng = CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX;
7449 tANI_U8 MCSRates[SIZE_OF_BASIC_MCS_SET];
7450 tANI_U32 MCSLeng = SIZE_OF_BASIC_MCS_SET;
7451 tANI_U16 maxRate = 0;
7452 tANI_U16 myRate;
7453 tANI_U16 currentRate = 0;
7454 tANI_U8 maxSpeedMCS = 0;
7455 tANI_U8 maxMCSIdx = 0;
7456 tANI_U8 rateFlag = 1;
7457 tANI_U8 i, j, rssidx;
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07007458 tANI_U16 temp;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307459 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07007460
Leo Chang6f8870f2013-03-26 18:11:36 -07007461#ifdef WLAN_FEATURE_11AC
7462 tANI_U32 vht_mcs_map;
7463 eDataRate11ACMaxMcs vhtMaxMcs;
7464#endif /* WLAN_FEATURE_11AC */
7465
Jeff Johnsone7245742012-09-05 17:12:55 -07007466 ENTER();
7467
Jeff Johnson295189b2012-06-20 16:38:30 -07007468 if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) ||
7469 (0 == ssidlen))
7470 {
7471 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Not associated or"
7472 " Invalid ssidlen, %d", __func__, ssidlen);
7473 /*To keep GUI happy*/
7474 return 0;
7475 }
7476
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307477 status = wlan_hdd_validate_context(pHddCtx);
7478
7479 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007480 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307481 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7482 "%s: HDD context is not valid", __func__);
7483 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007484 }
7485
Jeff Johnson295189b2012-06-20 16:38:30 -07007486
Kiet Lam3b17fc82013-09-27 05:24:08 +05307487 wlan_hdd_get_rssi(pAdapter, &sinfo->signal);
7488 sinfo->filled |= STATION_INFO_SIGNAL;
7489
c_hpothu44ff4e02014-05-08 00:13:57 +05307490 if ((eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed) ||
7491 (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed &&
7492 sinfo->signal >= pCfg->linkSpeedRssiHigh))
7493 {
7494 rate_flags = pAdapter->maxRateFlags;
7495 }
7496 else
7497 {
7498 wlan_hdd_get_station_stats(pAdapter);
7499 rate_flags = pAdapter->hdd_stats.ClassA_stat.tx_rate_flags;
7500 }
7501
Jeff Johnson295189b2012-06-20 16:38:30 -07007502 //convert to the UI units of 100kbps
7503 myRate = pAdapter->hdd_stats.ClassA_stat.tx_rate * 5;
7504
7505#ifdef LINKSPEED_DEBUG_ENABLED
Leo Chang6f8870f2013-03-26 18:11:36 -07007506 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 -07007507 sinfo->signal,
7508 pCfg->reportMaxLinkSpeed,
7509 myRate,
7510 (int) pCfg->linkSpeedRssiHigh,
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07007511 (int) pCfg->linkSpeedRssiMid,
7512 (int) pCfg->linkSpeedRssiLow,
Leo Chang6f8870f2013-03-26 18:11:36 -07007513 (int) rate_flags,
7514 (int) pAdapter->hdd_stats.ClassA_stat.mcs_index);
Jeff Johnson295189b2012-06-20 16:38:30 -07007515#endif //LINKSPEED_DEBUG_ENABLED
7516
7517 if (eHDD_LINK_SPEED_REPORT_ACTUAL != pCfg->reportMaxLinkSpeed)
7518 {
7519 // we do not want to necessarily report the current speed
7520 if (eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed)
7521 {
7522 // report the max possible speed
7523 rssidx = 0;
7524 }
7525 else if (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed)
7526 {
7527 // report the max possible speed with RSSI scaling
7528 if (sinfo->signal >= pCfg->linkSpeedRssiHigh)
7529 {
7530 // report the max possible speed
7531 rssidx = 0;
7532 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07007533 else if (sinfo->signal >= pCfg->linkSpeedRssiMid)
Jeff Johnson295189b2012-06-20 16:38:30 -07007534 {
7535 // report middle speed
7536 rssidx = 1;
7537 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07007538 else if (sinfo->signal >= pCfg->linkSpeedRssiLow)
7539 {
7540 // report middle speed
7541 rssidx = 2;
7542 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007543 else
7544 {
7545 // report actual speed
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07007546 rssidx = 3;
Jeff Johnson295189b2012-06-20 16:38:30 -07007547 }
7548 }
7549 else
7550 {
7551 // unknown, treat as eHDD_LINK_SPEED_REPORT_MAX
7552 hddLog(VOS_TRACE_LEVEL_ERROR,
7553 "%s: Invalid value for reportMaxLinkSpeed: %u",
7554 __func__, pCfg->reportMaxLinkSpeed);
7555 rssidx = 0;
7556 }
7557
7558 maxRate = 0;
7559
7560 /* Get Basic Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +05307561 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_OPERATIONAL_RATE_SET,
7562 OperationalRates, &ORLeng))
7563 {
7564 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
7565 /*To keep GUI happy*/
7566 return 0;
7567 }
7568
Jeff Johnson295189b2012-06-20 16:38:30 -07007569 for (i = 0; i < ORLeng; i++)
7570 {
Jeff Johnsone7245742012-09-05 17:12:55 -07007571 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -07007572 {
7573 /* Validate Rate Set */
7574 if (supported_data_rate[j].beacon_rate_index == (OperationalRates[i] & 0x7F))
7575 {
7576 currentRate = supported_data_rate[j].supported_rate[rssidx];
7577 break;
7578 }
7579 }
7580 /* Update MAX rate */
7581 maxRate = (currentRate > maxRate)?currentRate:maxRate;
7582 }
7583
7584 /* Get Extended Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +05307585 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET,
7586 ExtendedRates, &ERLeng))
7587 {
7588 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
7589 /*To keep GUI happy*/
7590 return 0;
7591 }
7592
Jeff Johnson295189b2012-06-20 16:38:30 -07007593 for (i = 0; i < ERLeng; i++)
7594 {
Jeff Johnsone7245742012-09-05 17:12:55 -07007595 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -07007596 {
7597 if (supported_data_rate[j].beacon_rate_index == (ExtendedRates[i] & 0x7F))
7598 {
7599 currentRate = supported_data_rate[j].supported_rate[rssidx];
7600 break;
7601 }
7602 }
7603 /* Update MAX rate */
7604 maxRate = (currentRate > maxRate)?currentRate:maxRate;
7605 }
Kiet Lamb69f8dc2013-11-15 15:34:27 +05307606 /* Get MCS Rate Set --
Kaushik, Sushantdc304d82014-01-22 10:58:37 +05307607 Only if we are always reporting max speed (or)
Kiet Lamb69f8dc2013-11-15 15:34:27 +05307608 if we have good rssi */
Kaushik, Sushantdc304d82014-01-22 10:58:37 +05307609 if ((0 == rssidx) ||
Kiet Lamb69f8dc2013-11-15 15:34:27 +05307610 (eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed))
Jeff Johnson295189b2012-06-20 16:38:30 -07007611 {
Gopichand Nakkala05ab1322013-02-15 11:28:38 +05307612 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_CURRENT_MCS_SET,
7613 MCSRates, &MCSLeng))
7614 {
7615 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
7616 /*To keep GUI happy*/
7617 return 0;
7618 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007619 rateFlag = 0;
Leo Chang6f8870f2013-03-26 18:11:36 -07007620#ifdef WLAN_FEATURE_11AC
7621 /* VHT80 rate has seperate rate table */
Gopichand Nakkala4c705372013-04-24 13:20:33 +05307622 if (rate_flags & (eHAL_TX_RATE_VHT20|eHAL_TX_RATE_VHT40|eHAL_TX_RATE_VHT80))
Jeff Johnson295189b2012-06-20 16:38:30 -07007623 {
Leo Chang6f8870f2013-03-26 18:11:36 -07007624 ccmCfgGetInt(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_VHT_TX_MCS_MAP, &vht_mcs_map);
Gopichand Nakkala4c705372013-04-24 13:20:33 +05307625 vhtMaxMcs = (eDataRate11ACMaxMcs)(vht_mcs_map & DATA_RATE_11AC_MCS_MASK );
Leo Chang6f8870f2013-03-26 18:11:36 -07007626 if (rate_flags & eHAL_TX_RATE_SGI)
Jeff Johnson295189b2012-06-20 16:38:30 -07007627 {
Leo Chang6f8870f2013-03-26 18:11:36 -07007628 rateFlag |= 1;
Jeff Johnson295189b2012-06-20 16:38:30 -07007629 }
Leo Chang6f8870f2013-03-26 18:11:36 -07007630 if (DATA_RATE_11AC_MAX_MCS_7 == vhtMaxMcs)
Jeff Johnson295189b2012-06-20 16:38:30 -07007631 {
Leo Chang6f8870f2013-03-26 18:11:36 -07007632 maxMCSIdx = 7;
7633 }
7634 else if (DATA_RATE_11AC_MAX_MCS_8 == vhtMaxMcs)
7635 {
7636 maxMCSIdx = 8;
7637 }
7638 else if (DATA_RATE_11AC_MAX_MCS_9 == vhtMaxMcs)
7639 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +05307640 //VHT20 is supporting 0~8
7641 if (rate_flags & eHAL_TX_RATE_VHT20)
7642 maxMCSIdx = 8;
7643 else
7644 maxMCSIdx = 9;
Leo Chang6f8870f2013-03-26 18:11:36 -07007645 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +05307646
7647 if (rate_flags & eHAL_TX_RATE_VHT80)
7648 {
7649 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT80_rate[rateFlag];
7650 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT80_rate[rateFlag];
7651 }
7652 else if (rate_flags & eHAL_TX_RATE_VHT40)
7653 {
7654 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT40_rate[rateFlag];
7655 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT40_rate[rateFlag];
7656 }
7657 else if (rate_flags & eHAL_TX_RATE_VHT20)
7658 {
7659 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT20_rate[rateFlag];
7660 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT20_rate[rateFlag];
7661 }
7662
Leo Chang6f8870f2013-03-26 18:11:36 -07007663 maxSpeedMCS = 1;
7664 if (currentRate > maxRate)
7665 {
7666 maxRate = currentRate;
7667 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +05307668
Leo Chang6f8870f2013-03-26 18:11:36 -07007669 }
7670 else
7671#endif /* WLAN_FEATURE_11AC */
7672 {
7673 if (rate_flags & eHAL_TX_RATE_HT40)
7674 {
7675 rateFlag |= 1;
7676 }
7677 if (rate_flags & eHAL_TX_RATE_SGI)
7678 {
7679 rateFlag |= 2;
7680 }
7681
7682 for (i = 0; i < MCSLeng; i++)
7683 {
7684 temp = sizeof(supported_mcs_rate) / sizeof(supported_mcs_rate[0]);
7685 for (j = 0; j < temp; j++)
7686 {
7687 if (supported_mcs_rate[j].beacon_rate_index == MCSRates[i])
7688 {
7689 currentRate = supported_mcs_rate[j].supported_rate[rateFlag];
7690 break;
7691 }
7692 }
7693 if ((j < temp) && (currentRate > maxRate))
7694 {
7695 maxRate = currentRate;
7696 maxSpeedMCS = 1;
7697 maxMCSIdx = supported_mcs_rate[j].beacon_rate_index;
7698 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007699 }
7700 }
7701 }
7702
Gopichand Nakkala4c705372013-04-24 13:20:33 +05307703 else if (!(rate_flags & eHAL_TX_RATE_LEGACY))
7704 {
7705 maxRate = myRate;
7706 maxSpeedMCS = 1;
7707 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
7708 }
7709
Jeff Johnson295189b2012-06-20 16:38:30 -07007710 // make sure we report a value at least as big as our current rate
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07007711 if (((maxRate < myRate) && (0 == rssidx)) ||
7712 (0 == maxRate))
Jeff Johnson295189b2012-06-20 16:38:30 -07007713 {
7714 maxRate = myRate;
7715 if (rate_flags & eHAL_TX_RATE_LEGACY)
7716 {
7717 maxSpeedMCS = 0;
7718 }
7719 else
7720 {
7721 maxSpeedMCS = 1;
7722 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
7723 }
7724 }
7725
Gopichand Nakkala4c705372013-04-24 13:20:33 +05307726 if (rate_flags & eHAL_TX_RATE_LEGACY)
Jeff Johnson295189b2012-06-20 16:38:30 -07007727 {
7728 sinfo->txrate.legacy = maxRate;
7729#ifdef LINKSPEED_DEBUG_ENABLED
7730 pr_info("Reporting legacy rate %d\n", sinfo->txrate.legacy);
7731#endif //LINKSPEED_DEBUG_ENABLED
7732 }
7733 else
7734 {
7735 sinfo->txrate.mcs = maxMCSIdx;
Leo Chang6f8870f2013-03-26 18:11:36 -07007736#ifdef WLAN_FEATURE_11AC
7737 sinfo->txrate.nss = 1;
7738 if (rate_flags & eHAL_TX_RATE_VHT80)
7739 {
7740 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
Gopichand Nakkala4c705372013-04-24 13:20:33 +05307741 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
Leo Chang6f8870f2013-03-26 18:11:36 -07007742 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +05307743 else if (rate_flags & eHAL_TX_RATE_VHT40)
Leo Chang6f8870f2013-03-26 18:11:36 -07007744 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +05307745 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
7746 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
7747 }
7748 else if (rate_flags & eHAL_TX_RATE_VHT20)
7749 {
7750 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
7751 }
7752#endif /* WLAN_FEATURE_11AC */
7753 if (rate_flags & (eHAL_TX_RATE_HT20 | eHAL_TX_RATE_HT40))
7754 {
7755 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
7756 if (rate_flags & eHAL_TX_RATE_HT40)
7757 {
7758 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
7759 }
Leo Chang6f8870f2013-03-26 18:11:36 -07007760 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007761 if (rate_flags & eHAL_TX_RATE_SGI)
7762 {
7763 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
7764 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +05307765
Jeff Johnson295189b2012-06-20 16:38:30 -07007766#ifdef LINKSPEED_DEBUG_ENABLED
7767 pr_info("Reporting MCS rate %d flags %x\n",
7768 sinfo->txrate.mcs,
7769 sinfo->txrate.flags );
7770#endif //LINKSPEED_DEBUG_ENABLED
7771 }
7772 }
7773 else
7774 {
7775 // report current rate instead of max rate
7776
7777 if (rate_flags & eHAL_TX_RATE_LEGACY)
7778 {
7779 //provide to the UI in units of 100kbps
7780 sinfo->txrate.legacy = myRate;
7781#ifdef LINKSPEED_DEBUG_ENABLED
7782 pr_info("Reporting actual legacy rate %d\n", sinfo->txrate.legacy);
7783#endif //LINKSPEED_DEBUG_ENABLED
7784 }
7785 else
7786 {
7787 //must be MCS
7788 sinfo->txrate.mcs = pAdapter->hdd_stats.ClassA_stat.mcs_index;
Leo Chang6f8870f2013-03-26 18:11:36 -07007789#ifdef WLAN_FEATURE_11AC
7790 sinfo->txrate.nss = 1;
7791 if (rate_flags & eHAL_TX_RATE_VHT80)
7792 {
7793 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
7794 }
7795 else
7796#endif /* WLAN_FEATURE_11AC */
7797 {
7798 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
7799 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007800 if (rate_flags & eHAL_TX_RATE_SGI)
7801 {
7802 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
7803 }
7804 if (rate_flags & eHAL_TX_RATE_HT40)
7805 {
7806 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
7807 }
Leo Chang6f8870f2013-03-26 18:11:36 -07007808#ifdef WLAN_FEATURE_11AC
7809 else if (rate_flags & eHAL_TX_RATE_VHT80)
7810 {
7811 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
7812 }
7813#endif /* WLAN_FEATURE_11AC */
Jeff Johnson295189b2012-06-20 16:38:30 -07007814#ifdef LINKSPEED_DEBUG_ENABLED
7815 pr_info("Reporting actual MCS rate %d flags %x\n",
7816 sinfo->txrate.mcs,
7817 sinfo->txrate.flags );
7818#endif //LINKSPEED_DEBUG_ENABLED
7819 }
7820 }
7821 sinfo->filled |= STATION_INFO_TX_BITRATE;
7822
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -07007823 sinfo->tx_packets =
7824 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[0] +
7825 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[1] +
7826 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[2] +
7827 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[3];
7828
7829 sinfo->tx_retries =
7830 pAdapter->hdd_stats.summary_stat.retry_cnt[0] +
7831 pAdapter->hdd_stats.summary_stat.retry_cnt[1] +
7832 pAdapter->hdd_stats.summary_stat.retry_cnt[2] +
7833 pAdapter->hdd_stats.summary_stat.retry_cnt[3];
7834
7835 sinfo->tx_failed =
7836 pAdapter->hdd_stats.summary_stat.fail_cnt[0] +
7837 pAdapter->hdd_stats.summary_stat.fail_cnt[1] +
7838 pAdapter->hdd_stats.summary_stat.fail_cnt[2] +
7839 pAdapter->hdd_stats.summary_stat.fail_cnt[3];
7840
7841 sinfo->filled |=
7842 STATION_INFO_TX_PACKETS |
7843 STATION_INFO_TX_RETRIES |
7844 STATION_INFO_TX_FAILED;
7845
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307846 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7847 TRACE_CODE_HDD_CFG80211_GET_STA,
7848 pAdapter->sessionId, maxRate));
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -07007849 EXIT();
7850 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07007851}
7852
7853static int wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
Sameer Thalappilc9f26e92013-06-07 10:11:06 -07007854 struct net_device *dev, bool mode, int timeout)
Jeff Johnson295189b2012-06-20 16:38:30 -07007855{
7856 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +05307857 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07007858 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307859 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07007860
Jeff Johnsone7245742012-09-05 17:12:55 -07007861 ENTER();
7862
Jeff Johnson295189b2012-06-20 16:38:30 -07007863 if (NULL == pAdapter)
7864 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08007865 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007866 return -ENODEV;
7867 }
7868
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307869 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7870 TRACE_CODE_HDD_CFG80211_SET_POWER_MGMT,
7871 pAdapter->sessionId, timeout));
7872
Gopichand Nakkala20c4c042013-04-19 22:08:55 +05307873 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307874 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +05307875
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307876 if (0 != status)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307877 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307878 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7879 "%s: HDD context is not valid", __func__);
7880 return status;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307881 }
7882
Gopichand Nakkala20c4c042013-04-19 22:08:55 +05307883 if ((DRIVER_POWER_MODE_AUTO == !mode) &&
7884 (TRUE == pHddCtx->hdd_wlan_suspended) &&
7885 (pHddCtx->cfg_ini->fhostArpOffload) &&
7886 (eConnectionState_Associated ==
7887 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
7888 {
Amar Singhald53568e2013-09-26 11:03:45 -07007889
7890 hddLog(VOS_TRACE_LEVEL_INFO,
7891 "offload: in cfg80211_set_power_mgmt, calling arp offload");
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05307892 vos_status = hdd_conf_arp_offload(pAdapter, TRUE);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +05307893 if (!VOS_IS_STATUS_SUCCESS(vos_status))
7894 {
7895 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007896 "%s:Failed to enable ARPOFFLOAD Feature %d",
Gopichand Nakkala20c4c042013-04-19 22:08:55 +05307897 __func__, vos_status);
7898 }
7899 }
7900
Jeff Johnson295189b2012-06-20 16:38:30 -07007901 /**The get power cmd from the supplicant gets updated by the nl only
7902 *on successful execution of the function call
7903 *we are oppositely mapped w.r.t mode in the driver
7904 **/
7905 vos_status = wlan_hdd_enter_bmps(pAdapter, !mode);
7906
Jeff Johnsone7245742012-09-05 17:12:55 -07007907 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07007908 if (VOS_STATUS_E_FAILURE == vos_status)
7909 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307910 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7911 "%s: failed to enter bmps mode", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007912 return -EINVAL;
7913 }
7914 return 0;
7915}
7916
7917
7918#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
7919static int wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
7920 struct net_device *netdev,
7921 u8 key_index)
7922{
Jeff Johnsone7245742012-09-05 17:12:55 -07007923 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07007924 return 0;
7925}
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307926#endif //LINUX_VERSION_CODE
Jeff Johnson295189b2012-06-20 16:38:30 -07007927
7928#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
7929static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
7930 struct net_device *dev,
7931 struct ieee80211_txq_params *params)
7932{
Jeff Johnsone7245742012-09-05 17:12:55 -07007933 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07007934 return 0;
7935}
7936#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
7937static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
7938 struct ieee80211_txq_params *params)
7939{
Jeff Johnsone7245742012-09-05 17:12:55 -07007940 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07007941 return 0;
7942}
7943#endif //LINUX_VERSION_CODE
7944
7945static int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
7946 struct net_device *dev, u8 *mac)
7947{
7948 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307949 hdd_context_t *pHddCtx;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08007950 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307951 int status;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08007952 v_U8_t staId;
Jeff Johnson295189b2012-06-20 16:38:30 -07007953
Jeff Johnsone7245742012-09-05 17:12:55 -07007954 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307955
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307956 if ( NULL == pAdapter )
Jeff Johnson295189b2012-06-20 16:38:30 -07007957 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307958 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007959 return -EINVAL;
7960 }
7961
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307962 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7963 TRACE_CODE_HDD_CFG80211_DEL_STA,
7964 pAdapter->sessionId, pAdapter->device_mode));
7965
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307966 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7967 status = wlan_hdd_validate_context(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07007968
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307969 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007970 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307971 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7972 "%s: HDD context is not valid", __func__);
7973 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007974 }
7975
Jeff Johnson295189b2012-06-20 16:38:30 -07007976 if ( (WLAN_HDD_SOFTAP == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -07007977 || (WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -07007978 )
7979 {
7980 if( NULL == mac )
7981 {
7982 v_U16_t i;
7983 for(i = 0; i < WLAN_MAX_STA_COUNT; i++)
7984 {
Rajesh Chauhan18488fc2013-08-22 10:15:03 -07007985 if ((pAdapter->aStaInfo[i].isUsed) &&
7986 (!pAdapter->aStaInfo[i].isDeauthInProgress))
Jeff Johnson295189b2012-06-20 16:38:30 -07007987 {
7988 u8 *macAddr = pAdapter->aStaInfo[i].macAddrSTA.bytes;
7989 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -08007990 "%s: Delete STA with MAC::"
7991 MAC_ADDRESS_STR,
7992 __func__, MAC_ADDR_ARRAY(macAddr));
Rajesh Chauhan18488fc2013-08-22 10:15:03 -07007993 vos_status = hdd_softap_sta_deauth(pAdapter, macAddr);
7994 if (VOS_IS_STATUS_SUCCESS(vos_status))
7995 pAdapter->aStaInfo[i].isDeauthInProgress = TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -07007996 }
7997 }
7998 }
7999 else
8000 {
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08008001
8002 vos_status = hdd_softap_GetStaId(pAdapter,(v_MACADDR_t *)mac, &staId);
8003 if (!VOS_IS_STATUS_SUCCESS(vos_status))
8004 {
8005 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -08008006 "%s: Skip this DEL STA as this is not used::"
8007 MAC_ADDRESS_STR,
8008 __func__, MAC_ADDR_ARRAY(mac));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08008009 return -ENOENT;
8010 }
8011
8012 if( pAdapter->aStaInfo[staId].isDeauthInProgress == TRUE)
8013 {
8014 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -08008015 "%s: Skip this DEL STA as deauth is in progress::"
8016 MAC_ADDRESS_STR,
8017 __func__, MAC_ADDR_ARRAY(mac));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08008018 return -ENOENT;
8019 }
8020
8021 pAdapter->aStaInfo[staId].isDeauthInProgress = TRUE;
8022
Jeff Johnson295189b2012-06-20 16:38:30 -07008023 hddLog(VOS_TRACE_LEVEL_INFO,
8024 "%s: Delete STA with MAC::"
Arif Hussain24bafea2013-11-15 15:10:03 -08008025 MAC_ADDRESS_STR,
Jeff Johnson295189b2012-06-20 16:38:30 -07008026 __func__,
Arif Hussain24bafea2013-11-15 15:10:03 -08008027 MAC_ADDR_ARRAY(mac));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08008028
8029 vos_status = hdd_softap_sta_deauth(pAdapter, mac);
8030 if (!VOS_IS_STATUS_SUCCESS(vos_status))
8031 {
8032 pAdapter->aStaInfo[staId].isDeauthInProgress = FALSE;
8033 hddLog(VOS_TRACE_LEVEL_INFO,
8034 "%s: STA removal failed for ::"
Arif Hussain24bafea2013-11-15 15:10:03 -08008035 MAC_ADDRESS_STR,
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08008036 __func__,
Arif Hussain24bafea2013-11-15 15:10:03 -08008037 MAC_ADDR_ARRAY(mac));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08008038 return -ENOENT;
8039 }
8040
Jeff Johnson295189b2012-06-20 16:38:30 -07008041 }
8042 }
8043
8044 EXIT();
8045
8046 return 0;
8047}
8048
Hoonki Lee11f7dda2013-02-14 16:55:44 -08008049static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
8050 struct net_device *dev, u8 *mac, struct station_parameters *params)
8051{
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308052 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkalab977a972013-02-18 19:15:09 -08008053 int status = -EPERM;
Hoonki Lee11f7dda2013-02-14 16:55:44 -08008054#ifdef FEATURE_WLAN_TDLS
8055 u32 mask, set;
Hoonki Lee11f7dda2013-02-14 16:55:44 -08008056 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308057
8058 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
8059 TRACE_CODE_HDD_CFG80211_ADD_STA,
8060 pAdapter->sessionId, params->listen_interval));
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008061 mask = params->sta_flags_mask;
8062
8063 set = params->sta_flags_set;
8064
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07008065#ifdef WLAN_FEATURE_TDLS_DEBUG
8066 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8067 "%s: mask 0x%x set 0x%x " MAC_ADDRESS_STR,
8068 __func__, mask, set, MAC_ADDR_ARRAY(mac));
8069#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008070
8071 if (mask & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
8072 if (set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008073 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 0, NULL);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008074 }
8075 }
8076#endif
Gopichand Nakkalab977a972013-02-18 19:15:09 -08008077 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -07008078}
8079
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008080
8081#ifdef FEATURE_WLAN_LFR
Wilson Yang6507c4e2013-10-01 20:11:19 -07008082#define MAX_PMKSAIDS_IN_CACHE 8
8083
8084static tPmkidCacheInfo PMKIDCache[MAX_PMKSAIDS_IN_CACHE]; // HDD local cache
8085static tANI_U32 PMKIDCacheIndex; // HDD local Cache index
8086
8087
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008088static int wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
Jeff Johnsond13512a2012-07-17 11:42:19 -07008089 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008090{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308091 tANI_U32 j=0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008092 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
8093 tHalHandle halHandle;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308094 eHalStatus result;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308095 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008096 tANI_U8 BSSIDMatched = 0;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308097 hdd_context_t *pHddCtx;
Jeff Johnson0299d0a2013-10-30 12:37:43 -07008098 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: set PMKSA for " MAC_ADDRESS_STR,
8099 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
Jeff Johnsone7245742012-09-05 17:12:55 -07008100
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308101 // Validate pAdapter
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308102 if ( NULL == pAdapter )
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008103 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308104 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008105 return -EINVAL;
8106 }
8107
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308108 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8109 status = wlan_hdd_validate_context(pHddCtx);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008110
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308111 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008112 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308113 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8114 "%s: HDD context is not valid", __func__);
8115 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008116 }
8117
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308118 // Retrieve halHandle
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008119 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
8120
Wilson Yang6507c4e2013-10-01 20:11:19 -07008121 for (j = 0; j < PMKIDCacheIndex; j++)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008122 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308123 if(vos_mem_compare(PMKIDCache[j].BSSID,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008124 pmksa->bssid, WNI_CFG_BSSID_LEN))
8125 {
8126 /* BSSID matched previous entry. Overwrite it. */
8127 BSSIDMatched = 1;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308128 vos_mem_copy(PMKIDCache[j].BSSID,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008129 pmksa->bssid, WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308130 vos_mem_copy(PMKIDCache[j].PMKID,
8131 pmksa->pmkid,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008132 CSR_RSN_PMKID_SIZE);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308133 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Reusing cache entry %d.",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008134 __func__, j );
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008135 dump_bssid(pmksa->bssid);
8136 dump_pmkid(halHandle, pmksa->pmkid);
8137 break;
8138 }
8139 }
8140
Madan Mohan Koyyalamudic4b317d2012-10-18 19:43:08 -07008141 /* Check we compared all entries,if then take the first slot now */
Wilson Yang6507c4e2013-10-01 20:11:19 -07008142 if(j == MAX_PMKSAIDS_IN_CACHE) PMKIDCacheIndex=0;
Madan Mohan Koyyalamudic4b317d2012-10-18 19:43:08 -07008143
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008144 if (!BSSIDMatched)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308145 {
8146 // Now, we DON'T have a BSSID match, so take a new entry in the cache.
Wilson Yang6507c4e2013-10-01 20:11:19 -07008147 vos_mem_copy(PMKIDCache[PMKIDCacheIndex].BSSID,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308148 pmksa->bssid, ETHER_ADDR_LEN);
Wilson Yang6507c4e2013-10-01 20:11:19 -07008149 vos_mem_copy(PMKIDCache[PMKIDCacheIndex].PMKID,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308150 pmksa->pmkid,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008151 CSR_RSN_PMKID_SIZE);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308152 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Adding a new cache entry %d.",
Wilson Yang6507c4e2013-10-01 20:11:19 -07008153 __func__, PMKIDCacheIndex );
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008154 dump_bssid(pmksa->bssid);
8155 dump_pmkid(halHandle, pmksa->pmkid);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308156 // Increment the HDD Local Cache index
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008157 // The "i=0" doesn't work for the call to sme_RoamSetPMKIDCache() - LFR FIXME
Wilson Yang6507c4e2013-10-01 20:11:19 -07008158 if (PMKIDCacheIndex <= (MAX_PMKSAIDS_IN_CACHE-1)) PMKIDCacheIndex++; else PMKIDCacheIndex = 0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008159 }
8160
8161
8162 // Calling csrRoamSetPMKIDCache to configure the PMKIDs into the cache
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308163 //hddLog(LOG1, FL("%s: Calling csrRoamSetPMKIDCache with %d cache entries."),
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008164 // __func__, i );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308165 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Calling csrRoamSetPMKIDCache with %d cache entries.",
Wilson Yang6507c4e2013-10-01 20:11:19 -07008166 __func__, PMKIDCacheIndex );
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008167 // Finally set the PMKSA ID Cache in CSR
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308168 result = sme_RoamSetPMKIDCache(halHandle,pAdapter->sessionId,
8169 PMKIDCache,
Wilson Yang6507c4e2013-10-01 20:11:19 -07008170 PMKIDCacheIndex);
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308171 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
8172 TRACE_CODE_HDD_CFG80211_SET_PMKSA,
8173 pAdapter->sessionId, result));
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008174 return 0;
8175}
8176
8177
Wilson Yang6507c4e2013-10-01 20:11:19 -07008178
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008179static int wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
Wilson Yang6507c4e2013-10-01 20:11:19 -07008180 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008181{
Wilson Yang6507c4e2013-10-01 20:11:19 -07008182 tANI_U32 j=0;
8183 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
8184 tHalHandle halHandle;
Wilson Yang6507c4e2013-10-01 20:11:19 -07008185 tANI_U8 BSSIDMatched = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -07008186 hdd_context_t *pHddCtx;
Wilson Yangef657d32014-01-15 19:19:23 -08008187 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -07008188
Jeff Johnson0299d0a2013-10-30 12:37:43 -07008189 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: deleting PMKSA for " MAC_ADDRESS_STR,
8190 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
Wilson Yang6507c4e2013-10-01 20:11:19 -07008191
8192 /* Validate pAdapter */
8193 if (NULL == pAdapter)
8194 {
8195 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
8196 return -EINVAL;
8197 }
8198
8199 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8200 status = wlan_hdd_validate_context(pHddCtx);
8201
8202 if (0 != status)
8203 {
8204 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8205 "%s: HDD context is not valid", __func__);
8206 return status;
8207 }
8208
8209 /*Retrieve halHandle*/
8210 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
8211
8212 /*in case index is 0,no entry to delete*/
8213 if (0 == PMKIDCacheIndex)
8214 {
8215 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid entry to delete" ,
8216 __func__);
8217 return -EINVAL;
8218 }
8219
8220 /*find the matching PMKSA entry from j=0 to (index-1),
8221 * and delete the matched one
8222 */
8223 for (j = 0; j<PMKIDCacheIndex; j++)
8224 {
8225 if (vos_mem_compare(PMKIDCache[j].BSSID,
8226 pmksa->bssid,
8227 WNI_CFG_BSSID_LEN))
8228 {
8229 /* BSSID matched entry */
8230 BSSIDMatched = 1;
8231
8232 if (j<PMKIDCacheIndex-1)
8233 {
8234 /*replace the matching entry with the last entry in HDD local cache*/
8235 vos_mem_copy(PMKIDCache[j].BSSID,
8236 PMKIDCache[PMKIDCacheIndex-1].BSSID,
8237 WNI_CFG_BSSID_LEN);
8238 vos_mem_copy(PMKIDCache[j].PMKID,
8239 PMKIDCache[PMKIDCacheIndex-1].PMKID,
8240 CSR_RSN_PMKID_SIZE);
8241 }
8242
8243 /*clear the last entry in HDD cache ---[index-1]*/
Wilson Yang6507c4e2013-10-01 20:11:19 -07008244 vos_mem_zero(PMKIDCache[PMKIDCacheIndex-1].BSSID, WNI_CFG_BSSID_LEN);
8245 vos_mem_zero(PMKIDCache[PMKIDCacheIndex-1].PMKID, CSR_RSN_PMKID_SIZE);
8246
8247 /*reduce the PMKID array index*/
8248 PMKIDCacheIndex--;
8249
8250 /*delete the last PMKID cache in CSR*/
Wilson Yangef657d32014-01-15 19:19:23 -08008251 if (eHAL_STATUS_SUCCESS !=
8252 sme_RoamDelPMKIDfromCache(halHandle, pAdapter->sessionId, pmksa->bssid))
Wilson Yang6507c4e2013-10-01 20:11:19 -07008253 {
8254 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: cannot delete PMKSA %d CONTENT.",
8255 __func__,PMKIDCacheIndex);
Wilson Yangef657d32014-01-15 19:19:23 -08008256 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -07008257 }
8258
8259 dump_bssid(pmksa->bssid);
8260 dump_pmkid(halHandle,pmksa->pmkid);
8261
8262 break;
8263 }
8264 }
8265
8266 /* we compare all entries,but cannot find matching entry */
8267 if (j == MAX_PMKSAIDS_IN_CACHE && !BSSIDMatched)
8268 {
Jeff Johnson0299d0a2013-10-30 12:37:43 -07008269 hddLog(VOS_TRACE_LEVEL_FATAL,
8270 "%s: No such PMKSA entry existed " MAC_ADDRESS_STR,
8271 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
Wilson Yang6507c4e2013-10-01 20:11:19 -07008272 dump_bssid(pmksa->bssid);
8273 dump_pmkid(halHandle, pmksa->pmkid);
8274 return -EINVAL;
8275 }
Wilson Yangef657d32014-01-15 19:19:23 -08008276 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008277}
8278
Wilson Yang6507c4e2013-10-01 20:11:19 -07008279
8280
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008281static int wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
8282{
Wilson Yang6507c4e2013-10-01 20:11:19 -07008283 tANI_U32 j=0;
8284 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
8285 tHalHandle halHandle;
8286 hdd_context_t *pHddCtx;
8287 tANI_U8 *pBSSId;
Wilson Yangef657d32014-01-15 19:19:23 -08008288 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -07008289
8290 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: flushing PMKSA ",__func__);
8291
8292 /* Validate pAdapter */
8293 if (NULL == pAdapter)
8294 {
8295 hddLog(VOS_TRACE_LEVEL_ERROR,
8296 "%s: Invalid Adapter" ,__func__);
8297 return -EINVAL;
8298 }
8299
8300 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8301 status = wlan_hdd_validate_context(pHddCtx);
8302
8303 if (0 != status)
8304 {
8305 hddLog(VOS_TRACE_LEVEL_ERROR,
8306 "%s: HDD context is not valid", __func__);
8307 return status;
8308 }
8309
8310 /*Retrieve halHandle*/
8311 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
8312
8313 /*in case index is 0,no entry to delete*/
8314 if (0 == PMKIDCacheIndex)
8315 {
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +05308316 hddLog(VOS_TRACE_LEVEL_ERROR, FL("No entries to flush"));
Wilson Yang6507c4e2013-10-01 20:11:19 -07008317 return -EINVAL;
8318 }
8319
8320 /*delete all the PMKSA one by one */
8321 for (j = 0; j<PMKIDCacheIndex; j++)
8322 {
Wilson Yang6507c4e2013-10-01 20:11:19 -07008323 pBSSId =(tANI_U8 *)(PMKIDCache[j].BSSID);
Wilson Yang6507c4e2013-10-01 20:11:19 -07008324
8325 /*delete the PMKID in CSR*/
Wilson Yangef657d32014-01-15 19:19:23 -08008326 if (eHAL_STATUS_SUCCESS !=
8327 sme_RoamDelPMKIDfromCache(halHandle, pAdapter->sessionId, pBSSId))
Wilson Yang6507c4e2013-10-01 20:11:19 -07008328 {
8329 hddLog(VOS_TRACE_LEVEL_ERROR ,"%s cannot flush PMKIDCache %d.",
8330 __func__,j);
Wilson Yangef657d32014-01-15 19:19:23 -08008331 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -07008332 }
Kiet Lam8d21d5b2013-10-31 17:18:29 +05308333 /*clear the entry in HDD cache 0--index-1 */
8334 vos_mem_zero(PMKIDCache[j].BSSID, WNI_CFG_BSSID_LEN);
8335 vos_mem_zero(PMKIDCache[j].PMKID, CSR_RSN_PMKID_SIZE);
Wilson Yang6507c4e2013-10-01 20:11:19 -07008336 }
8337
8338 PMKIDCacheIndex = 0;
Wilson Yangef657d32014-01-15 19:19:23 -08008339 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008340}
8341#endif
8342
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07008343#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308344static int wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07008345 struct net_device *dev, struct cfg80211_update_ft_ies_params *ftie)
8346{
8347 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
8348 hdd_station_ctx_t *pHddStaCtx;
8349
8350 if (NULL == pAdapter)
8351 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08008352 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07008353 return -ENODEV;
8354 }
8355
8356 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
8357
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308358 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
8359 TRACE_CODE_HDD_CFG80211_UPDATE_FT_IES,
8360 pAdapter->sessionId, pHddStaCtx->conn_info.connState));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07008361 // Added for debug on reception of Re-assoc Req.
8362 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
8363 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08008364 hddLog(LOGE, FL("Called with Ie of length = %zu when not associated"),
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07008365 ftie->ie_len);
Arif Hussain6d2a3322013-11-17 19:50:10 -08008366 hddLog(LOGE, FL("Should be Re-assoc Req IEs"));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07008367 }
8368
8369#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG
Arif Hussain6d2a3322013-11-17 19:50:10 -08008370 hddLog(LOGE, FL("%s called with Ie of length = %zu"), __func__,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07008371 ftie->ie_len);
8372#endif
8373
8374 // Pass the received FT IEs to SME
Gopichand Nakkala356fb102013-03-06 12:34:04 +05308375 sme_SetFTIEs( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
8376 (const u8 *)ftie->ie,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07008377 ftie->ie_len);
8378 return 0;
8379}
8380#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008381
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308382#ifdef FEATURE_WLAN_SCAN_PNO
8383
8384void hdd_cfg80211_sched_scan_done_callback(void *callbackContext,
8385 tSirPrefNetworkFoundInd *pPrefNetworkFoundInd)
8386{
8387 int ret;
8388 hdd_adapter_t* pAdapter = (hdd_adapter_t*)callbackContext;
8389 hdd_context_t *pHddCtx;
8390
Nirav Shah80830bf2013-12-31 16:35:12 +05308391 ENTER();
8392
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308393 if (NULL == pAdapter)
8394 {
Agarwal Ashish971c2882013-10-30 20:11:12 +05308395 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308396 "%s: HDD adapter is Null", __func__);
8397 return ;
8398 }
8399
8400 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8401 if (NULL == pHddCtx)
8402 {
8403 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8404 "%s: HDD context is Null!!!", __func__);
8405 return ;
8406 }
8407
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05308408 spin_lock(&pHddCtx->schedScan_lock);
8409 if (TRUE == pHddCtx->isWiphySuspended)
8410 {
8411 pHddCtx->isSchedScanUpdatePending = TRUE;
8412 spin_unlock(&pHddCtx->schedScan_lock);
8413 hddLog(VOS_TRACE_LEVEL_INFO,
8414 "%s: Update cfg80211 scan database after it resume", __func__);
8415 return ;
8416 }
8417 spin_unlock(&pHddCtx->schedScan_lock);
8418
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308419 ret = wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter);
8420
8421 if (0 > ret)
8422 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
8423
8424 cfg80211_sched_scan_results(pHddCtx->wiphy);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05308425 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8426 "%s: cfg80211 scan result database updated", __func__);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308427}
8428
8429/*
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +05308430 * FUNCTION: wlan_hdd_is_pno_allowed
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +05308431 * Disallow pno if any session is active
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +05308432 */
8433static eHalStatus wlan_hdd_is_pno_allowed(hdd_adapter_t *pAdapter)
8434{
8435 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
8436 hdd_adapter_t *pTempAdapter = NULL;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +05308437 hdd_station_ctx_t *pStaCtx;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +05308438 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8439 int status = 0;
8440 status = hdd_get_front_adapter(pHddCtx, &pAdapterNode);
8441
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +05308442 /* The current firmware design does not allow PNO during any
8443 * active sessions. Hence, determine the active sessions
8444 * and return a failure.
8445 */
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +05308446 while ((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status))
8447 {
8448 pTempAdapter = pAdapterNode->pAdapter;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +05308449 pStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pTempAdapter);
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +05308450
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +05308451 if (((WLAN_HDD_INFRA_STATION == pTempAdapter->device_mode)
8452 && (eConnectionState_NotConnected != pStaCtx->conn_info.connState))
8453 || (WLAN_HDD_P2P_CLIENT == pTempAdapter->device_mode)
8454 || (WLAN_HDD_P2P_GO == pTempAdapter->device_mode)
8455 || (WLAN_HDD_SOFTAP == pTempAdapter->device_mode)
8456 )
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +05308457 {
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +05308458 return eHAL_STATUS_FAILURE;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +05308459 }
8460 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
8461 pAdapterNode = pNext;
8462 }
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +05308463 return eHAL_STATUS_SUCCESS;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +05308464}
8465
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +05308466void hdd_cfg80211_sched_scan_start_status_cb(void *callbackContext, VOS_STATUS status)
8467{
8468 hdd_adapter_t *pAdapter = callbackContext;
8469 hdd_context_t *pHddCtx;
8470
8471 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
8472 {
8473 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8474 FL("Invalid adapter or adapter has invalid magic"));
8475 return;
8476 }
8477
8478 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8479 if (0 != wlan_hdd_validate_context(pHddCtx))
8480 {
8481 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8482 FL("HDD context is not valid"));
8483 return;
8484 }
8485
8486 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8487 FL("PNO enable response status = %d"), status);
8488
8489 pAdapter->pno_req_status = (status == VOS_STATUS_SUCCESS) ? 0 : -EBUSY;
8490 complete(&pAdapter->pno_comp_var);
8491}
8492
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +05308493/*
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308494 * FUNCTION: wlan_hdd_cfg80211_sched_scan_start
8495 * NL interface to enable PNO
8496 */
8497static int wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
8498 struct net_device *dev, struct cfg80211_sched_scan_request *request)
8499{
8500 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
8501 tpSirPNOScanReq pPnoRequest = NULL;
8502 hdd_context_t *pHddCtx;
8503 tHalHandle hHal;
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +05308504 v_U32_t i, indx, num_ch, tempInterval;
Sushant Kaushikd62d9782014-02-19 15:39:40 +05308505 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
8506 u8 channels_allowed[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308507 v_U32_t num_channels_allowed = WNI_CFG_VALID_CHANNEL_LIST_LEN;
8508 eHalStatus status = eHAL_STATUS_FAILURE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308509 int ret = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308510
8511 if (NULL == pAdapter)
8512 {
8513 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
8514 "%s: HDD adapter is Null", __func__);
8515 return -ENODEV;
8516 }
8517
8518 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05308519 ret = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308520
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05308521 if (0 != ret)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308522 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05308523 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8524 "%s: HDD context is not valid", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308525 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308526 }
8527
8528 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
8529 if (NULL == hHal)
8530 {
8531 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8532 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05308533 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308534 }
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +05308535
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +05308536 if (eHAL_STATUS_SUCCESS != wlan_hdd_is_pno_allowed(pAdapter))
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +05308537 {
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +05308538 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +05308539 FL("Cannot handle sched_scan"));
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +05308540 return -EBUSY;
8541 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308542
c_hpothu37f21312014-04-09 21:49:54 +05308543 if (TRUE == pHddCtx->isPnoEnable)
8544 {
8545 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
8546 FL("already PNO is enabled"));
8547 return -EBUSY;
8548 }
8549 pHddCtx->isPnoEnable = TRUE;
8550
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308551 pPnoRequest = (tpSirPNOScanReq) vos_mem_malloc(sizeof (tSirPNOScanReq));
8552 if (NULL == pPnoRequest)
8553 {
8554 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
8555 "%s: vos_mem_malloc failed", __func__);
c_hpothu37f21312014-04-09 21:49:54 +05308556 pHddCtx->isPnoEnable = FALSE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308557 return -ENOMEM;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308558 }
8559
Madan Mohan Koyyalamudic3f04352013-09-26 19:21:48 +05308560 memset(pPnoRequest, 0, sizeof (tSirPNOScanReq));
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308561 pPnoRequest->enable = 1; /*Enable PNO */
8562 pPnoRequest->ucNetworksCount = request->n_match_sets;
8563
8564 if (( !pPnoRequest->ucNetworksCount ) ||
8565 ( pPnoRequest->ucNetworksCount > SIR_PNO_MAX_SUPP_NETWORKS ))
8566 {
8567 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik1e406c32014-05-09 15:57:52 +05308568 "%s: Network input is not correct %d Max Network supported is %d",
8569 __func__, pPnoRequest->ucNetworksCount,
8570 SIR_PNO_MAX_SUPP_NETWORKS);
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308571 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308572 goto error;
8573 }
8574
8575 if ( SIR_PNO_MAX_NETW_CHANNELS_EX < request->n_channels )
8576 {
8577 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +05308578 "%s: Incorrect number of channels %d",
8579 __func__, request->n_channels);
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308580 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308581 goto error;
8582 }
8583
8584 /* Framework provides one set of channels(all)
8585 * common for all saved profile */
8586 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
8587 channels_allowed, &num_channels_allowed))
8588 {
8589 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8590 "%s: failed to get valid channel list", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308591 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308592 goto error;
8593 }
8594 /* Checking each channel against allowed channel list */
8595 num_ch = 0;
Nirav Shah80830bf2013-12-31 16:35:12 +05308596 if (request->n_channels)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308597 {
Nirav Shah80830bf2013-12-31 16:35:12 +05308598 char chList [(request->n_channels*5)+1];
8599 int len;
8600 for (i = 0, len = 0; i < request->n_channels; i++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308601 {
Nirav Shah80830bf2013-12-31 16:35:12 +05308602 for (indx = 0; indx < num_channels_allowed; indx++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308603 {
Nirav Shah80830bf2013-12-31 16:35:12 +05308604 if (request->channels[i]->hw_value == channels_allowed[indx])
8605 {
8606 valid_ch[num_ch++] = request->channels[i]->hw_value;
8607 len += snprintf(chList+len, 5, "%d ",
8608 request->channels[i]->hw_value);
8609 break ;
8610 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308611 }
8612 }
Nirav Shah80830bf2013-12-31 16:35:12 +05308613 hddLog(VOS_TRACE_LEVEL_INFO,"Channel-List: %s ", chList);
8614 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308615
8616 /* Filling per profile params */
8617 for (i = 0; i < pPnoRequest->ucNetworksCount; i++)
8618 {
8619 pPnoRequest->aNetworks[i].ssId.length =
8620 request->match_sets[i].ssid.ssid_len;
8621
8622 if (( 0 == pPnoRequest->aNetworks[i].ssId.length ) ||
8623 ( pPnoRequest->aNetworks[i].ssId.length > 32 ) )
8624 {
8625 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +05308626 "%s: SSID Len %d is not correct for network %d",
8627 __func__, pPnoRequest->aNetworks[i].ssId.length, i);
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308628 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308629 goto error;
8630 }
8631
8632 memcpy(pPnoRequest->aNetworks[i].ssId.ssId,
8633 request->match_sets[i].ssid.ssid,
8634 request->match_sets[i].ssid.ssid_len);
Sushant Kaushik1e406c32014-05-09 15:57:52 +05308635 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8636 "%s: SSID of network %d is %s ", __func__,
8637 i, pPnoRequest->aNetworks[i].ssId.ssId);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308638 pPnoRequest->aNetworks[i].authentication = 0; /*eAUTH_TYPE_ANY*/
8639 pPnoRequest->aNetworks[i].encryption = 0; /*eED_ANY*/
8640 pPnoRequest->aNetworks[i].bcastNetwType = 0; /*eBCAST_UNKNOWN*/
8641
8642 /*Copying list of valid channel into request */
8643 memcpy(pPnoRequest->aNetworks[i].aChannels, valid_ch, num_ch);
8644 pPnoRequest->aNetworks[i].ucChannelCount = num_ch;
8645
8646 pPnoRequest->aNetworks[i].rssiThreshold = 0; //Default value
8647 }
8648
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +05308649 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnson59a121e2013-11-30 09:46:08 -08008650 "request->ie_len = %zu", request->ie_len);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +05308651 if ((0 < request->ie_len) && (NULL != request->ie))
8652 {
8653 pPnoRequest->us24GProbeTemplateLen = request->ie_len;
8654 memcpy(&pPnoRequest->p24GProbeTemplate, request->ie,
8655 pPnoRequest->us24GProbeTemplateLen);
8656
8657 pPnoRequest->us5GProbeTemplateLen = request->ie_len;
8658 memcpy(&pPnoRequest->p5GProbeTemplate, request->ie,
8659 pPnoRequest->us5GProbeTemplateLen);
8660 }
8661
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +05308662 /* Driver gets only one time interval which is hardcoded in
8663 * supplicant for 10000ms. Taking power consumption into account 6 timers
8664 * will be used, Timervalue is increased exponentially i.e 10,20,40,
8665 * 80,160,320 secs. And number of scan cycle for each timer
8666 * is configurable through INI param gPNOScanTimerRepeatValue.
8667 * If it is set to 0 only one timer will be used and PNO scan cycle
8668 * will be repeated after each interval specified by supplicant
8669 * till PNO is disabled.
8670 */
8671 if (0 == pHddCtx->cfg_ini->configPNOScanTimerRepeatValue)
8672 pPnoRequest->scanTimers.ucScanTimersCount = HDD_PNO_SCAN_TIMERS_SET_ONE;
8673 else
8674 pPnoRequest->scanTimers.ucScanTimersCount =
8675 HDD_PNO_SCAN_TIMERS_SET_MULTIPLE;
8676
8677 tempInterval = (request->interval)/1000;
8678 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8679 "Base scan interval = %d PNOScanTimerRepeatValue = %d",
8680 tempInterval, pHddCtx->cfg_ini->configPNOScanTimerRepeatValue);
8681 for ( i = 0; i < pPnoRequest->scanTimers.ucScanTimersCount; i++)
8682 {
8683 pPnoRequest->scanTimers.aTimerValues[i].uTimerRepeat =
8684 pHddCtx->cfg_ini->configPNOScanTimerRepeatValue;
8685 pPnoRequest->scanTimers.aTimerValues[i].uTimerValue = tempInterval;
8686 tempInterval *= 2;
8687 }
8688 //Repeat last timer until pno disabled.
8689 pPnoRequest->scanTimers.aTimerValues[i-1].uTimerRepeat = 0;
8690
Madan Mohan Koyyalamudid206c7b2013-09-26 22:54:51 +05308691 pPnoRequest->modePNO = SIR_PNO_MODE_IMMEDIATE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308692
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +05308693 INIT_COMPLETION(pAdapter->pno_comp_var);
8694 pPnoRequest->statusCallback = hdd_cfg80211_sched_scan_start_status_cb;
8695 pPnoRequest->callbackContext = pAdapter;
8696 pAdapter->pno_req_status = 0;
8697
Nirav Shah80830bf2013-12-31 16:35:12 +05308698 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8699 "SessionId %d, enable %d, modePNO %d, ucScanTimersCount %d",
8700 pAdapter->sessionId, pPnoRequest->enable, pPnoRequest->modePNO,
8701 pPnoRequest->scanTimers.ucScanTimersCount);
8702
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308703 status = sme_SetPreferredNetworkList(WLAN_HDD_GET_HAL_CTX(pAdapter),
8704 pPnoRequest, pAdapter->sessionId,
8705 hdd_cfg80211_sched_scan_done_callback, pAdapter);
8706 if (eHAL_STATUS_SUCCESS != status)
8707 {
8708 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +05308709 "%s: Failed to enable PNO", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308710 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308711 goto error;
8712 }
8713
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +05308714 ret = wait_for_completion_timeout(
8715 &pAdapter->pno_comp_var,
8716 msecs_to_jiffies(WLAN_WAIT_TIME_PNO));
8717 if (0 >= ret)
8718 {
8719 // Did not receive the response for PNO enable in time.
8720 // Assuming the PNO enable was success.
8721 // Returning error from here, because we timeout, results
8722 // in side effect of Wifi (Wifi Setting) not to work.
8723 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8724 FL("Timed out waiting for PNO to be Enabled"));
8725 ret = 0;
8726 goto error;
8727 }
8728
8729 ret = pAdapter->pno_req_status;
c_hpothu37f21312014-04-09 21:49:54 +05308730 return ret;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05308731
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308732error:
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +05308733 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8734 FL("PNO scanRequest offloaded ret = %d"), ret);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308735 vos_mem_free(pPnoRequest);
c_hpothu37f21312014-04-09 21:49:54 +05308736 pHddCtx->isPnoEnable = FALSE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308737 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308738}
8739
8740/*
8741 * FUNCTION: wlan_hdd_cfg80211_sched_scan_stop
8742 * NL interface to disable PNO
8743 */
8744static int wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
8745 struct net_device *dev)
8746{
8747 eHalStatus status = eHAL_STATUS_FAILURE;
8748 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
8749 hdd_context_t *pHddCtx;
8750 tHalHandle hHal;
8751 tpSirPNOScanReq pPnoRequest = NULL;
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308752 int ret = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308753
8754 ENTER();
8755
8756 if (NULL == pAdapter)
8757 {
8758 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
8759 "%s: HDD adapter is Null", __func__);
8760 return -ENODEV;
8761 }
8762
8763 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308764
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308765 if (NULL == pHddCtx)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308766 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05308767 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308768 "%s: HDD context is Null", __func__);
8769 return -ENODEV;
8770 }
8771
8772 /* The return 0 is intentional when isLogpInProgress and
8773 * isLoadUnloadInProgress. We did observe a crash due to a return of
8774 * failure in sched_scan_stop , especially for a case where the unload
8775 * of the happens at the same time. The function __cfg80211_stop_sched_scan
8776 * was clearing rdev->sched_scan_req only when the sched_scan_stop returns
8777 * success. If it returns a failure , then its next invocation due to the
8778 * clean up of the second interface will have the dev pointer corresponding
8779 * to the first one leading to a crash.
8780 */
8781 if (pHddCtx->isLogpInProgress)
8782 {
8783 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8784 "%s: LOGP in Progress. Ignore!!!", __func__);
8785 return ret;
8786 }
8787
Mihir Shete18156292014-03-11 15:38:30 +05308788 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308789 {
8790 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8791 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
8792 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308793 }
8794
8795 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
8796 if (NULL == hHal)
8797 {
8798 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8799 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05308800 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308801 }
8802
8803 pPnoRequest = (tpSirPNOScanReq) vos_mem_malloc(sizeof (tSirPNOScanReq));
8804 if (NULL == pPnoRequest)
8805 {
8806 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
8807 "%s: vos_mem_malloc failed", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308808 return -ENOMEM;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308809 }
8810
8811 memset(pPnoRequest, 0, sizeof (tSirPNOScanReq));
8812 pPnoRequest->enable = 0; /* Disable PNO */
8813 pPnoRequest->ucNetworksCount = 0;
8814
8815 status = sme_SetPreferredNetworkList(hHal, pPnoRequest,
8816 pAdapter->sessionId,
8817 NULL, pAdapter);
8818 if (eHAL_STATUS_SUCCESS != status)
8819 {
8820 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8821 "Failed to disabled PNO");
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308822 ret = -EINVAL;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +05308823 goto error;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308824 }
c_hpothu37f21312014-04-09 21:49:54 +05308825 pHddCtx->isPnoEnable = FALSE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308826
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +05308827error:
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05308828 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +05308829 FL("PNO scan disabled ret = %d"), ret);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308830 vos_mem_free(pPnoRequest);
8831
8832 EXIT();
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308833 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308834}
8835
8836#endif /*FEATURE_WLAN_SCAN_PNO*/
8837
8838
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008839#ifdef FEATURE_WLAN_TDLS
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +05308840#if TDLS_MGMT_VERSION2
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008841static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
8842 u8 *peer, u8 action_code, u8 dialog_token,
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +05308843 u16 status_code, u32 peer_capability, const u8 *buf, size_t len)
8844#else
8845static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
8846 u8 *peer, u8 action_code, u8 dialog_token,
8847 u16 status_code, const u8 *buf, size_t len)
8848#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008849{
8850
8851 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
8852 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008853 u8 peerMac[6];
8854 VOS_STATUS status;
Gopichand Nakkala05922802013-03-14 12:23:19 -07008855 int max_sta_failed = 0;
Hoonki Leea34dd892013-02-05 22:56:02 -08008856 int responder;
Hoonki Leed37cbb32013-04-20 00:31:14 -07008857 long rc;
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +05308858#if !(TDLS_MGMT_VERSION2)
8859 u32 peer_capability = 0;
8860#endif
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05308861 tANI_U16 numCurrTdlsPeers;
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008862
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308863 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
8864 TRACE_CODE_HDD_CFG80211_TDLS_MGMT,
8865 pAdapter->sessionId, action_code));
Hoonki Lee11f7dda2013-02-14 16:55:44 -08008866 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008867 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308868 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008869 "Invalid arguments");
8870 return -EINVAL;
8871 }
8872
Sameer Thalappil75ea31a2013-02-21 19:38:16 -08008873 if (pHddCtx->isLogpInProgress)
8874 {
8875 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8876 "%s:LOGP in Progress. Ignore!!!", __func__);
Gopichand Nakkala05922802013-03-14 12:23:19 -07008877 wlan_hdd_tdls_set_link_status(pAdapter, peer, eTDLS_LINK_IDLE);
Sameer Thalappil75ea31a2013-02-21 19:38:16 -08008878 return -EBUSY;
8879 }
8880
Hoonki Lee27511902013-03-14 18:19:06 -07008881 if (eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode)
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008882 {
Hoonki Lee27511902013-03-14 18:19:06 -07008883 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
8884 "%s: TDLS mode is disabled OR not enabled in FW."
8885 MAC_ADDRESS_STR " action %d declined.",
8886 __func__, MAC_ADDR_ARRAY(peer), action_code);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008887 return -ENOTSUPP;
8888 }
Lee Hoonkic1262f22013-01-24 21:59:00 -08008889
Hoonki Lee27511902013-03-14 18:19:06 -07008890 /* other than teardown frame, other mgmt frames are not sent if disabled */
8891 if (SIR_MAC_TDLS_TEARDOWN != action_code)
8892 {
8893 /* if tdls_mode is disabled to respond to peer's request */
8894 if (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode)
8895 {
8896 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
8897 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07008898 " TDLS mode is disabled. action %d declined.",
8899 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee27511902013-03-14 18:19:06 -07008900
8901 return -ENOTSUPP;
8902 }
8903 }
8904
Gopichand Nakkalab977a972013-02-18 19:15:09 -08008905 if (WLAN_IS_TDLS_SETUP_ACTION(action_code))
8906 {
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308907 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, peer, TRUE))
Gopichand Nakkalab977a972013-02-18 19:15:09 -08008908 {
8909 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07008910 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07008911 " TDLS setup is ongoing. action %d declined.",
8912 __func__, MAC_ADDR_ARRAY(peer), action_code);
8913 return -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -08008914 }
8915 }
8916
Hoonki Lee11f7dda2013-02-14 16:55:44 -08008917 if (SIR_MAC_TDLS_SETUP_REQ == action_code ||
8918 SIR_MAC_TDLS_SETUP_RSP == action_code )
Lee Hoonkic1262f22013-01-24 21:59:00 -08008919 {
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05308920 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
8921 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Lee Hoonkic1262f22013-01-24 21:59:00 -08008922 {
8923 /* supplicant still sends tdls_mgmt(SETUP_REQ) even after
8924 we return error code at 'add_station()'. Hence we have this
8925 check again in addtion to add_station().
8926 Anyway, there is no hard to double-check. */
Hoonki Lee11f7dda2013-02-14 16:55:44 -08008927 if (SIR_MAC_TDLS_SETUP_REQ == action_code)
Lee Hoonkic1262f22013-01-24 21:59:00 -08008928 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07008929 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8930 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05308931 " TDLS Max peer already connected. action (%d) declined. Num of peers (%d), Max allowed (%d).",
8932 __func__, MAC_ADDR_ARRAY(peer), action_code,
8933 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Sunil Dutt388ac8f2013-11-28 18:06:52 +05308934 return -EINVAL;
Lee Hoonkic1262f22013-01-24 21:59:00 -08008935 }
8936 else
8937 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -08008938 /* maximum reached. tweak to send error code to peer and return
8939 error code to supplicant */
Lee Hoonkic1262f22013-01-24 21:59:00 -08008940 status_code = eSIR_MAC_UNSPEC_FAILURE_STATUS;
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07008941 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8942 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05308943 " TDLS Max peer already connected, send response status (%d). Num of peers (%d), Max allowed (%d).",
8944 __func__, MAC_ADDR_ARRAY(peer), status_code,
8945 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -07008946 max_sta_failed = -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -08008947 /* fall through to send setup resp with failure status
8948 code */
Lee Hoonkic1262f22013-01-24 21:59:00 -08008949 }
8950 }
Hoonki Lee11f7dda2013-02-14 16:55:44 -08008951 else
8952 {
8953 hddTdlsPeer_t *pTdlsPeer;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308954 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008955 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Hoonki Lee11f7dda2013-02-14 16:55:44 -08008956 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07008957 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07008958 "%s:" MAC_ADDRESS_STR " already connected. action %d declined.",
8959 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee11f7dda2013-02-14 16:55:44 -08008960 return -EPERM;
8961 }
8962 }
Lee Hoonkic1262f22013-01-24 21:59:00 -08008963 }
Hoonki Lee11f7dda2013-02-14 16:55:44 -08008964 vos_mem_copy(peerMac, peer, 6);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008965
Hoonki Lee1090c6a2013-01-16 17:40:54 -08008966#ifdef WLAN_FEATURE_TDLS_DEBUG
8967 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +05308968 "%s: " MAC_ADDRESS_STR " action %d, dialog_token %d status %d, len = %zu",
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07008969 "tdls_mgmt", MAC_ADDR_ARRAY(peer),
8970 action_code, dialog_token, status_code, len);
Hoonki Lee1090c6a2013-01-16 17:40:54 -08008971#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008972
Hoonki Leea34dd892013-02-05 22:56:02 -08008973 /*Except teardown responder will not be used so just make 0*/
8974 responder = 0;
Hoonki Lee11f7dda2013-02-14 16:55:44 -08008975 if (SIR_MAC_TDLS_TEARDOWN == action_code)
Hoonki Leea34dd892013-02-05 22:56:02 -08008976 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -07008977
8978 hddTdlsPeer_t *pTdlsPeer;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308979 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peerMac, TRUE);
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -07008980
8981 if(pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
8982 responder = pTdlsPeer->is_responder;
8983 else
Hoonki Leea34dd892013-02-05 22:56:02 -08008984 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -07008985 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +05308986 "%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 -07008987 __func__, MAC_ADDR_ARRAY(peer), (NULL == pTdlsPeer) ? -1 : pTdlsPeer->link_status,
8988 dialog_token, status_code, len);
8989 return -EPERM;
Hoonki Leea34dd892013-02-05 22:56:02 -08008990 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008991 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008992
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +05308993 /* For explicit trigger of DIS_REQ come out of BMPS for
8994 successfully receiving DIS_RSP from peer. */
Hoonki Lee14621352013-04-16 17:51:19 -07008995 if ((SIR_MAC_TDLS_SETUP_RSP == action_code) ||
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +05308996 (SIR_MAC_TDLS_DIS_RSP == action_code) ||
8997 (SIR_MAC_TDLS_DIS_REQ == action_code))
Hoonki Lee14621352013-04-16 17:51:19 -07008998 {
8999 if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter)))
9000 {
9001 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +05309002 "%s: Sending frame action_code %u.Disable BMPS", __func__, action_code);
Hoonki Lee14621352013-04-16 17:51:19 -07009003 hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
9004 }
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +05309005 if (SIR_MAC_TDLS_DIS_REQ != action_code)
9006 wlan_hdd_tdls_set_cap(pAdapter, peerMac, eTDLS_CAP_SUPPORTED);
Hoonki Lee14621352013-04-16 17:51:19 -07009007 }
9008
Hoonki Lee5305c3a2013-04-29 23:28:59 -07009009 /* make sure doesn't call send_mgmt() while it is pending */
9010 if (TDLS_CTX_MAGIC == pAdapter->mgmtTxCompletionStatus)
9011 {
9012 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009013 "%s: " MAC_ADDRESS_STR " action %d couldn't sent, as one is pending. return EBUSY",
Hoonki Lee5305c3a2013-04-29 23:28:59 -07009014 __func__, MAC_ADDR_ARRAY(peer), action_code);
9015 return -EBUSY;
9016 }
9017
9018 pAdapter->mgmtTxCompletionStatus = TDLS_CTX_MAGIC;
Gopichand Nakkalab977a972013-02-18 19:15:09 -08009019 INIT_COMPLETION(pAdapter->tdls_mgmt_comp);
9020
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009021 status = sme_SendTdlsMgmtFrame(WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
Pradeep Reddy POTTETIca171f82014-03-21 14:17:35 +05309022 peerMac, action_code, dialog_token, status_code, peer_capability, (tANI_U8 *)buf, len, responder);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009023
Gopichand Nakkalab977a972013-02-18 19:15:09 -08009024 if (VOS_STATUS_SUCCESS != status)
9025 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009026 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9027 "%s: sme_SendTdlsMgmtFrame failed!", __func__);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07009028 pAdapter->mgmtTxCompletionStatus = FALSE;
Hoonki Lee14621352013-04-16 17:51:19 -07009029 wlan_hdd_tdls_check_bmps(pAdapter);
Sunil Dutt388ac8f2013-11-28 18:06:52 +05309030 return -EINVAL;
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009031 }
9032
Hoonki Leed37cbb32013-04-20 00:31:14 -07009033 rc = wait_for_completion_interruptible_timeout(&pAdapter->tdls_mgmt_comp,
9034 msecs_to_jiffies(WAIT_TIME_TDLS_MGMT));
9035
9036 if ((rc <= 0) || (TRUE != pAdapter->mgmtTxCompletionStatus))
Gopichand Nakkalab977a972013-02-18 19:15:09 -08009037 {
Hoonki Leed37cbb32013-04-20 00:31:14 -07009038 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07009039 "%s: Mgmt Tx Completion failed status %ld TxCompletion %u",
Hoonki Leed37cbb32013-04-20 00:31:14 -07009040 __func__, rc, pAdapter->mgmtTxCompletionStatus);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07009041 pAdapter->mgmtTxCompletionStatus = FALSE;
Yue Ma4f55ef32014-01-23 16:45:33 -08009042
9043 if (pHddCtx->isLogpInProgress)
9044 {
9045 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9046 "%s: LOGP in Progress. Ignore!!!", __func__);
9047 return -EAGAIN;
9048 }
9049
Hoonki Leed37cbb32013-04-20 00:31:14 -07009050 wlan_hdd_tdls_check_bmps(pAdapter);
Sunil Dutt388ac8f2013-11-28 18:06:52 +05309051 return -EINVAL;
Gopichand Nakkalab977a972013-02-18 19:15:09 -08009052 }
9053
Gopichand Nakkala05922802013-03-14 12:23:19 -07009054 if (max_sta_failed)
Hoonki Lee14621352013-04-16 17:51:19 -07009055 {
9056 wlan_hdd_tdls_check_bmps(pAdapter);
Gopichand Nakkala05922802013-03-14 12:23:19 -07009057 return max_sta_failed;
Hoonki Lee14621352013-04-16 17:51:19 -07009058 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -08009059
Hoonki Leea34dd892013-02-05 22:56:02 -08009060 if (SIR_MAC_TDLS_SETUP_RSP == action_code)
9061 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -08009062 wlan_hdd_tdls_set_responder(pAdapter, peerMac, TRUE);
Hoonki Leea34dd892013-02-05 22:56:02 -08009063 }
9064 else if (SIR_MAC_TDLS_SETUP_CNF == action_code)
9065 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -08009066 wlan_hdd_tdls_set_responder(pAdapter, peerMac, FALSE);
Hoonki Leea34dd892013-02-05 22:56:02 -08009067 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009068
9069 return 0;
9070}
9071
9072static int wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
9073 u8 *peer, enum nl80211_tdls_operation oper)
9074{
9075 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
9076 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309077 int status;
Hoonki Lee5305c3a2013-04-29 23:28:59 -07009078 hddTdlsPeer_t *pTdlsPeer;
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009079
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309080 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
9081 TRACE_CODE_HDD_CFG80211_TDLS_OPER,
9082 pAdapter->sessionId, oper));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309083 if ( NULL == peer )
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009084 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -08009085 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chilam Ngc4244af2013-04-01 15:37:32 -07009086 "%s: Invalid arguments", __func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009087 return -EINVAL;
9088 }
Hoonki Lee1090c6a2013-01-16 17:40:54 -08009089
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309090 status = wlan_hdd_validate_context(pHddCtx);
9091
9092 if (0 != status)
Sameer Thalappil75ea31a2013-02-21 19:38:16 -08009093 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309094 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9095 "%s: HDD context is not valid", __func__);
9096 return status;
Sameer Thalappil75ea31a2013-02-21 19:38:16 -08009097 }
9098
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009099
9100 if( FALSE == pHddCtx->cfg_ini->fEnableTDLSSupport ||
Hoonki Lee1090c6a2013-01-16 17:40:54 -08009101 FALSE == sme_IsFeatureSupportedByFW(TDLS))
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009102 {
Hoonki Lee1090c6a2013-01-16 17:40:54 -08009103 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chilam Ngc4244af2013-04-01 15:37:32 -07009104 "TDLS Disabled in INI OR not enabled in FW. "
9105 "Cannot process TDLS commands");
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009106 return -ENOTSUPP;
9107 }
9108
9109 switch (oper) {
9110 case NL80211_TDLS_ENABLE_LINK:
9111 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009112 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309113 long ret;
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05309114 tCsrTdlsLinkEstablishParams tdlsLinkEstablishParams;
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009115
Sunil Dutt41de4e22013-11-14 18:09:02 +05309116 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
9117
9118 if ( NULL == pTdlsPeer ) {
9119 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
9120 " (oper %d) not exsting. ignored",
9121 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
9122 return -EINVAL;
9123 }
9124
9125 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9126 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
9127 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
9128 "NL80211_TDLS_ENABLE_LINK");
9129
Gopichand Nakkala2f4a2822013-04-17 11:22:01 -07009130 if (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
9131 {
9132 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Staion Index %u "
9133 MAC_ADDRESS_STR " failed",
9134 __func__, pTdlsPeer->staId, MAC_ADDR_ARRAY(peer));
9135 return -EINVAL;
9136 }
9137
Hoonki Lee5305c3a2013-04-29 23:28:59 -07009138 if (eTDLS_LINK_CONNECTED != pTdlsPeer->link_status)
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07009139 {
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +05309140 if (IS_ADVANCE_TDLS_ENABLE) {
Gopichand Nakkala24be5312013-07-02 16:47:12 +05309141
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +05309142 if (0 != wlan_hdd_tdls_get_link_establish_params(
9143 pAdapter, peer,&tdlsLinkEstablishParams)) {
9144 return -EINVAL;
9145 }
9146 INIT_COMPLETION(pAdapter->tdls_link_establish_req_comp);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05309147
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +05309148 sme_SendTdlsLinkEstablishParams(WLAN_HDD_GET_HAL_CTX(pAdapter),
9149 pAdapter->sessionId, peer, &tdlsLinkEstablishParams);
9150 /* Send TDLS peer UAPSD capabilities to the firmware and
9151 * register with the TL on after the response for this operation
9152 * is received .
9153 */
9154 ret = wait_for_completion_interruptible_timeout(
9155 &pAdapter->tdls_link_establish_req_comp,
9156 msecs_to_jiffies(WAIT_TIME_TDLS_LINK_ESTABLISH_REQ));
9157 if (ret <= 0)
9158 {
9159 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9160 "%s: Link Establish Request Faled Status %ld",
9161 __func__, ret);
9162 return -EINVAL;
9163 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05309164 }
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -07009165 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer, eTDLS_LINK_CONNECTED);
Gopichand Nakkala471708b2013-06-04 20:03:01 +05309166 /* Mark TDLS client Authenticated .*/
9167 status = WLANTL_ChangeSTAState( pHddCtx->pvosContext,
9168 pTdlsPeer->staId,
9169 WLANTL_STA_AUTHENTICATED);
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -07009170 if (VOS_STATUS_SUCCESS == status)
9171 {
Hoonki Lee14621352013-04-16 17:51:19 -07009172 if (pTdlsPeer->is_responder == 0)
9173 {
9174 v_U8_t staId = (v_U8_t)pTdlsPeer->staId;
9175
9176 wlan_hdd_tdls_timer_restart(pAdapter,
9177 &pTdlsPeer->initiatorWaitTimeoutTimer,
9178 WAIT_TIME_TDLS_INITIATOR);
9179 /* suspend initiator TX until it receives direct packet from the
9180 reponder or WAIT_TIME_TDLS_INITIATOR timer expires */
9181 WLANTL_SuspendDataTx( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
9182 &staId, NULL);
9183 }
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -07009184 wlan_hdd_tdls_increment_peer_count(pAdapter);
9185 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07009186 wlan_hdd_tdls_check_bmps(pAdapter);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05309187
9188 /* Update TL about the UAPSD masks , to route the packets to firmware */
Gopichand Nakkala574f6d12013-06-27 19:38:43 +05309189 if ((TRUE == pHddCtx->cfg_ini->fEnableTDLSBufferSta)
9190 || pHddCtx->cfg_ini->fTDLSUapsdMask )
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05309191 {
Gopichand Nakkala574f6d12013-06-27 19:38:43 +05309192 int ac;
9193 uint8 ucAc[4] = { WLANTL_AC_VO,
9194 WLANTL_AC_VI,
9195 WLANTL_AC_BK,
9196 WLANTL_AC_BE };
9197 uint8 tlTid[4] = { 7, 5, 2, 3 } ;
9198 for(ac=0; ac < 4; ac++)
9199 {
9200 status = WLANTL_EnableUAPSDForAC( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
9201 pTdlsPeer->staId, ucAc[ac],
9202 tlTid[ac], tlTid[ac], 0, 0,
9203 WLANTL_BI_DIR );
9204 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05309205 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07009206 }
9207
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009208 }
9209 break;
9210 case NL80211_TDLS_DISABLE_LINK:
Lee Hoonkic1262f22013-01-24 21:59:00 -08009211 {
Sunil Dutt41de4e22013-11-14 18:09:02 +05309212 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
9213
9214 if ( NULL == pTdlsPeer ) {
9215 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
9216 " (oper %d) not exsting. ignored",
9217 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
9218 return -EINVAL;
9219 }
9220
9221 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9222 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
9223 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
9224 "NL80211_TDLS_DISABLE_LINK");
9225
Hoonki Lee5305c3a2013-04-29 23:28:59 -07009226 if(TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
Lee Hoonkic1262f22013-01-24 21:59:00 -08009227 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009228 long status;
9229
9230 INIT_COMPLETION(pAdapter->tdls_del_station_comp);
9231
Lee Hoonkic1262f22013-01-24 21:59:00 -08009232 sme_DeleteTdlsPeerSta( WLAN_HDD_GET_HAL_CTX(pAdapter),
9233 pAdapter->sessionId, peer );
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009234
9235 status = wait_for_completion_interruptible_timeout(&pAdapter->tdls_del_station_comp,
9236 msecs_to_jiffies(WAIT_TIME_TDLS_DEL_STA));
9237 if (status <= 0)
9238 {
Hoonki Lee5305c3a2013-04-29 23:28:59 -07009239 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer, eTDLS_LINK_IDLE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009240 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9241 "%s: Del station failed status %ld",
9242 __func__, status);
9243 return -EPERM;
9244 }
Hoonki Lee5305c3a2013-04-29 23:28:59 -07009245 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer, eTDLS_LINK_IDLE);
Lee Hoonkic1262f22013-01-24 21:59:00 -08009246 }
9247 else
9248 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07009249 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9250 "%s: TDLS Peer Station doesn't exist.", __func__);
Lee Hoonkic1262f22013-01-24 21:59:00 -08009251 }
Lee Hoonkic1262f22013-01-24 21:59:00 -08009252 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07009253 break;
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009254 case NL80211_TDLS_TEARDOWN:
Sunil Dutt41de4e22013-11-14 18:09:02 +05309255 {
9256 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9257 " %s : NL80211_TDLS_TEARDOWN for " MAC_ADDRESS_STR,
9258 __func__, MAC_ADDR_ARRAY(peer));
9259
9260 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
9261 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
9262
9263 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9264 " %s TDLS External control and Implicit Trigger not enabled ",
9265 __func__);
9266 return -ENOTSUPP;
9267 }
9268
Sunil Dutt41de4e22013-11-14 18:09:02 +05309269
9270 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
9271
9272 if ( NULL == pTdlsPeer ) {
9273 hddLog(VOS_TRACE_LEVEL_INFO, "%s: " MAC_ADDRESS_STR
9274 " peer not exsting",
9275 __func__, MAC_ADDR_ARRAY(peer));
Naresh Jayaram937abdf2013-11-26 19:50:25 +05309276 return -EINVAL;
Sunil Dutt41de4e22013-11-14 18:09:02 +05309277 }
9278 else {
9279 wlan_hdd_tdls_indicate_teardown(pAdapter, pTdlsPeer,
9280 eSIR_MAC_TDLS_TEARDOWN_UNSPEC_REASON);
9281 }
Naresh Jayaram937abdf2013-11-26 19:50:25 +05309282
9283 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, FALSE) )
9284 return -EINVAL;
Sunil Dutt41de4e22013-11-14 18:09:02 +05309285 break;
9286 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009287 case NL80211_TDLS_SETUP:
Sunil Dutt41de4e22013-11-14 18:09:02 +05309288 {
Naresh Jayaramdb4514b2013-11-25 18:08:10 +05309289 hddTdlsPeer_t *pTdlsPeer;
Sunil Dutt41de4e22013-11-14 18:09:02 +05309290 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9291 " %s : NL80211_TDLS_SETUP for " MAC_ADDRESS_STR,
9292 __func__, MAC_ADDR_ARRAY(peer));
9293
9294 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
9295 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
9296
9297 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9298 " %s TDLS External control and Implicit Trigger not enabled ",
9299 __func__);
9300 return -ENOTSUPP;
9301 }
9302
Naresh Jayaramdb4514b2013-11-25 18:08:10 +05309303 /* To cater the requirement of establishing the TDLS link
9304 * irrespective of the data traffic , get an entry of TDLS peer.
9305 */
9306 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, peer);
9307 if (pTdlsPeer == NULL) {
9308 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9309 "%s: peer " MAC_ADDRESS_STR " not existing",
9310 __func__, MAC_ADDR_ARRAY(peer));
9311 return -EINVAL;
9312 }
Naresh Jayaram937abdf2013-11-26 19:50:25 +05309313
9314 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, TRUE) ) {
9315
9316 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9317 " %s TDLS Add Force Peer Failed",
9318 __func__);
9319 return -EINVAL;
9320 }
Naresh Jayaramdb4514b2013-11-25 18:08:10 +05309321 break;
Sunil Dutt41de4e22013-11-14 18:09:02 +05309322 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009323 case NL80211_TDLS_DISCOVERY_REQ:
9324 /* We don't support in-driver setup/teardown/discovery */
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309325 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
9326 "%s: We don't support in-driver setup/teardown/discovery "
9327 ,__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009328 return -ENOTSUPP;
9329 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309330 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9331 "%s: unsupported event",__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009332 return -ENOTSUPP;
9333 }
9334 return 0;
9335}
Chilam NG571c65a2013-01-19 12:27:36 +05309336
9337int wlan_hdd_cfg80211_send_tdls_discover_req(struct wiphy *wiphy,
9338 struct net_device *dev, u8 *peer)
9339{
Arif Hussaina7c8e412013-11-20 11:06:42 -08009340 hddLog(VOS_TRACE_LEVEL_INFO,
9341 "tdls send discover req: "MAC_ADDRESS_STR,
9342 MAC_ADDR_ARRAY(peer));
Chilam NG571c65a2013-01-19 12:27:36 +05309343
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +05309344#if TDLS_MGMT_VERSION2
9345 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
9346 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
9347#else
Chilam NG571c65a2013-01-19 12:27:36 +05309348 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
9349 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, NULL, 0);
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +05309350#endif
Chilam NG571c65a2013-01-19 12:27:36 +05309351}
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009352#endif
9353
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309354#ifdef WLAN_FEATURE_GTK_OFFLOAD
9355/*
9356 * FUNCTION: wlan_hdd_cfg80211_update_replayCounterCallback
9357 * Callback rountine called upon receiving response for
9358 * get offload info
9359 */
9360void wlan_hdd_cfg80211_update_replayCounterCallback(void *callbackContext,
9361 tpSirGtkOffloadGetInfoRspParams pGtkOffloadGetInfoRsp)
9362{
9363
9364 hdd_adapter_t *pAdapter = (hdd_adapter_t *)callbackContext;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05309365 tANI_U8 tempReplayCounter[8];
9366 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309367
9368 ENTER();
9369
9370 if (NULL == pAdapter)
9371 {
Agarwal Ashish971c2882013-10-30 20:11:12 +05309372 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309373 "%s: HDD adapter is Null", __func__);
9374 return ;
9375 }
9376
9377 if (NULL == pGtkOffloadGetInfoRsp)
9378 {
9379 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9380 "%s: pGtkOffloadGetInfoRsp is Null", __func__);
9381 return ;
9382 }
9383
9384 if (VOS_STATUS_SUCCESS != pGtkOffloadGetInfoRsp->ulStatus)
9385 {
9386 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9387 "%s: wlan Failed to get replay counter value",
9388 __func__);
9389 return ;
9390 }
9391
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05309392 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9393 /* Update replay counter */
9394 pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter =
9395 pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
9396
9397 {
9398 /* changing from little to big endian since supplicant
9399 * works on big endian format
9400 */
9401 int i;
9402 tANI_U8 *p = (tANI_U8 *)&pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
9403
9404 for (i = 0; i < 8; i++)
9405 {
9406 tempReplayCounter[7-i] = (tANI_U8)p[i];
9407 }
9408 }
9409
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309410 /* Update replay counter to NL */
9411 cfg80211_gtk_rekey_notify(pAdapter->dev, pGtkOffloadGetInfoRsp->bssId,
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05309412 tempReplayCounter, GFP_KERNEL);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309413}
9414
9415/*
9416 * FUNCTION: wlan_hdd_cfg80211_set_rekey_data
9417 * This function is used to offload GTK rekeying job to the firmware.
9418 */
9419int wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
9420 struct cfg80211_gtk_rekey_data *data)
9421{
9422 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
9423 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
9424 hdd_station_ctx_t *pHddStaCtx;
9425 tHalHandle hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309426 int result;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05309427 tSirGtkOffloadParams hddGtkOffloadReqParams;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309428 eHalStatus status = eHAL_STATUS_FAILURE;
9429
9430 ENTER();
9431
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309432
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309433 if (NULL == pAdapter)
9434 {
9435 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
9436 "%s: HDD adapter is Null", __func__);
9437 return -ENODEV;
9438 }
9439
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309440 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
9441 TRACE_CODE_HDD_CFG80211_SET_REKEY_DATA,
9442 pAdapter->sessionId, pAdapter->device_mode));
9443
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309444 result = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309445
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309446 if (0 != result)
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309447 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309448 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9449 "%s: HDD context is not valid", __func__);
9450 return result;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309451 }
9452
9453 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9454 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
9455 if (NULL == hHal)
9456 {
9457 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9458 "%s: HAL context is Null!!!", __func__);
9459 return -EAGAIN;
9460 }
9461
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05309462 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_ENABLE;
9463 memcpy(pHddStaCtx->gtkOffloadReqParams.aKCK, data->kck, NL80211_KCK_LEN);
9464 memcpy(pHddStaCtx->gtkOffloadReqParams.aKEK, data->kek, NL80211_KEK_LEN);
9465 memcpy(pHddStaCtx->gtkOffloadReqParams.bssId, &pHddStaCtx->conn_info.bssId,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309466 WNI_CFG_BSSID_LEN);
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05309467 {
9468 /* changing from big to little endian since driver
9469 * works on little endian format
9470 */
9471 tANI_U8 *p =
9472 (tANI_U8 *)&pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter;
9473 int i;
9474
9475 for (i = 0; i < 8; i++)
9476 {
9477 p[7-i] = data->replay_ctr[i];
9478 }
9479 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309480
9481 if (TRUE == pHddCtx->hdd_wlan_suspended)
9482 {
9483 /* if wlan is suspended, enable GTK offload directly from here */
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05309484 memcpy(&hddGtkOffloadReqParams, &pHddStaCtx->gtkOffloadReqParams,
9485 sizeof (tSirGtkOffloadParams));
9486 status = sme_SetGTKOffload(hHal, &hddGtkOffloadReqParams,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309487 pAdapter->sessionId);
9488
9489 if (eHAL_STATUS_SUCCESS != status)
9490 {
9491 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9492 "%s: sme_SetGTKOffload failed, returned %d",
9493 __func__, status);
9494 return status;
9495 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309496 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9497 "%s: sme_SetGTKOffload successfull", __func__);
9498 }
9499 else
9500 {
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309501 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9502 "%s: wlan not suspended GTKOffload request is stored",
9503 __func__);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309504 }
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05309505
9506 return eHAL_STATUS_SUCCESS;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309507}
9508#endif /*WLAN_FEATURE_GTK_OFFLOAD*/
9509
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05309510/*
9511 * FUNCTION: wlan_hdd_cfg80211_set_mac_acl
9512 * This function is used to set access control policy
9513 */
9514static int wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy,
9515 struct net_device *dev, const struct cfg80211_acl_data *params)
9516{
9517 int i;
9518 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
9519 hdd_hostapd_state_t *pHostapdState;
9520 tsap_Config_t *pConfig;
9521 v_CONTEXT_t pVosContext = NULL;
9522 hdd_context_t *pHddCtx;
9523 int status;
9524
9525 ENTER();
9526
9527 if (NULL == pAdapter)
9528 {
9529 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
9530 "%s: HDD adapter is Null", __func__);
9531 return -ENODEV;
9532 }
9533
9534 if (NULL == params)
9535 {
9536 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
9537 "%s: params is Null", __func__);
9538 return -EINVAL;
9539 }
9540
9541 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9542 status = wlan_hdd_validate_context(pHddCtx);
9543
9544 if (0 != status)
9545 {
9546 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9547 "%s: HDD context is not valid", __func__);
9548 return status;
9549 }
9550
9551 pVosContext = pHddCtx->pvosContext;
9552 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
9553
9554 if (NULL == pHostapdState)
9555 {
9556 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
9557 "%s: pHostapdState is Null", __func__);
9558 return -EINVAL;
9559 }
9560
9561 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"acl policy: = %d"
9562 "no acl entries = %d", params->acl_policy, params->n_acl_entries);
9563
9564 if (WLAN_HDD_SOFTAP == pAdapter->device_mode)
9565 {
9566 pConfig = &pAdapter->sessionCtx.ap.sapConfig;
9567
9568 /* default value */
9569 pConfig->num_accept_mac = 0;
9570 pConfig->num_deny_mac = 0;
9571
9572 /**
9573 * access control policy
9574 * @NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED: Deny stations which are
9575 * listed in hostapd.deny file.
9576 * @NL80211_ACL_POLICY_DENY_UNLESS_LISTED: Allow stations which are
9577 * listed in hostapd.accept file.
9578 */
9579 if (NL80211_ACL_POLICY_DENY_UNLESS_LISTED == params->acl_policy)
9580 {
9581 pConfig->SapMacaddr_acl = eSAP_DENY_UNLESS_ACCEPTED;
9582 }
9583 else if (NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED == params->acl_policy)
9584 {
9585 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
9586 }
9587 else
9588 {
9589 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9590 "%s:Acl Policy : %d is not supported",
9591 __func__, params->acl_policy);
9592 return -ENOTSUPP;
9593 }
9594
9595 if (eSAP_DENY_UNLESS_ACCEPTED == pConfig->SapMacaddr_acl)
9596 {
9597 pConfig->num_accept_mac = params->n_acl_entries;
9598 for (i = 0; i < params->n_acl_entries; i++)
9599 {
9600 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9601 "** Add ACL MAC entry %i in WhiletList :"
9602 MAC_ADDRESS_STR, i,
9603 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
9604
9605 vos_mem_copy(&pConfig->accept_mac[i], params->mac_addrs[i].addr,
9606 sizeof(qcmacaddr));
9607 }
9608 }
9609 else if (eSAP_ACCEPT_UNLESS_DENIED == pConfig->SapMacaddr_acl)
9610 {
9611 pConfig->num_deny_mac = params->n_acl_entries;
9612 for (i = 0; i < params->n_acl_entries; i++)
9613 {
9614 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9615 "** Add ACL MAC entry %i in BlackList :"
9616 MAC_ADDRESS_STR, i,
9617 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
9618
9619 vos_mem_copy(&pConfig->deny_mac[i], params->mac_addrs[i].addr,
9620 sizeof(qcmacaddr));
9621 }
9622 }
9623
9624 if (VOS_STATUS_SUCCESS != WLANSAP_SetMacACL(pVosContext, pConfig))
9625 {
9626 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9627 "%s: SAP Set Mac Acl fail", __func__);
9628 return -EINVAL;
9629 }
9630 }
9631 else
9632 {
9633 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309634 "%s: Invalid device_mode = %s (%d)",
9635 __func__, hdd_device_modetoString(pAdapter->device_mode),
9636 pAdapter->device_mode);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05309637 return -EINVAL;
9638 }
9639
9640 return 0;
9641}
9642
Leo Chang9056f462013-08-01 19:21:11 -07009643#ifdef WLAN_NL80211_TESTMODE
9644#ifdef FEATURE_WLAN_LPHB
Leo Changd9df8aa2013-09-26 13:32:26 -07009645void wlan_hdd_cfg80211_lphb_ind_handler
Leo Chang9056f462013-08-01 19:21:11 -07009646(
9647 void *pAdapter,
9648 void *indCont
9649)
9650{
Leo Changd9df8aa2013-09-26 13:32:26 -07009651 tSirLPHBInd *lphbInd;
9652 struct sk_buff *skb;
c_hpothu73f35e62014-04-18 13:40:08 +05309653 hdd_context_t *pHddCtxt;
Leo Chang9056f462013-08-01 19:21:11 -07009654
9655 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -07009656 "LPHB indication arrived");
Leo Chang9056f462013-08-01 19:21:11 -07009657
c_hpothu73f35e62014-04-18 13:40:08 +05309658 if (pAdapter == NULL)
9659 {
9660 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9661 "%s: pAdapter is NULL\n",__func__);
9662 return;
9663 }
9664
Leo Chang9056f462013-08-01 19:21:11 -07009665 if (NULL == indCont)
9666 {
9667 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -07009668 "LPHB IND, invalid argument");
Leo Chang9056f462013-08-01 19:21:11 -07009669 return;
9670 }
9671
c_hpothu73f35e62014-04-18 13:40:08 +05309672 pHddCtxt = (hdd_context_t *)pAdapter;
Leo Changd9df8aa2013-09-26 13:32:26 -07009673 lphbInd = (tSirLPHBInd *)indCont;
Leo Chang9056f462013-08-01 19:21:11 -07009674 skb = cfg80211_testmode_alloc_event_skb(
c_hpothu73f35e62014-04-18 13:40:08 +05309675 pHddCtxt->wiphy,
Leo Changd9df8aa2013-09-26 13:32:26 -07009676 sizeof(tSirLPHBInd),
Leo Chang9056f462013-08-01 19:21:11 -07009677 GFP_ATOMIC);
9678 if (!skb)
9679 {
9680 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9681 "LPHB timeout, NL buffer alloc fail");
9682 return;
9683 }
9684
Leo Changac3ba772013-10-07 09:47:04 -07009685 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_CMD, WLAN_HDD_TM_CMD_WLAN_HB))
Leo Changd9df8aa2013-09-26 13:32:26 -07009686 {
9687 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9688 "WLAN_HDD_TM_ATTR_CMD put fail");
9689 goto nla_put_failure;
9690 }
Leo Changac3ba772013-10-07 09:47:04 -07009691 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_TYPE, lphbInd->protocolType))
Leo Changd9df8aa2013-09-26 13:32:26 -07009692 {
9693 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9694 "WLAN_HDD_TM_ATTR_TYPE put fail");
9695 goto nla_put_failure;
9696 }
Leo Changac3ba772013-10-07 09:47:04 -07009697 if(nla_put(skb, WLAN_HDD_TM_ATTR_DATA,
Leo Changd9df8aa2013-09-26 13:32:26 -07009698 sizeof(tSirLPHBInd), lphbInd))
9699 {
9700 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9701 "WLAN_HDD_TM_ATTR_DATA put fail");
9702 goto nla_put_failure;
9703 }
Leo Chang9056f462013-08-01 19:21:11 -07009704 cfg80211_testmode_event(skb, GFP_ATOMIC);
9705 return;
9706
9707nla_put_failure:
9708 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9709 "NLA Put fail");
9710 kfree_skb(skb);
9711
9712 return;
9713}
9714#endif /* FEATURE_WLAN_LPHB */
9715
9716static int wlan_hdd_cfg80211_testmode(struct wiphy *wiphy, void *data, int len)
9717{
9718 struct nlattr *tb[WLAN_HDD_TM_ATTR_MAX + 1];
9719 int err = 0;
9720#ifdef FEATURE_WLAN_LPHB
9721 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Leo Changd9df8aa2013-09-26 13:32:26 -07009722 eHalStatus smeStatus;
Leo Chang9056f462013-08-01 19:21:11 -07009723#endif /* FEATURE_WLAN_LPHB */
9724
9725 err = nla_parse(tb, WLAN_HDD_TM_ATTR_MAX, data, len, wlan_hdd_tm_policy);
9726 if (err)
9727 {
9728 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9729 "%s Testmode INV ATTR", __func__);
9730 return err;
9731 }
9732
9733 if (!tb[WLAN_HDD_TM_ATTR_CMD])
9734 {
9735 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9736 "%s Testmode INV CMD", __func__);
9737 return -EINVAL;
9738 }
9739
9740 switch (nla_get_u32(tb[WLAN_HDD_TM_ATTR_CMD]))
9741 {
9742#ifdef FEATURE_WLAN_LPHB
9743 /* Low Power Heartbeat configuration request */
9744 case WLAN_HDD_TM_CMD_WLAN_HB:
9745 {
9746 int buf_len;
9747 void *buf;
9748 tSirLPHBReq *hb_params = NULL;
Amar Singhal05852702014-02-04 14:40:00 -08009749 tSirLPHBReq *hb_params_temp = NULL;
Leo Chang9056f462013-08-01 19:21:11 -07009750
9751 if (!tb[WLAN_HDD_TM_ATTR_DATA])
9752 {
9753 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9754 "%s Testmode INV DATA", __func__);
9755 return -EINVAL;
9756 }
9757
9758 buf = nla_data(tb[WLAN_HDD_TM_ATTR_DATA]);
9759 buf_len = nla_len(tb[WLAN_HDD_TM_ATTR_DATA]);
Amar Singhal05852702014-02-04 14:40:00 -08009760
9761 hb_params_temp =(tSirLPHBReq *)buf;
9762 if ((hb_params_temp->cmd == LPHB_SET_TCP_PARAMS_INDID) &&
9763 (hb_params_temp->params.lphbTcpParamReq.timePeriodSec == 0))
9764 return -EINVAL;
9765
Leo Chang9056f462013-08-01 19:21:11 -07009766 hb_params = (tSirLPHBReq *)vos_mem_malloc(sizeof(tSirLPHBReq));
9767 if (NULL == hb_params)
9768 {
9769 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9770 "%s Request Buffer Alloc Fail", __func__);
9771 return -EINVAL;
9772 }
9773
9774 vos_mem_copy(hb_params, buf, buf_len);
Leo Changd9df8aa2013-09-26 13:32:26 -07009775 smeStatus = sme_LPHBConfigReq((tHalHandle)(pHddCtx->hHal),
9776 hb_params,
9777 wlan_hdd_cfg80211_lphb_ind_handler);
9778 if (eHAL_STATUS_SUCCESS != smeStatus)
Leo Chang9056f462013-08-01 19:21:11 -07009779 {
Leo Changd9df8aa2013-09-26 13:32:26 -07009780 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9781 "LPHB Config Fail, disable");
Leo Chang9056f462013-08-01 19:21:11 -07009782 vos_mem_free(hb_params);
9783 }
Leo Chang9056f462013-08-01 19:21:11 -07009784 return 0;
9785 }
9786#endif /* FEATURE_WLAN_LPHB */
9787 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309788 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9789 "%s: unsupported event",__func__);
Leo Chang9056f462013-08-01 19:21:11 -07009790 return -EOPNOTSUPP;
9791 }
9792
9793 return err;
9794}
9795#endif /* CONFIG_NL80211_TESTMODE */
9796
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +05309797static int wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
9798 struct net_device *dev,
9799 int idx, struct survey_info *survey)
9800{
9801 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
9802 hdd_context_t *pHddCtx;
Mihir Sheted9072e02013-08-21 17:02:29 +05309803 hdd_station_ctx_t *pHddStaCtx;
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +05309804 tHalHandle halHandle;
Mihir Sheted9072e02013-08-21 17:02:29 +05309805 v_U32_t channel = 0, freq = 0; /* Initialization Required */
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +05309806 v_S7_t snr,rssi;
9807 int status, i, j, filled = 0;
9808
9809 ENTER();
9810
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +05309811 if (NULL == pAdapter)
9812 {
9813 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
9814 "%s: HDD adapter is Null", __func__);
9815 return -ENODEV;
9816 }
9817
9818 if (NULL == wiphy)
9819 {
9820 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
9821 "%s: wiphy is Null", __func__);
9822 return -ENODEV;
9823 }
9824
9825 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9826 status = wlan_hdd_validate_context(pHddCtx);
9827
9828 if (0 != status)
9829 {
9830 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9831 "%s: HDD context is not valid", __func__);
9832 return status;
9833 }
9834
Mihir Sheted9072e02013-08-21 17:02:29 +05309835 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9836
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +05309837 if (0 == pHddCtx->cfg_ini->fEnableSNRMonitoring ||
Mihir Sheted9072e02013-08-21 17:02:29 +05309838 0 != pAdapter->survey_idx ||
9839 eConnectionState_Associated != pHddStaCtx->conn_info.connState)
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +05309840 {
9841 /* The survey dump ops when implemented completely is expected to
9842 * return a survey of all channels and the ops is called by the
9843 * kernel with incremental values of the argument 'idx' till it
9844 * returns -ENONET. But we can only support the survey for the
9845 * operating channel for now. survey_idx is used to track
9846 * that the ops is called only once and then return -ENONET for
9847 * the next iteration
9848 */
9849 pAdapter->survey_idx = 0;
9850 return -ENONET;
9851 }
9852
9853 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
9854
9855 wlan_hdd_get_snr(pAdapter, &snr);
9856 wlan_hdd_get_rssi(pAdapter, &rssi);
9857
9858 sme_GetOperationChannel(halHandle, &channel, pAdapter->sessionId);
9859 hdd_wlan_get_freq(channel, &freq);
9860
9861
9862 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
9863 {
9864 if (NULL == wiphy->bands[i])
9865 {
9866 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
9867 "%s: wiphy->bands[i] is NULL, i = %d", __func__, i);
9868 continue;
9869 }
9870
9871 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
9872 {
9873 struct ieee80211_supported_band *band = wiphy->bands[i];
9874
9875 if (band->channels[j].center_freq == (v_U16_t)freq)
9876 {
9877 survey->channel = &band->channels[j];
9878 /* The Rx BDs contain SNR values in dB for the received frames
9879 * while the supplicant expects noise. So we calculate and
9880 * return the value of noise (dBm)
9881 * SNR (dB) = RSSI (dBm) - NOISE (dBm)
9882 */
9883 survey->noise = rssi - snr;
9884 survey->filled = SURVEY_INFO_NOISE_DBM;
9885 filled = 1;
9886 }
9887 }
9888 }
9889
9890 if (filled)
9891 pAdapter->survey_idx = 1;
9892 else
9893 {
9894 pAdapter->survey_idx = 0;
9895 return -ENONET;
9896 }
9897
9898 return 0;
9899}
9900
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05309901/*
9902 * FUNCTION: wlan_hdd_cfg80211_resume_wlan
9903 * this is called when cfg80211 driver resume
9904 * driver updates latest sched_scan scan result(if any) to cfg80211 database
9905 */
9906int wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
9907{
9908 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
9909 hdd_adapter_t *pAdapter;
9910 hdd_adapter_list_node_t *pAdapterNode, *pNext;
9911 VOS_STATUS status = VOS_STATUS_SUCCESS;
9912
9913 ENTER();
9914
9915 if ( NULL == pHddCtx )
9916 {
9917 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
9918 "%s: HddCtx validation failed", __func__);
9919 return 0;
9920 }
9921
9922 if (pHddCtx->isLogpInProgress)
9923 {
9924 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9925 "%s: LOGP in Progress. Ignore!!!", __func__);
9926 return 0;
9927 }
9928
Mihir Shete18156292014-03-11 15:38:30 +05309929 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05309930 {
9931 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9932 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
9933 return 0;
9934 }
9935
9936 spin_lock(&pHddCtx->schedScan_lock);
9937 pHddCtx->isWiphySuspended = FALSE;
9938 if (TRUE != pHddCtx->isSchedScanUpdatePending)
9939 {
9940 spin_unlock(&pHddCtx->schedScan_lock);
9941 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9942 "%s: Return resume is not due to PNO indication", __func__);
9943 return 0;
9944 }
9945 // Reset flag to avoid updatating cfg80211 data old results again
9946 pHddCtx->isSchedScanUpdatePending = FALSE;
9947 spin_unlock(&pHddCtx->schedScan_lock);
9948
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +05309949
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05309950 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
9951
9952 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
9953 {
9954 pAdapter = pAdapterNode->pAdapter;
9955 if ( (NULL != pAdapter) &&
9956 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) )
9957 {
9958 if (0 != wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter))
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +05309959 {
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05309960 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
9961 "%s: NO SCAN result", __func__);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +05309962 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05309963 else
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +05309964 {
9965 /* Acquire wakelock to handle the case where APP's tries to
9966 * suspend immediately after updating the scan results. Whis
9967 * results in app's is in suspended state and not able to
9968 * process the connect request to AP
9969 */
9970 hdd_prevent_suspend_timeout(2000);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05309971 cfg80211_sched_scan_results(pHddCtx->wiphy);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +05309972 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05309973
9974 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9975 "%s : cfg80211 scan result database updated", __func__);
9976
9977 return 0;
9978
9979 }
9980 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
9981 pAdapterNode = pNext;
9982 }
9983
9984 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9985 "%s: Failed to find Adapter", __func__);
9986 return 0;
9987}
9988
9989/*
9990 * FUNCTION: wlan_hdd_cfg80211_suspend_wlan
9991 * this is called when cfg80211 driver suspends
9992 */
9993int wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
9994 struct cfg80211_wowlan *wow)
9995{
9996 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
9997
9998 ENTER();
9999 if (NULL == pHddCtx)
10000 {
10001 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
10002 "%s: HddCtx validation failed", __func__);
10003 return 0;
10004 }
10005
10006 pHddCtx->isWiphySuspended = TRUE;
10007
10008 EXIT();
10009
10010 return 0;
10011}
10012
Jeff Johnson295189b2012-06-20 16:38:30 -070010013/* cfg80211_ops */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010014static struct cfg80211_ops wlan_hdd_cfg80211_ops =
Jeff Johnson295189b2012-06-20 16:38:30 -070010015{
10016 .add_virtual_intf = wlan_hdd_add_virtual_intf,
10017 .del_virtual_intf = wlan_hdd_del_virtual_intf,
10018 .change_virtual_intf = wlan_hdd_cfg80211_change_iface,
10019 .change_station = wlan_hdd_change_station,
10020#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
10021 .add_beacon = wlan_hdd_cfg80211_add_beacon,
10022 .del_beacon = wlan_hdd_cfg80211_del_beacon,
10023 .set_beacon = wlan_hdd_cfg80211_set_beacon,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010024#else
10025 .start_ap = wlan_hdd_cfg80211_start_ap,
10026 .change_beacon = wlan_hdd_cfg80211_change_beacon,
10027 .stop_ap = wlan_hdd_cfg80211_stop_ap,
Jeff Johnson295189b2012-06-20 16:38:30 -070010028#endif
10029 .change_bss = wlan_hdd_cfg80211_change_bss,
10030 .add_key = wlan_hdd_cfg80211_add_key,
10031 .get_key = wlan_hdd_cfg80211_get_key,
10032 .del_key = wlan_hdd_cfg80211_del_key,
10033 .set_default_key = wlan_hdd_cfg80211_set_default_key,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080010034#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
Jeff Johnson295189b2012-06-20 16:38:30 -070010035 .set_channel = wlan_hdd_cfg80211_set_channel,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080010036#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010037 .scan = wlan_hdd_cfg80211_scan,
10038 .connect = wlan_hdd_cfg80211_connect,
10039 .disconnect = wlan_hdd_cfg80211_disconnect,
10040 .join_ibss = wlan_hdd_cfg80211_join_ibss,
10041 .leave_ibss = wlan_hdd_cfg80211_leave_ibss,
10042 .set_wiphy_params = wlan_hdd_cfg80211_set_wiphy_params,
10043 .set_tx_power = wlan_hdd_cfg80211_set_txpower,
10044 .get_tx_power = wlan_hdd_cfg80211_get_txpower,
Jeff Johnson295189b2012-06-20 16:38:30 -070010045 .remain_on_channel = wlan_hdd_cfg80211_remain_on_channel,
10046 .cancel_remain_on_channel = wlan_hdd_cfg80211_cancel_remain_on_channel,
DARAM SUDHA39eede62014-02-12 11:16:40 +053010047 .mgmt_tx = wlan_hdd_mgmt_tx,
Jeff Johnson295189b2012-06-20 16:38:30 -070010048#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
10049 .mgmt_tx_cancel_wait = wlan_hdd_cfg80211_mgmt_tx_cancel_wait,
10050 .set_default_mgmt_key = wlan_hdd_set_default_mgmt_key,
10051 .set_txq_params = wlan_hdd_set_txq_params,
10052#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010053 .get_station = wlan_hdd_cfg80211_get_station,
10054 .set_power_mgmt = wlan_hdd_cfg80211_set_power_mgmt,
10055 .del_station = wlan_hdd_cfg80211_del_station,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010056 .add_station = wlan_hdd_cfg80211_add_station,
10057#ifdef FEATURE_WLAN_LFR
10058 .set_pmksa = wlan_hdd_cfg80211_set_pmksa,
10059 .del_pmksa = wlan_hdd_cfg80211_del_pmksa,
10060 .flush_pmksa = wlan_hdd_cfg80211_flush_pmksa,
10061#endif
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070010062#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
10063 .update_ft_ies = wlan_hdd_cfg80211_update_ft_ies,
10064#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080010065#ifdef FEATURE_WLAN_TDLS
10066 .tdls_mgmt = wlan_hdd_cfg80211_tdls_mgmt,
10067 .tdls_oper = wlan_hdd_cfg80211_tdls_oper,
10068#endif
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053010069#ifdef WLAN_FEATURE_GTK_OFFLOAD
10070 .set_rekey_data = wlan_hdd_cfg80211_set_rekey_data,
10071#endif /* WLAN_FEATURE_GTK_OFFLOAD */
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053010072#ifdef FEATURE_WLAN_SCAN_PNO
10073 .sched_scan_start = wlan_hdd_cfg80211_sched_scan_start,
10074 .sched_scan_stop = wlan_hdd_cfg80211_sched_scan_stop,
10075#endif /*FEATURE_WLAN_SCAN_PNO */
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053010076 .resume = wlan_hdd_cfg80211_resume_wlan,
10077 .suspend = wlan_hdd_cfg80211_suspend_wlan,
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053010078 .set_mac_acl = wlan_hdd_cfg80211_set_mac_acl,
Leo Chang9056f462013-08-01 19:21:11 -070010079#ifdef WLAN_NL80211_TESTMODE
10080 .testmode_cmd = wlan_hdd_cfg80211_testmode,
10081#endif
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053010082 .dump_survey = wlan_hdd_cfg80211_dump_survey,
Jeff Johnson295189b2012-06-20 16:38:30 -070010083};
10084