blob: 68f0ffa820da17fa41feb95a3a04ed9e243667e2 [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/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +05305144 * FUNCTION: __wlan_hdd_cfg80211_scan
Jeff Johnson295189b2012-06-20 16:38:30 -07005145 * this scan respond to scan trigger and update cfg80211 scan database
5146 * later, scan dump command can be used to recieve scan results
5147 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +05305148int __wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -08005149#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
5150 struct net_device *dev,
5151#endif
5152 struct cfg80211_scan_request *request)
5153{
Siddharth Bhal0c162d02014-05-06 19:50:42 +05305154 hdd_adapter_t *pAdapter = NULL;
5155 hdd_context_t *pHddCtx = NULL;
5156 hdd_wext_state_t *pwextBuf = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305157 hdd_config_t *cfg_param = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07005158 tCsrScanRequest scanRequest;
5159 tANI_U8 *channelList = NULL, i;
5160 v_U32_t scanId = 0;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305161 int status;
5162 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07005163 v_U8_t* pP2pIe = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07005164
Siddharth Bhal0c162d02014-05-06 19:50:42 +05305165#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
5166 struct net_device *dev = NULL;
5167 if (NULL == request)
5168 {
5169 hddLog(VOS_TRACE_LEVEL_ERROR,
5170 "%s: scan req param null", __func__);
5171 return -EINVAL;
5172 }
5173 dev = request->wdev->netdev;
5174#endif
5175
5176 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
5177 pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
5178 pwextBuf = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
5179
Jeff Johnson295189b2012-06-20 16:38:30 -07005180 ENTER();
5181
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05305182
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05305183 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
5184 __func__, hdd_device_modetoString(pAdapter->device_mode),
5185 pAdapter->device_mode);
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08005186
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305187 status = wlan_hdd_validate_context(pHddCtx);
5188
5189 if (0 != status)
5190 {
5191 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5192 "%s: HDD context is not valid", __func__);
5193 return status;
5194 }
5195
Siddharth Bhal0c162d02014-05-06 19:50:42 +05305196 if (NULL == pwextBuf)
5197 {
5198 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: invalid WEXT state\n",
5199 __func__);
5200 return -EIO;
5201 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305202 cfg_param = pHddCtx->cfg_ini;
5203 pScanInfo = &pHddCtx->scan_info;
5204
Jeff Johnson295189b2012-06-20 16:38:30 -07005205#ifdef WLAN_BTAMP_FEATURE
5206 //Scan not supported when AMP traffic is on.
Gopichand Nakkala681989c2013-03-06 22:27:48 -08005207 if (VOS_TRUE == WLANBAP_AmpSessionOn())
Jeff Johnson295189b2012-06-20 16:38:30 -07005208 {
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08005209 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07005210 "%s: No scanning when AMP is on", __func__);
5211 return -EOPNOTSUPP;
5212 }
5213#endif
5214 //Scan on any other interface is not supported.
Gopichand Nakkala681989c2013-03-06 22:27:48 -08005215 if (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07005216 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -08005217 hddLog(VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05305218 "%s: Not scanning on device_mode = %s (%d)",
5219 __func__, hdd_device_modetoString(pAdapter->device_mode),
5220 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07005221 return -EOPNOTSUPP;
5222 }
5223
5224 if (TRUE == pScanInfo->mScanPending)
5225 {
Kiet Lamac06e2c2013-10-23 16:25:07 +05305226 if ( MAX_PENDING_LOG > pScanInfo->mScanPendingCounter++ )
5227 {
5228 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: mScanPending is TRUE", __func__);
5229 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08005230 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -07005231 }
5232
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305233 //Don't Allow Scan and return busy if Remain On
Jeff Johnson32d95a32012-09-10 13:15:23 -07005234 //Channel and action frame is pending
5235 //Otherwise Cancel Remain On Channel and allow Scan
5236 //If no action frame pending
Gopichand Nakkala681989c2013-03-06 22:27:48 -08005237 if (0 != wlan_hdd_check_remain_on_channel(pAdapter))
Jeff Johnson32d95a32012-09-10 13:15:23 -07005238 {
Kiet Lamac06e2c2013-10-23 16:25:07 +05305239 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Remain On Channel Pending", __func__);
Jeff Johnson32d95a32012-09-10 13:15:23 -07005240 return -EBUSY;
5241 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08005242#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07005243 /* if tdls disagree scan right now, return immediately.
5244 tdls will schedule the scan when scan is allowed. (return SUCCESS)
5245 or will reject the scan if any TDLS is in progress. (return -EBUSY)
5246 */
5247 status = wlan_hdd_tdls_scan_callback (pAdapter,
5248 wiphy,
5249#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
5250 dev,
Gopichand Nakkalac3c42b92013-03-20 19:42:34 -07005251#endif
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07005252 request);
5253 if(status <= 0)
5254 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05305255 if(!status)
5256 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS in progress."
5257 "scan rejected %d", __func__, status);
5258 else
5259 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS teardown is ongoing %d",
5260 __func__, status);
5261
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07005262 return status;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08005263 }
5264#endif
Jeff Johnson32d95a32012-09-10 13:15:23 -07005265
Jeff Johnson295189b2012-06-20 16:38:30 -07005266 if (mutex_lock_interruptible(&pHddCtx->tmInfo.tmOperationLock))
5267 {
5268 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_ERROR,
Jeff Johnson1250df42012-12-10 14:31:52 -08005269 "%s: Acquire lock fail", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005270 return -EAGAIN;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305271 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005272 if (TRUE == pHddCtx->tmInfo.tmAction.enterImps)
5273 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05305274 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07005275 "%s: MAX TM Level Scan not allowed", __func__);
5276 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305277 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -07005278 }
5279 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
5280
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08005281 /* Check if scan is allowed at this point of time.
5282 */
Rashmi Ramannab1429032014-04-26 14:59:09 +05305283 if (hdd_isConnectionInProgress(pHddCtx))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08005284 {
5285 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Scan not allowed", __func__);
5286 return -EBUSY;
5287 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305288
Jeff Johnson295189b2012-06-20 16:38:30 -07005289 vos_mem_zero( &scanRequest, sizeof(scanRequest));
5290
5291 if (NULL != request)
5292 {
Siddharth Bhal0c162d02014-05-06 19:50:42 +05305293 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
5294 TRACE_CODE_HDD_CFG80211_SCAN,
5295 pAdapter->sessionId, request->n_channels));
Jeff Johnson295189b2012-06-20 16:38:30 -07005296 hddLog(VOS_TRACE_LEVEL_INFO, "scan request for ssid = %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305297 (int)request->n_ssids);
Jeff Johnson295189b2012-06-20 16:38:30 -07005298
5299 /* Even though supplicant doesn't provide any SSIDs, n_ssids is set to 1.
5300 * Becasue of this, driver is assuming that this is not wildcard scan and so
5301 * is not aging out the scan results.
5302 */
Jeff Johnson32d95a32012-09-10 13:15:23 -07005303 if (request->ssids && '\0' == request->ssids->ssid[0])
Jeff Johnson295189b2012-06-20 16:38:30 -07005304 {
5305 request->n_ssids = 0;
5306 }
5307
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07005308 if ((request->ssids) && (0 < request->n_ssids))
Jeff Johnson295189b2012-06-20 16:38:30 -07005309 {
5310 tCsrSSIDInfo *SsidInfo;
5311 int j;
5312 scanRequest.SSIDs.numOfSSIDs = request->n_ssids;
5313 /* Allocate num_ssid tCsrSSIDInfo structure */
5314 SsidInfo = scanRequest.SSIDs.SSIDList =
5315 ( tCsrSSIDInfo *)vos_mem_malloc(
5316 request->n_ssids*sizeof(tCsrSSIDInfo));
5317
5318 if(NULL == scanRequest.SSIDs.SSIDList)
5319 {
5320 hddLog(VOS_TRACE_LEVEL_ERROR,
Nirav Shah20ac06f2013-12-12 18:14:06 +05305321 "%s: memory alloc failed SSIDInfo buffer", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005322 return -ENOMEM;
5323 }
5324
5325 /* copy all the ssid's and their length */
5326 for(j = 0; j < request->n_ssids; j++, SsidInfo++)
5327 {
5328 /* get the ssid length */
5329 SsidInfo->SSID.length = request->ssids[j].ssid_len;
5330 vos_mem_copy(SsidInfo->SSID.ssId, &request->ssids[j].ssid[0],
5331 SsidInfo->SSID.length);
5332 SsidInfo->SSID.ssId[SsidInfo->SSID.length] = '\0';
Nirav Shah20ac06f2013-12-12 18:14:06 +05305333 hddLog(VOS_TRACE_LEVEL_INFO, "SSID number %d: %s",
Jeff Johnson295189b2012-06-20 16:38:30 -07005334 j, SsidInfo->SSID.ssId);
5335 }
5336 /* set the scan type to active */
5337 scanRequest.scanType = eSIR_ACTIVE_SCAN;
5338 }
5339 else if(WLAN_HDD_P2P_GO == pAdapter->device_mode)
5340 {
5341 /* set the scan type to active */
5342 scanRequest.scanType = eSIR_ACTIVE_SCAN;
5343 }
5344 else
5345 {
5346 /*Set the scan type to default type, in this case it is ACTIVE*/
5347 scanRequest.scanType = pScanInfo->scan_mode;
5348 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305349 scanRequest.minChnTime = cfg_param->nActiveMinChnTime;
Jeff Johnson295189b2012-06-20 16:38:30 -07005350 scanRequest.maxChnTime = cfg_param->nActiveMaxChnTime;
5351 }
5352 else
5353 {
Siddharth Bhal0c162d02014-05-06 19:50:42 +05305354 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
5355 TRACE_CODE_HDD_CFG80211_SCAN,
5356 pAdapter->sessionId, 0));
Jeff Johnson295189b2012-06-20 16:38:30 -07005357 /* set the scan type to active */
5358 scanRequest.scanType = eSIR_ACTIVE_SCAN;
5359 vos_mem_set( scanRequest.bssid, sizeof( tCsrBssid ), 0xff );
5360
5361 /* set min and max channel time to zero */
5362 scanRequest.minChnTime = 0;
5363 scanRequest.maxChnTime = 0;
5364 }
5365
5366 /* set BSSType to default type */
5367 scanRequest.BSSType = eCSR_BSS_TYPE_ANY;
5368
5369 /*TODO: scan the requested channels only*/
5370
5371 /*Right now scanning all the channels */
5372 if( request )
5373 {
c_hpothu53512302014-04-15 18:49:53 +05305374 if (MAX_CHANNEL < request->n_channels)
5375 {
5376 hddLog(VOS_TRACE_LEVEL_WARN,
5377 "No of Scan Channels exceeded limit: %d", request->n_channels);
5378 request->n_channels = MAX_CHANNEL;
5379 }
Nirav Shah20ac06f2013-12-12 18:14:06 +05305380 hddLog(VOS_TRACE_LEVEL_INFO,
5381 "No of Scan Channels: %d", request->n_channels);
c_hpothu53512302014-04-15 18:49:53 +05305382
Jeff Johnson295189b2012-06-20 16:38:30 -07005383 if( request->n_channels )
5384 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05305385 char chList [(request->n_channels*5)+1];
5386 int len;
Jeff Johnson295189b2012-06-20 16:38:30 -07005387 channelList = vos_mem_malloc( request->n_channels );
5388 if( NULL == channelList )
5389 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305390 hddLog(VOS_TRACE_LEVEL_ERROR,
Nirav Shah20ac06f2013-12-12 18:14:06 +05305391 "%s: memory alloc failed channelList", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005392 status = -ENOMEM;
5393 goto free_mem;
5394 }
5395
Nirav Shah20ac06f2013-12-12 18:14:06 +05305396 for( i = 0, len = 0; i < request->n_channels ; i++ )
5397 {
Jeff Johnson295189b2012-06-20 16:38:30 -07005398 channelList[i] = request->channels[i]->hw_value;
Nirav Shah20ac06f2013-12-12 18:14:06 +05305399 len += snprintf(chList+len, 5, "%d ", channelList[i]);
5400 }
5401
5402 hddLog(VOS_TRACE_LEVEL_INFO,
5403 "Channel-List: %s ", chList);
Jeff Johnson295189b2012-06-20 16:38:30 -07005404 }
5405
5406 scanRequest.ChannelInfo.numOfChannels = request->n_channels;
5407 scanRequest.ChannelInfo.ChannelList = channelList;
5408
5409 /* set requestType to full scan */
5410 scanRequest.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305411
5412 /* Flush the scan results(only p2p beacons) for STA scan and P2P
Madan Mohan Koyyalamudi8d50f312012-11-27 15:48:57 -08005413 * search (Flush on both full scan and social scan but not on single
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305414 * channel scan).P2P search happens on 3 social channels (1, 6, 11)
Madan Mohan Koyyalamudi8d50f312012-11-27 15:48:57 -08005415 */
5416
5417 /* Supplicant does single channel scan after 8-way handshake
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305418 * and in that case driver shoudnt flush scan results. If
5419 * driver flushes the scan results here and unfortunately if
5420 * the AP doesnt respond to our probe req then association
Madan Mohan Koyyalamudi8d50f312012-11-27 15:48:57 -08005421 * fails which is not desired
5422 */
5423
5424 if( request->n_channels != WLAN_HDD_P2P_SINGLE_CHANNEL_SCAN )
5425 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05305426 hddLog(VOS_TRACE_LEVEL_DEBUG, "Flushing P2P Results");
Madan Mohan Koyyalamudi8d50f312012-11-27 15:48:57 -08005427 sme_ScanFlushP2PResult( WLAN_HDD_GET_HAL_CTX(pAdapter),
5428 pAdapter->sessionId );
5429 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005430
5431 if( request->ie_len )
5432 {
5433 /* save this for future association (join requires this) */
Agarwal Ashish4f616132013-12-30 23:32:50 +05305434 /*TODO: Array needs to be converted to dynamic allocation,
5435 * as multiple ie.s can be sent in cfg80211_scan_request structure
5436 * CR 597966
5437 */
Jeff Johnson295189b2012-06-20 16:38:30 -07005438 memset( &pScanInfo->scanAddIE, 0, sizeof(pScanInfo->scanAddIE) );
5439 memcpy( pScanInfo->scanAddIE.addIEdata, request->ie, request->ie_len);
5440 pScanInfo->scanAddIE.length = request->ie_len;
5441
Agarwal Ashish4f616132013-12-30 23:32:50 +05305442 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Jeff Johnsone7245742012-09-05 17:12:55 -07005443 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
Agarwal Ashish4f616132013-12-30 23:32:50 +05305444 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -07005445 {
Agarwal Ashish4f616132013-12-30 23:32:50 +05305446 if ( request->ie_len <= SIR_MAC_MAX_IE_LENGTH)
5447 {
5448 pwextBuf->roamProfile.nAddIEScanLength = request->ie_len;
5449 memcpy( pwextBuf->roamProfile.addIEScan,
5450 request->ie, request->ie_len);
5451 }
5452 else
5453 {
5454 hddLog(VOS_TRACE_LEVEL_ERROR, "Scan Ie length is invalid:"
Arun Kumar Khandavalli75eeb122014-03-27 21:43:12 +05305455 "%zu", request->ie_len);
Agarwal Ashish4f616132013-12-30 23:32:50 +05305456 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005457
Agarwal Ashish4f616132013-12-30 23:32:50 +05305458 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005459 scanRequest.uIEFieldLen = pScanInfo->scanAddIE.length;
5460 scanRequest.pIEField = pScanInfo->scanAddIE.addIEdata;
5461
Jeff Johnson295189b2012-06-20 16:38:30 -07005462 pP2pIe = wlan_hdd_get_p2p_ie_ptr((v_U8_t*)request->ie,
5463 request->ie_len);
5464 if (pP2pIe != NULL)
5465 {
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07005466#ifdef WLAN_FEATURE_P2P_DEBUG
5467 if (((globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED) ||
5468 (globalP2PConnectionStatus == P2P_GO_NEG_PROCESS)) &&
5469 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
5470 {
5471 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_1;
5472 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
5473 "Go nego completed to Connection is started");
5474 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
5475 "for 8way Handshake");
5476 }
5477 else if((globalP2PConnectionStatus == P2P_CLIENT_DISCONNECTED_STATE) &&
5478 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
5479 {
5480 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_2;
5481 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
5482 "Disconnected state to Connection is started");
5483 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
5484 "for 4way Handshake");
5485 }
5486#endif
5487
Jeff Johnsone7245742012-09-05 17:12:55 -07005488 /* no_cck will be set during p2p find to disable 11b rates */
5489 if(TRUE == request->no_cck)
Jeff Johnson295189b2012-06-20 16:38:30 -07005490 {
Jeff Johnson295189b2012-06-20 16:38:30 -07005491 hddLog(VOS_TRACE_LEVEL_INFO,
5492 "%s: This is a P2P Search", __func__);
5493 scanRequest.p2pSearch = 1;
Jeff Johnsone7245742012-09-05 17:12:55 -07005494
Jeff Johnsone7245742012-09-05 17:12:55 -07005495 if( request->n_channels == WLAN_HDD_P2P_SOCIAL_CHANNELS )
5496 {
Madan Mohan Koyyalamudi1b1d9e82012-10-21 11:38:33 -07005497 /* set requestType to P2P Discovery */
5498 scanRequest.requestType = eCSR_SCAN_P2P_DISCOVERY;
Jeff Johnsone7245742012-09-05 17:12:55 -07005499 }
5500
5501 /*
5502 Skip Dfs Channel in case of P2P Search
5503 if it is set in ini file
5504 */
5505 if(cfg_param->skipDfsChnlInP2pSearch)
5506 {
5507 scanRequest.skipDfsChnlInP2pSearch = 1;
5508 }
5509 else
5510 {
5511 scanRequest.skipDfsChnlInP2pSearch = 0;
5512 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005513
Jeff Johnson295189b2012-06-20 16:38:30 -07005514 }
5515 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005516 }
5517 }
5518
5519 INIT_COMPLETION(pScanInfo->scan_req_completion_event);
5520
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07005521 /* acquire the wakelock to avoid the apps suspend during the scan. To
5522 * address the following issues.
5523 * 1) Disconnected scenario: we are not allowing the suspend as WLAN is not in
5524 * BMPS/IMPS this result in android trying to suspend aggressively and backing off
5525 * for long time, this result in apps running at full power for long time.
5526 * 2) Connected scenario: If we allow the suspend during the scan, RIVA will
5527 * be stuck in full power because of resume BMPS
5528 */
5529 hdd_prevent_suspend();
Jeff Johnsone7245742012-09-05 17:12:55 -07005530
Nirav Shah20ac06f2013-12-12 18:14:06 +05305531 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
5532 "requestType %d, scanType %d, minChnTime %d, maxChnTime %d,"
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05305533 "p2pSearch %d, skipDfsChnlInP2pSearch %d",
5534 scanRequest.requestType, scanRequest.scanType,
5535 scanRequest.minChnTime, scanRequest.maxChnTime,
Nirav Shah20ac06f2013-12-12 18:14:06 +05305536 scanRequest.p2pSearch, scanRequest.skipDfsChnlInP2pSearch);
5537
Jeff Johnsone7245742012-09-05 17:12:55 -07005538 status = sme_ScanRequest( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07005539 pAdapter->sessionId, &scanRequest, &scanId,
5540 &hdd_cfg80211_scan_done_callback, dev );
Jeff Johnsone7245742012-09-05 17:12:55 -07005541
Jeff Johnson295189b2012-06-20 16:38:30 -07005542 if (eHAL_STATUS_SUCCESS != status)
5543 {
5544 hddLog(VOS_TRACE_LEVEL_ERROR,
5545 "%s: sme_ScanRequest returned error %d", __func__, status);
5546 complete(&pScanInfo->scan_req_completion_event);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -07005547 if(eHAL_STATUS_RESOURCES == status)
5548 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05305549 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: HO is in progress."
5550 "So defer the scan by informing busy",__func__);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -07005551 status = -EBUSY;
5552 } else {
5553 status = -EIO;
5554 }
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07005555 hdd_allow_suspend();
Jeff Johnson295189b2012-06-20 16:38:30 -07005556 goto free_mem;
5557 }
5558
5559 pScanInfo->mScanPending = TRUE;
5560 pAdapter->request = request;
5561 pScanInfo->scanId = scanId;
5562
5563 complete(&pScanInfo->scan_req_completion_event);
5564
5565free_mem:
5566 if( scanRequest.SSIDs.SSIDList )
5567 {
5568 vos_mem_free(scanRequest.SSIDs.SSIDList);
5569 }
5570
5571 if( channelList )
5572 vos_mem_free( channelList );
5573
5574 EXIT();
5575
5576 return status;
5577}
5578
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +05305579int wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
5580#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
5581 struct net_device *dev,
5582#endif
5583 struct cfg80211_scan_request *request)
5584{
5585 int ret;
5586
5587 vos_ssr_protect(__func__);
5588 ret = __wlan_hdd_cfg80211_scan(wiphy,
5589#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
5590 dev,
5591#endif
5592 request);
5593 vos_ssr_unprotect(__func__);
5594
5595 return ret;
5596}
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07005597
5598void hdd_select_cbmode( hdd_adapter_t *pAdapter,v_U8_t operationChannel)
5599{
5600 v_U8_t iniDot11Mode =
5601 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->dot11Mode;
5602 eHddDot11Mode hddDot11Mode = iniDot11Mode;
5603
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +05305604 hddLog(LOG1, FL("Channel Bonding Mode Selected is %u"),
5605 iniDot11Mode);
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07005606 switch ( iniDot11Mode )
5607 {
5608 case eHDD_DOT11_MODE_AUTO:
5609 case eHDD_DOT11_MODE_11ac:
5610 case eHDD_DOT11_MODE_11ac_ONLY:
5611#ifdef WLAN_FEATURE_11AC
5612 hddDot11Mode = eHDD_DOT11_MODE_11ac;
5613#else
5614 hddDot11Mode = eHDD_DOT11_MODE_11n;
5615#endif
5616 break;
5617 case eHDD_DOT11_MODE_11n:
5618 case eHDD_DOT11_MODE_11n_ONLY:
5619 hddDot11Mode = eHDD_DOT11_MODE_11n;
5620 break;
5621 default:
5622 hddDot11Mode = iniDot11Mode;
5623 break;
5624 }
5625 /* This call decides required channel bonding mode */
5626 sme_SelectCBMode((WLAN_HDD_GET_CTX(pAdapter)->hHal),
5627 hdd_cfg_xlate_to_csr_phy_mode(hddDot11Mode),
5628 operationChannel);
5629}
5630
Jeff Johnson295189b2012-06-20 16:38:30 -07005631/*
5632 * FUNCTION: wlan_hdd_cfg80211_connect_start
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305633 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -07005634 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305635int wlan_hdd_cfg80211_connect_start( hdd_adapter_t *pAdapter,
Jeff Johnson32d95a32012-09-10 13:15:23 -07005636 const u8 *ssid, size_t ssid_len, const u8 *bssid, u8 operatingChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -07005637{
5638 int status = 0;
5639 hdd_wext_state_t *pWextState;
Yue Mae36e3552014-03-05 17:06:20 -08005640 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07005641 v_U32_t roamId;
5642 tCsrRoamProfile *pRoamProfile;
Jeff Johnson295189b2012-06-20 16:38:30 -07005643 eCsrAuthType RSNAuthType;
5644
5645 ENTER();
5646
5647 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Yue Mae36e3552014-03-05 17:06:20 -08005648 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
5649
5650 status = wlan_hdd_validate_context(pHddCtx);
5651 if (status)
5652 {
5653 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5654 "%s: HDD context is not valid!", __func__);
5655 return status;
5656 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305657
Jeff Johnson295189b2012-06-20 16:38:30 -07005658 if (SIR_MAC_MAX_SSID_LENGTH < ssid_len)
5659 {
5660 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wrong SSID len", __func__);
5661 return -EINVAL;
5662 }
5663
5664 pRoamProfile = &pWextState->roamProfile;
5665
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305666 if (pRoamProfile)
Jeff Johnson295189b2012-06-20 16:38:30 -07005667 {
Jeff Johnsone7245742012-09-05 17:12:55 -07005668 hdd_station_ctx_t *pHddStaCtx;
5669 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07005670
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305671 if (HDD_WMM_USER_MODE_NO_QOS ==
Jeff Johnson295189b2012-06-20 16:38:30 -07005672 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->WmmMode)
5673 {
5674 /*QoS not enabled in cfg file*/
5675 pRoamProfile->uapsd_mask = 0;
5676 }
5677 else
5678 {
5679 /*QoS enabled, update uapsd mask from cfg file*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305680 pRoamProfile->uapsd_mask =
Jeff Johnson295189b2012-06-20 16:38:30 -07005681 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask;
5682 }
5683
5684 pRoamProfile->SSIDs.numOfSSIDs = 1;
5685 pRoamProfile->SSIDs.SSIDList->SSID.length = ssid_len;
5686 vos_mem_zero(pRoamProfile->SSIDs.SSIDList->SSID.ssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305687 sizeof(pRoamProfile->SSIDs.SSIDList->SSID.ssId));
Jeff Johnson295189b2012-06-20 16:38:30 -07005688 vos_mem_copy((void *)(pRoamProfile->SSIDs.SSIDList->SSID.ssId),
5689 ssid, ssid_len);
5690
5691 if (bssid)
5692 {
5693 pRoamProfile->BSSIDs.numOfBSSIDs = 1;
5694 vos_mem_copy((void *)(pRoamProfile->BSSIDs.bssid), bssid,
5695 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305696 /* Save BSSID in seperate variable as well, as RoamProfile
5697 BSSID is getting zeroed out in the association process. And in
Jeff Johnson295189b2012-06-20 16:38:30 -07005698 case of join failure we should send valid BSSID to supplicant
5699 */
5700 vos_mem_copy((void *)(pWextState->req_bssId), bssid,
5701 WNI_CFG_BSSID_LEN);
5702 }
Dhanashri Atre51981c62013-06-13 11:47:57 -07005703 else
5704 {
5705 vos_mem_zero((void *)(pRoamProfile->BSSIDs.bssid),WNI_CFG_BSSID_LEN);
5706 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005707
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +05305708 hddLog(LOG1, FL("Connect to SSID: %s opertating Channel: %u"),
5709 pRoamProfile->SSIDs.SSIDList->SSID.ssId, operatingChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -07005710 if ((IW_AUTH_WPA_VERSION_WPA == pWextState->wpaVersion) ||
5711 (IW_AUTH_WPA_VERSION_WPA2 == pWextState->wpaVersion))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305712 {
Jeff Johnson295189b2012-06-20 16:38:30 -07005713 /*set gen ie*/
5714 hdd_SetGENIEToCsr(pAdapter, &RSNAuthType);
5715 /*set auth*/
5716 hdd_set_csr_auth_type(pAdapter, RSNAuthType);
5717 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005718#ifdef FEATURE_WLAN_WAPI
5719 if (pAdapter->wapi_info.nWapiMode)
5720 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005721 hddLog(LOG1, "%s: Setting WAPI AUTH Type and Encryption Mode values", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005722 switch (pAdapter->wapi_info.wapiAuthMode)
5723 {
5724 case WAPI_AUTH_MODE_PSK:
5725 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005726 hddLog(LOG1, "%s: WAPI AUTH TYPE: PSK: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07005727 pAdapter->wapi_info.wapiAuthMode);
5728 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_PSK;
5729 break;
5730 }
5731 case WAPI_AUTH_MODE_CERT:
5732 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005733 hddLog(LOG1, "%s: WAPI AUTH TYPE: CERT: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07005734 pAdapter->wapi_info.wapiAuthMode);
5735 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE;
5736 break;
5737 }
5738 } // End of switch
5739 if ( pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_PSK ||
5740 pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_CERT)
5741 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005742 hddLog(LOG1, "%s: WAPI PAIRWISE/GROUP ENCRYPTION: WPI", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005743 pRoamProfile->AuthType.numEntries = 1;
5744 pRoamProfile->EncryptionType.numEntries = 1;
5745 pRoamProfile->EncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
5746 pRoamProfile->mcEncryptionType.numEntries = 1;
5747 pRoamProfile->mcEncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
5748 }
5749 }
5750#endif /* FEATURE_WLAN_WAPI */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05305751#ifdef WLAN_FEATURE_GTK_OFFLOAD
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05305752 /* Initializing gtkOffloadReqParams */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05305753 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
5754 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
5755 {
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05305756 memset(&pHddStaCtx->gtkOffloadReqParams, 0,
5757 sizeof (tSirGtkOffloadParams));
5758 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_DISABLE;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05305759 }
5760#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005761 pRoamProfile->csrPersona = pAdapter->device_mode;
5762
Jeff Johnson32d95a32012-09-10 13:15:23 -07005763 if( operatingChannel )
5764 {
5765 pRoamProfile->ChannelInfo.ChannelList = &operatingChannel;
5766 pRoamProfile->ChannelInfo.numOfChannels = 1;
5767 }
Chet Lanctot186b5732013-03-18 10:26:30 -07005768 else
5769 {
5770 pRoamProfile->ChannelInfo.ChannelList = NULL;
5771 pRoamProfile->ChannelInfo.numOfChannels = 0;
5772 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07005773 if ( (WLAN_HDD_IBSS == pAdapter->device_mode) && operatingChannel)
5774 {
5775 hdd_select_cbmode(pAdapter,operatingChannel);
5776 }
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +05305777
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08005778 /* change conn_state to connecting before sme_RoamConnect(), because sme_RoamConnect()
5779 * has a direct path to call hdd_smeRoamCallback(), which will change the conn_state
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305780 * If direct path, conn_state will be accordingly changed to NotConnected or Associated
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08005781 * by either hdd_AssociationCompletionHandler() or hdd_DisConnectHandler() in sme_RoamCallback()
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -08005782 * if sme_RomConnect is to be queued, Connecting state will remain until it is completed.
5783 */
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05305784 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
5785 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode)
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -08005786 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
5787 eConnectionState_Connecting);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305788
5789 status = sme_RoamConnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07005790 pAdapter->sessionId, pRoamProfile, &roamId);
5791
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05305792 if ((eHAL_STATUS_SUCCESS != status) &&
5793 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
5794 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +05305795
5796 {
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08005797 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: sme_RoamConnect (session %d) failed with "
5798 "status %d. -> NotConnected", __func__, pAdapter->sessionId, status);
5799 /* change back to NotAssociated */
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +05305800 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08005801 eConnectionState_NotConnected);
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +05305802 }
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -08005803
5804 pRoamProfile->ChannelInfo.ChannelList = NULL;
5805 pRoamProfile->ChannelInfo.numOfChannels = 0;
5806
Jeff Johnson295189b2012-06-20 16:38:30 -07005807 }
5808 else
5809 {
5810 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid Roam profile", __func__);
5811 return -EINVAL;
5812 }
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08005813 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07005814 return status;
5815}
5816
5817/*
5818 * FUNCTION: wlan_hdd_set_cfg80211_auth_type
5819 * This function is used to set the authentication type (OPEN/SHARED).
5820 *
5821 */
5822static int wlan_hdd_cfg80211_set_auth_type(hdd_adapter_t *pAdapter,
5823 enum nl80211_auth_type auth_type)
5824{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305825 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07005826 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
5827
5828 ENTER();
5829
5830 /*set authentication type*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305831 switch (auth_type)
Jeff Johnson295189b2012-06-20 16:38:30 -07005832 {
Jeff Johnson295189b2012-06-20 16:38:30 -07005833 case NL80211_AUTHTYPE_AUTOMATIC:
Gopichand Nakkala29149562013-05-10 21:43:41 +05305834 hddLog(VOS_TRACE_LEVEL_INFO,
5835 "%s: set authentication type to AUTOSWITCH", __func__);
5836 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_AUTOSWITCH;
5837 break;
5838
5839 case NL80211_AUTHTYPE_OPEN_SYSTEM:
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07005840#ifdef WLAN_FEATURE_VOWIFI_11R
5841 case NL80211_AUTHTYPE_FT:
5842#endif /* WLAN_FEATURE_VOWIFI_11R */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305843 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -07005844 "%s: set authentication type to OPEN", __func__);
5845 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
5846 break;
5847
5848 case NL80211_AUTHTYPE_SHARED_KEY:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305849 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -07005850 "%s: set authentication type to SHARED", __func__);
5851 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_SHARED_KEY;
5852 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005853#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -07005854 case NL80211_AUTHTYPE_NETWORK_EAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305855 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -07005856 "%s: set authentication type to CCKM WPA", __func__);
5857 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_CCKM_WPA;//eCSR_AUTH_TYPE_CCKM_RSN needs to be handled as well if required.
5858 break;
5859#endif
5860
5861
5862 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305863 hddLog(VOS_TRACE_LEVEL_ERROR,
5864 "%s: Unsupported authentication type %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07005865 auth_type);
5866 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_UNKNOWN;
5867 return -EINVAL;
5868 }
5869
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305870 pWextState->roamProfile.AuthType.authType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -07005871 pHddStaCtx->conn_info.authType;
5872 return 0;
5873}
5874
5875/*
5876 * FUNCTION: wlan_hdd_set_akm_suite
5877 * This function is used to set the key mgmt type(PSK/8021x).
5878 *
5879 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305880static int wlan_hdd_set_akm_suite( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07005881 u32 key_mgmt
5882 )
5883{
5884 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
5885 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305886
Jeff Johnson295189b2012-06-20 16:38:30 -07005887 /*set key mgmt type*/
5888 switch(key_mgmt)
5889 {
5890 case WLAN_AKM_SUITE_PSK:
Gopichand Nakkala356fb102013-03-06 12:34:04 +05305891#ifdef WLAN_FEATURE_VOWIFI_11R
5892 case WLAN_AKM_SUITE_FT_PSK:
5893#endif
5894 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to PSK",
Jeff Johnson295189b2012-06-20 16:38:30 -07005895 __func__);
5896 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_PSK;
5897 break;
5898
5899 case WLAN_AKM_SUITE_8021X:
Gopichand Nakkala356fb102013-03-06 12:34:04 +05305900#ifdef WLAN_FEATURE_VOWIFI_11R
5901 case WLAN_AKM_SUITE_FT_8021X:
5902#endif
5903 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to 8021x",
Jeff Johnson295189b2012-06-20 16:38:30 -07005904 __func__);
5905 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
5906 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005907#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -07005908#define WLAN_AKM_SUITE_CCKM 0x00409600 /* Should be in ieee802_11_defs.h */
5909#define IW_AUTH_KEY_MGMT_CCKM 8 /* Should be in linux/wireless.h */
5910 case WLAN_AKM_SUITE_CCKM:
5911 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to CCKM",
5912 __func__);
5913 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_CCKM;
5914 break;
5915#endif
Leela Venkata Kiran Kumar Reddy Chiralae208a832014-04-27 22:34:25 -07005916#ifndef WLAN_AKM_SUITE_OSEN
5917#define WLAN_AKM_SUITE_OSEN 0x506f9a01 /* Should be in ieee802_11_defs.h */
5918 case WLAN_AKM_SUITE_OSEN:
5919 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to OSEN",
5920 __func__);
5921 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
5922 break;
5923#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005924
5925 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305926 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported key mgmt type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07005927 __func__, key_mgmt);
5928 return -EINVAL;
5929
5930 }
5931 return 0;
5932}
5933
5934/*
5935 * FUNCTION: wlan_hdd_cfg80211_set_cipher
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305936 * This function is used to set the encryption type
Jeff Johnson295189b2012-06-20 16:38:30 -07005937 * (NONE/WEP40/WEP104/TKIP/CCMP).
5938 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305939static int wlan_hdd_cfg80211_set_cipher( hdd_adapter_t *pAdapter,
5940 u32 cipher,
Jeff Johnson295189b2012-06-20 16:38:30 -07005941 bool ucast
5942 )
5943{
5944 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305945 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07005946 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
5947
5948 ENTER();
5949
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305950 if (!cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -07005951 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305952 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: received cipher %d - considering none",
Jeff Johnson295189b2012-06-20 16:38:30 -07005953 __func__, cipher);
5954 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
5955 }
5956 else
5957 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305958
Jeff Johnson295189b2012-06-20 16:38:30 -07005959 /*set encryption method*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305960 switch (cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -07005961 {
5962 case IW_AUTH_CIPHER_NONE:
5963 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
5964 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305965
Jeff Johnson295189b2012-06-20 16:38:30 -07005966 case WLAN_CIPHER_SUITE_WEP40:
Gopichand Nakkala29149562013-05-10 21:43:41 +05305967 encryptionType = eCSR_ENCRYPT_TYPE_WEP40;
Jeff Johnson295189b2012-06-20 16:38:30 -07005968 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305969
Jeff Johnson295189b2012-06-20 16:38:30 -07005970 case WLAN_CIPHER_SUITE_WEP104:
Gopichand Nakkala29149562013-05-10 21:43:41 +05305971 encryptionType = eCSR_ENCRYPT_TYPE_WEP104;
Jeff Johnson295189b2012-06-20 16:38:30 -07005972 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305973
Jeff Johnson295189b2012-06-20 16:38:30 -07005974 case WLAN_CIPHER_SUITE_TKIP:
5975 encryptionType = eCSR_ENCRYPT_TYPE_TKIP;
5976 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305977
Jeff Johnson295189b2012-06-20 16:38:30 -07005978 case WLAN_CIPHER_SUITE_CCMP:
5979 encryptionType = eCSR_ENCRYPT_TYPE_AES;
5980 break;
5981#ifdef FEATURE_WLAN_WAPI
5982 case WLAN_CIPHER_SUITE_SMS4:
5983 encryptionType = eCSR_ENCRYPT_TYPE_WPI;
5984 break;
5985#endif
5986
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005987#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -07005988 case WLAN_CIPHER_SUITE_KRK:
5989 encryptionType = eCSR_ENCRYPT_TYPE_KRK;
5990 break;
5991#endif
5992 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305993 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported cipher type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07005994 __func__, cipher);
5995 return -EOPNOTSUPP;
5996 }
5997 }
5998
5999 if (ucast)
6000 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306001 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting unicast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07006002 __func__, encryptionType);
6003 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
6004 pWextState->roamProfile.EncryptionType.numEntries = 1;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306005 pWextState->roamProfile.EncryptionType.encryptionType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -07006006 encryptionType;
6007 }
6008 else
6009 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306010 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting mcast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07006011 __func__, encryptionType);
6012 pHddStaCtx->conn_info.mcEncryptionType = encryptionType;
6013 pWextState->roamProfile.mcEncryptionType.numEntries = 1;
6014 pWextState->roamProfile.mcEncryptionType.encryptionType[0] = encryptionType;
6015 }
6016
6017 return 0;
6018}
6019
6020
6021/*
6022 * FUNCTION: wlan_hdd_cfg80211_set_ie
6023 * This function is used to parse WPA/RSN IE's.
6024 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306025int wlan_hdd_cfg80211_set_ie( hdd_adapter_t *pAdapter,
6026 u8 *ie,
Jeff Johnson295189b2012-06-20 16:38:30 -07006027 size_t ie_len
6028 )
6029{
6030 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
6031 u8 *genie = ie;
6032 v_U16_t remLen = ie_len;
6033#ifdef FEATURE_WLAN_WAPI
6034 v_U32_t akmsuite[MAX_NUM_AKM_SUITES];
6035 u16 *tmp;
6036 v_U16_t akmsuiteCount;
6037 int *akmlist;
6038#endif
6039 ENTER();
6040
6041 /* clear previous assocAddIE */
6042 pWextState->assocAddIE.length = 0;
6043 pWextState->roamProfile.bWPSAssociation = VOS_FALSE;
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -07006044 pWextState->roamProfile.bOSENAssociation = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07006045
6046 while (remLen >= 2)
6047 {
6048 v_U16_t eLen = 0;
6049 v_U8_t elementId;
6050 elementId = *genie++;
6051 eLen = *genie++;
6052 remLen -= 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306053
Arif Hussain6d2a3322013-11-17 19:50:10 -08006054 hddLog(VOS_TRACE_LEVEL_INFO, "%s: IE[0x%X], LEN[%d]",
Jeff Johnson295189b2012-06-20 16:38:30 -07006055 __func__, elementId, eLen);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306056
6057 switch ( elementId )
Jeff Johnson295189b2012-06-20 16:38:30 -07006058 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306059 case DOT11F_EID_WPA:
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07006060 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 -07006061 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306062 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07006063 "%s: Invalid WPA IE", __func__);
6064 return -EINVAL;
6065 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306066 else if (0 == memcmp(&genie[0], "\x00\x50\xf2\x04", 4))
Jeff Johnson295189b2012-06-20 16:38:30 -07006067 {
6068 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306069 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPS IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -07006070 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306071
Jeff Johnson295189b2012-06-20 16:38:30 -07006072 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
6073 {
Jeff Johnson902c9832012-12-10 14:28:09 -08006074 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE. "
6075 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -07006076 VOS_ASSERT(0);
6077 return -ENOMEM;
6078 }
6079 // WSC IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
6080 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
6081 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306082
Jeff Johnson295189b2012-06-20 16:38:30 -07006083 pWextState->roamProfile.bWPSAssociation = VOS_TRUE;
6084 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
6085 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
6086 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306087 else if (0 == memcmp(&genie[0], "\x00\x50\xf2", 3))
6088 {
Jeff Johnson295189b2012-06-20 16:38:30 -07006089 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPA IE (len %d)",__func__, eLen + 2);
6090 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
6091 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2) /*ie_len*/);
6092 pWextState->roamProfile.pWPAReqIE = pWextState->WPARSNIE;
6093 pWextState->roamProfile.nWPAReqIELength = eLen + 2;//ie_len;
6094 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306095 else if ( (0 == memcmp(&genie[0], P2P_OUI_TYPE,
Kiet Lam8da98992013-11-21 15:59:07 +05306096 P2P_OUI_TYPE_SIZE)))
Jeff Johnson295189b2012-06-20 16:38:30 -07006097 {
6098 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306099 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set P2P IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -07006100 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306101
Jeff Johnson295189b2012-06-20 16:38:30 -07006102 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
6103 {
Jeff Johnson902c9832012-12-10 14:28:09 -08006104 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
6105 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -07006106 VOS_ASSERT(0);
6107 return -ENOMEM;
6108 }
6109 // P2P IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
6110 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
6111 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306112
Jeff Johnson295189b2012-06-20 16:38:30 -07006113 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
6114 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
6115 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006116#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306117 else if ( (0 == memcmp(&genie[0], WFD_OUI_TYPE,
6118 WFD_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07006119 /*Consider WFD IE, only for P2P Client */
6120 && (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
6121 {
6122 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306123 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WFD IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -07006124 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306125
Jeff Johnson295189b2012-06-20 16:38:30 -07006126 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
6127 {
Jeff Johnson902c9832012-12-10 14:28:09 -08006128 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
6129 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -07006130 VOS_ASSERT(0);
6131 return -ENOMEM;
6132 }
6133 // WFD IE is saved to Additional IE ; it should be accumulated to handle
6134 // WPS IE + P2P IE + WFD IE
6135 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
6136 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306137
Jeff Johnson295189b2012-06-20 16:38:30 -07006138 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
6139 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
6140 }
6141#endif
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07006142 /* Appending HS 2.0 Indication Element in Assiciation Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306143 else if ( (0 == memcmp(&genie[0], HS20_OUI_TYPE,
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07006144 HS20_OUI_TYPE_SIZE)) )
6145 {
6146 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306147 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set HS20 IE(len %d)",
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07006148 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07006149
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07006150 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
6151 {
Jeff Johnson902c9832012-12-10 14:28:09 -08006152 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
6153 "Need bigger buffer space");
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07006154 VOS_ASSERT(0);
6155 return -ENOMEM;
6156 }
6157 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
6158 pWextState->assocAddIE.length += eLen + 2;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07006159
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07006160 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
6161 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
6162 }
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -07006163 /* Appending OSEN Information Element in Assiciation Request */
6164 else if ( (0 == memcmp(&genie[0], OSEN_OUI_TYPE,
6165 OSEN_OUI_TYPE_SIZE)) )
6166 {
6167 v_U16_t curAddIELen = pWextState->assocAddIE.length;
6168 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set OSEN IE(len %d)",
6169 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07006170
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -07006171 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
6172 {
6173 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
6174 "Need bigger buffer space");
6175 VOS_ASSERT(0);
6176 return -ENOMEM;
6177 }
6178 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
6179 pWextState->assocAddIE.length += eLen + 2;
6180
6181 pWextState->roamProfile.bOSENAssociation = VOS_TRUE;
6182 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
6183 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
6184 }
6185
6186 break;
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -07006187 if (WLAN_HDD_IBSS == pAdapter->device_mode) {
6188
6189 /* populating as ADDIE in beacon frames */
6190 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
6191 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, genie - 2, eLen + 2,
6192 NULL, eANI_BOOLEAN_FALSE)== eHAL_STATUS_SUCCESS)
6193 {
6194 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
6195 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
6196 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
6197 {
6198 hddLog(LOGE,
6199 "Coldn't pass "
6200 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
6201 }
6202 }/* ccmCfgSetStr(,WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, , )*/
6203 else
6204 hddLog(LOGE,
6205 "Could not pass on "
6206 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
6207
6208 /* IBSS mode doesn't contain params->proberesp_ies still
6209 beaconIE's need to be populated in probe response frames */
6210 if ( (NULL != (genie - 2)) && (0 != eLen + 2) )
6211 {
6212 u16 rem_probe_resp_ie_len = eLen + 2;
6213 u8 probe_rsp_ie_len[3] = {0};
6214 u8 counter = 0;
6215
6216 /* Check Probe Resp Length if it is greater then 255 then
6217 Store Probe Rsp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1
6218 & WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are
6219 not able Store More then 255 bytes into One Variable */
6220
6221 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
6222 {
6223 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
6224 {
6225 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
6226 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
6227 }
6228 else
6229 {
6230 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
6231 rem_probe_resp_ie_len = 0;
6232 }
6233 }
6234
6235 rem_probe_resp_ie_len = 0;
6236
6237 if (probe_rsp_ie_len[0] > 0)
6238 {
6239 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
6240 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
6241 (tANI_U8*)(genie - 2),
6242 probe_rsp_ie_len[0], NULL,
6243 eANI_BOOLEAN_FALSE)
6244 == eHAL_STATUS_FAILURE)
6245 {
6246 hddLog(LOGE,
6247 "Could not pass"
6248 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
6249 }
6250 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
6251 }
6252
6253 if (probe_rsp_ie_len[1] > 0)
6254 {
6255 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
6256 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
6257 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
6258 probe_rsp_ie_len[1], NULL,
6259 eANI_BOOLEAN_FALSE)
6260 == eHAL_STATUS_FAILURE)
6261 {
6262 hddLog(LOGE,
6263 "Could not pass"
6264 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
6265 }
6266 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
6267 }
6268
6269 if (probe_rsp_ie_len[2] > 0)
6270 {
6271 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
6272 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
6273 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
6274 probe_rsp_ie_len[2], NULL,
6275 eANI_BOOLEAN_FALSE)
6276 == eHAL_STATUS_FAILURE)
6277 {
6278 hddLog(LOGE,
6279 "Could not pass"
6280 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
6281 }
6282 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
6283 }
6284
6285 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
6286 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
6287 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
6288 {
6289 hddLog(LOGE,
6290 "Could not pass"
6291 "on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
6292 }
6293 }
6294 else
6295 {
6296 // Reset WNI_CFG_PROBE_RSP Flags
6297 wlan_hdd_reset_prob_rspies(pAdapter);
6298
6299 hddLog(VOS_TRACE_LEVEL_INFO,
6300 "%s: No Probe Response IE received in set beacon",
6301 __func__);
6302 }
6303 } /* end of if (WLAN_HDD_IBSS == pAdapter->device_mode) */
Jeff Johnson295189b2012-06-20 16:38:30 -07006304 break;
6305 case DOT11F_EID_RSN:
6306 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set RSN IE(len %d)",__func__, eLen + 2);
6307 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
6308 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2)/*ie_len*/);
6309 pWextState->roamProfile.pRSNReqIE = pWextState->WPARSNIE;
6310 pWextState->roamProfile.nRSNReqIELength = eLen + 2; //ie_len;
6311 break;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07006312 /* Appending Extended Capabilities with Interworking bit set in Assoc Req */
6313 case DOT11F_EID_EXTCAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306314 {
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07006315 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306316 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set Extended CAPS IE(len %d)",
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07006317 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306318
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07006319 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
6320 {
Jeff Johnson902c9832012-12-10 14:28:09 -08006321 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
6322 "Need bigger buffer space");
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07006323 VOS_ASSERT(0);
6324 return -ENOMEM;
6325 }
6326 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
6327 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306328
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07006329 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
6330 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
6331 break;
6332 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006333#ifdef FEATURE_WLAN_WAPI
6334 case WLAN_EID_WAPI:
6335 pAdapter->wapi_info.nWapiMode = 1; //Setting WAPI Mode to ON=1
Jeff Johnson0299d0a2013-10-30 12:37:43 -07006336 hddLog(VOS_TRACE_LEVEL_INFO, "WAPI MODE IS %u",
Jeff Johnson295189b2012-06-20 16:38:30 -07006337 pAdapter->wapi_info.nWapiMode);
6338 tmp = (u16 *)ie;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306339 tmp = tmp + 2; // Skip element Id and Len, Version
Jeff Johnson295189b2012-06-20 16:38:30 -07006340 akmsuiteCount = WPA_GET_LE16(tmp);
6341 tmp = tmp + 1;
6342 akmlist = (int *)(tmp);
6343 if(akmsuiteCount <= MAX_NUM_AKM_SUITES)
6344 {
6345 memcpy(akmsuite, akmlist, (4*akmsuiteCount));
6346 }
6347 else
6348 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08006349 hddLog(VOS_TRACE_LEVEL_FATAL, "Invalid akmSuite count");
Jeff Johnson295189b2012-06-20 16:38:30 -07006350 VOS_ASSERT(0);
6351 return -EINVAL;
6352 }
6353
6354 if (WAPI_PSK_AKM_SUITE == akmsuite[0])
6355 {
6356 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO PSK",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006357 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006358 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_PSK;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306359 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006360 if (WAPI_CERT_AKM_SUITE == akmsuite[0])
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306361 {
Jeff Johnson295189b2012-06-20 16:38:30 -07006362 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO CERTIFICATE",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006363 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006364 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_CERT;
6365 }
6366 break;
6367#endif
6368 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306369 hddLog (VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07006370 "%s Set UNKNOWN IE %X", __func__, elementId);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07006371 /* when Unknown IE is received we should break and continue
6372 * to the next IE in the buffer instead we were returning
6373 * so changing this to break */
6374 break;
Jeff Johnson295189b2012-06-20 16:38:30 -07006375 }
6376 genie += eLen;
6377 remLen -= eLen;
6378 }
6379 EXIT();
6380 return 0;
6381}
6382
6383/*
Gopichand Nakkala18f0c262013-05-07 23:25:08 +05306384 * FUNCTION: hdd_isWPAIEPresent
6385 * Parse the received IE to find the WPA IE
6386 *
6387 */
6388static bool hdd_isWPAIEPresent(u8 *ie, u8 ie_len)
6389{
6390 v_U8_t eLen = 0;
6391 v_U16_t remLen = ie_len;
6392 v_U8_t elementId = 0;
6393
6394 while (remLen >= 2)
6395 {
6396 elementId = *ie++;
6397 eLen = *ie++;
6398 remLen -= 2;
6399 if (eLen > remLen)
6400 {
6401 hddLog(VOS_TRACE_LEVEL_ERROR,
6402 "%s: IE length is wrong %d", __func__, eLen);
6403 return FALSE;
6404 }
6405 if ((elementId == DOT11F_EID_WPA) && (remLen > 5))
6406 {
6407 /* OUI - 0x00 0X50 0XF2
6408 WPA Information Element - 0x01
6409 WPA version - 0x01*/
6410 if (0 == memcmp(&ie[0], "\x00\x50\xf2\x01\x01", 5))
6411 return TRUE;
6412 }
6413 ie += eLen;
6414 remLen -= eLen;
6415 }
6416 return FALSE;
6417}
6418
6419/*
Jeff Johnson295189b2012-06-20 16:38:30 -07006420 * FUNCTION: wlan_hdd_cfg80211_set_privacy
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306421 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -07006422 * parameters during connect operation.
6423 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306424int wlan_hdd_cfg80211_set_privacy( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07006425 struct cfg80211_connect_params *req
6426 )
6427{
6428 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306429 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07006430 ENTER();
6431
6432 /*set wpa version*/
6433 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
6434
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306435 if (req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -07006436 {
Gopichand Nakkala781ded42013-06-28 12:10:45 +05306437 if (NL80211_WPA_VERSION_1 == req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -07006438 {
6439 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
6440 }
6441 else if (NL80211_WPA_VERSION_2 == req->crypto.wpa_versions)
6442 {
6443 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
6444 }
6445 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306446
6447 hddLog(VOS_TRACE_LEVEL_INFO, "%s: set wpa version to %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07006448 pWextState->wpaVersion);
6449
6450 /*set authentication type*/
6451 status = wlan_hdd_cfg80211_set_auth_type(pAdapter, req->auth_type);
6452
6453 if (0 > status)
6454 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306455 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07006456 "%s: failed to set authentication type ", __func__);
6457 return status;
6458 }
6459
6460 /*set key mgmt type*/
6461 if (req->crypto.n_akm_suites)
6462 {
6463 status = wlan_hdd_set_akm_suite(pAdapter, req->crypto.akm_suites[0]);
6464 if (0 > status)
6465 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306466 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set akm suite",
Jeff Johnson295189b2012-06-20 16:38:30 -07006467 __func__);
6468 return status;
6469 }
6470 }
6471
6472 /*set pairwise cipher type*/
6473 if (req->crypto.n_ciphers_pairwise)
6474 {
6475 status = wlan_hdd_cfg80211_set_cipher(pAdapter,
6476 req->crypto.ciphers_pairwise[0], true);
6477 if (0 > status)
6478 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306479 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07006480 "%s: failed to set unicast cipher type", __func__);
6481 return status;
6482 }
6483 }
6484 else
6485 {
6486 /*Reset previous cipher suite to none*/
6487 status = wlan_hdd_cfg80211_set_cipher(pAdapter, 0, true);
6488 if (0 > status)
6489 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306490 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07006491 "%s: failed to set unicast cipher type", __func__);
6492 return status;
6493 }
6494 }
6495
6496 /*set group cipher type*/
6497 status = wlan_hdd_cfg80211_set_cipher(pAdapter, req->crypto.cipher_group,
6498 false);
6499
6500 if (0 > status)
6501 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306502 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set mcast cipher type",
Jeff Johnson295189b2012-06-20 16:38:30 -07006503 __func__);
6504 return status;
6505 }
6506
Chet Lanctot186b5732013-03-18 10:26:30 -07006507#ifdef WLAN_FEATURE_11W
6508 pWextState->roamProfile.MFPEnabled = (req->mfp == NL80211_MFP_REQUIRED);
6509#endif
6510
Jeff Johnson295189b2012-06-20 16:38:30 -07006511 /*parse WPA/RSN IE, and set the correspoing fileds in Roam profile*/
6512 if (req->ie_len)
6513 {
6514 status = wlan_hdd_cfg80211_set_ie(pAdapter, req->ie, req->ie_len);
6515 if ( 0 > status)
6516 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306517 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse the WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -07006518 __func__);
6519 return status;
6520 }
6521 }
6522
6523 /*incase of WEP set default key information*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306524 if (req->key && req->key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -07006525 {
6526 if ( (WLAN_CIPHER_SUITE_WEP40 == req->crypto.ciphers_pairwise[0])
6527 || (WLAN_CIPHER_SUITE_WEP104 == req->crypto.ciphers_pairwise[0])
6528 )
6529 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306530 if ( IW_AUTH_KEY_MGMT_802_1X
Jeff Johnson295189b2012-06-20 16:38:30 -07006531 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X ))
6532 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306533 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Dynamic WEP not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -07006534 __func__);
6535 return -EOPNOTSUPP;
6536 }
6537 else
6538 {
6539 u8 key_len = req->key_len;
6540 u8 key_idx = req->key_idx;
6541
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306542 if ((eCSR_SECURITY_WEP_KEYSIZE_MAX_BYTES >= key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -07006543 && (CSR_MAX_NUM_KEY > key_idx)
6544 )
6545 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306546 hddLog(VOS_TRACE_LEVEL_INFO,
6547 "%s: setting default wep key, key_idx = %hu key_len %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07006548 __func__, key_idx, key_len);
6549 vos_mem_copy(
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306550 &pWextState->roamProfile.Keys.KeyMaterial[key_idx][0],
Jeff Johnson295189b2012-06-20 16:38:30 -07006551 req->key, key_len);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306552 pWextState->roamProfile.Keys.KeyLength[key_idx] =
Jeff Johnson295189b2012-06-20 16:38:30 -07006553 (u8)key_len;
6554 pWextState->roamProfile.Keys.defaultIndex = (u8)key_idx;
6555 }
6556 }
6557 }
6558 }
6559
6560 return status;
6561}
6562
6563/*
Vinay Krishna Eranna21042322014-01-08 19:21:39 +05306564 * FUNCTION: wlan_hdd_try_disconnect
6565 * This function is used to disconnect from previous
6566 * connection
6567 */
6568static int wlan_hdd_try_disconnect( hdd_adapter_t *pAdapter )
6569{
6570 long ret = 0;
6571 hdd_station_ctx_t *pHddStaCtx;
6572 eMib_dot11DesiredBssType connectedBssType;
6573
6574 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6575
6576 hdd_connGetConnectedBssType(pHddStaCtx,&connectedBssType );
6577
6578 if((eMib_dot11DesiredBssType_independent == connectedBssType) ||
6579 (eConnectionState_Associated == pHddStaCtx->conn_info.connState) ||
6580 (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState))
6581 {
6582 /* Issue disconnect to CSR */
6583 INIT_COMPLETION(pAdapter->disconnect_comp_var);
6584 if( eHAL_STATUS_SUCCESS ==
6585 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
6586 pAdapter->sessionId,
6587 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
6588 {
6589 ret = wait_for_completion_interruptible_timeout(
6590 &pAdapter->disconnect_comp_var,
6591 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
6592 if (0 >= ret)
6593 {
6594 hddLog(LOGE, FL("Failed to receive disconnect event"));
6595 return -EALREADY;
6596 }
6597 }
6598 }
6599 else if(eConnectionState_Disconnecting == pHddStaCtx->conn_info.connState)
6600 {
6601 ret = wait_for_completion_interruptible_timeout(
6602 &pAdapter->disconnect_comp_var,
6603 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
6604 if (0 >= ret)
6605 {
6606 hddLog(LOGE, FL("Failed to receive disconnect event"));
6607 return -EALREADY;
6608 }
6609 }
6610
6611 return 0;
6612}
6613
6614/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +05306615 * FUNCTION: __wlan_hdd_cfg80211_set_privacy
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306616 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -07006617 * parameters during connect operation.
6618 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +05306619static int __wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07006620 struct net_device *ndev,
6621 struct cfg80211_connect_params *req
6622 )
6623{
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306624 int status;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306625 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -07006626 VOS_STATUS exitbmpsStatus = VOS_STATUS_E_INVAL;
Rajesh Chauhana0516c62014-01-30 16:11:18 -08006627 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07006628
6629 ENTER();
6630
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05306631 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
6632 TRACE_CODE_HDD_CFG80211_CONNECT,
6633 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306634 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05306635 "%s: device_mode = %s (%d)", __func__,
6636 hdd_device_modetoString(pAdapter->device_mode),
6637 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07006638
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306639 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -08006640 if (!pHddCtx)
6641 {
6642 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6643 "%s: HDD context is null", __func__);
6644 return VOS_STATUS_E_FAILURE;
6645 }
6646
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306647 status = wlan_hdd_validate_context(pHddCtx);
6648
6649 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -07006650 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306651 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6652 "%s: HDD context is not valid", __func__);
6653 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -07006654 }
6655
6656#ifdef WLAN_BTAMP_FEATURE
6657 //Infra connect not supported when AMP traffic is on.
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306658 if( VOS_TRUE == WLANBAP_AmpSessionOn() )
Jeff Johnson295189b2012-06-20 16:38:30 -07006659 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306660 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07006661 "%s: No connection when AMP is on", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08006662 return -ECONNREFUSED;
Jeff Johnson295189b2012-06-20 16:38:30 -07006663 }
6664#endif
Vinay Krishna Eranna21042322014-01-08 19:21:39 +05306665
6666 //If Device Mode is Station Concurrent Sessions Exit BMps
6667 //P2P Mode will be taken care in Open/close adapter
6668 if((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
6669 (vos_concurrent_sessions_running()))
6670 {
6671 exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
6672 }
6673
6674 /*Try disconnecting if already in connected state*/
6675 status = wlan_hdd_try_disconnect(pAdapter);
6676 if ( 0 > status)
6677 {
6678 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
6679 " connection"));
6680 return -EALREADY;
6681 }
6682
Jeff Johnson295189b2012-06-20 16:38:30 -07006683 /*initialise security parameters*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306684 status = wlan_hdd_cfg80211_set_privacy(pAdapter, req);
Jeff Johnson295189b2012-06-20 16:38:30 -07006685
6686 if ( 0 > status)
6687 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306688 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security params",
Jeff Johnson295189b2012-06-20 16:38:30 -07006689 __func__);
6690 return status;
6691 }
6692
Mohit Khanna765234a2012-09-11 15:08:35 -07006693 if ( req->channel )
6694 {
6695 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
6696 req->ssid_len, req->bssid,
6697 req->channel->hw_value);
6698 }
6699 else
6700 {
6701 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306702 req->ssid_len, req->bssid, 0);
Mohit Khanna765234a2012-09-11 15:08:35 -07006703 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006704
6705 if (0 > status)
6706 {
6707 //ReEnable BMPS if disabled
6708 if((VOS_STATUS_SUCCESS == exitbmpsStatus) &&
6709 (NULL != pHddCtx))
6710 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306711 if (pHddCtx->hdd_wlan_suspended)
6712 {
6713 hdd_set_pwrparams(pHddCtx);
6714 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006715 //ReEnable Bmps and Imps back
6716 hdd_enable_bmps_imps(pHddCtx);
6717 }
6718
6719 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: connect failed", __func__);
6720 return status;
6721 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306722 pHddCtx->isAmpAllowed = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07006723 EXIT();
6724 return status;
6725}
6726
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +05306727static int wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
6728 struct net_device *ndev,
6729 struct cfg80211_connect_params *req)
6730{
6731 int ret;
6732 vos_ssr_protect(__func__);
6733 ret = __wlan_hdd_cfg80211_connect(wiphy, ndev, req);
6734 vos_ssr_unprotect(__func__);
6735
6736 return ret;
6737}
Jeff Johnson295189b2012-06-20 16:38:30 -07006738
6739/*
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05306740 * FUNCTION: wlan_hdd_disconnect
6741 * This function is used to issue a disconnect request to SME
6742 */
6743int wlan_hdd_disconnect( hdd_adapter_t *pAdapter, u16 reason )
6744{
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306745 int status;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05306746 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306747 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
6748
6749 status = wlan_hdd_validate_context(pHddCtx);
6750
6751 if (0 != status)
6752 {
6753 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6754 "%s: HDD context is not valid", __func__);
6755 return status;
6756 }
6757
6758 pHddCtx->isAmpAllowed = VOS_TRUE;
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +05306759 pHddStaCtx->conn_info.connState = eConnectionState_Disconnecting;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05306760 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306761
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05306762 /*issue disconnect*/
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +05306763
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05306764 status = sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
6765 pAdapter->sessionId, reason);
6766
6767 if ( 0 != status )
6768 {
6769 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006770 "%s csrRoamDisconnect failure, returned %d",
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05306771 __func__, (int)status );
6772 return -EINVAL;
6773 }
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +05306774 status = wait_for_completion_interruptible_timeout(
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05306775 &pAdapter->disconnect_comp_var,
6776 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +05306777 if (!status)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306778 {
6779 hddLog(VOS_TRACE_LEVEL_ERROR,
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +05306780 "%s: Failed to disconnect, timed out", __func__);
6781 return -ETIMEDOUT;
6782 }
6783 else if (status == -ERESTARTSYS)
6784 {
6785 hddLog(VOS_TRACE_LEVEL_ERROR,
6786 "%s: Failed to disconnect, wait interrupted", __func__);
6787 return status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306788 }
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05306789 /*stop tx queues*/
6790 netif_tx_disable(pAdapter->dev);
6791 netif_carrier_off(pAdapter->dev);
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +05306792 return 0;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05306793}
6794
6795
6796/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +05306797 * FUNCTION: __wlan_hdd_cfg80211_disconnect
Jeff Johnson295189b2012-06-20 16:38:30 -07006798 * This function is used to issue a disconnect request to SME
6799 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +05306800static int __wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07006801 struct net_device *dev,
6802 u16 reason
6803 )
6804{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306805 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
6806 tCsrRoamProfile *pRoamProfile =
Jeff Johnson295189b2012-06-20 16:38:30 -07006807 &(WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter))->roamProfile;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306808 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07006809 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkala4327a152013-03-04 23:22:42 -08006810 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaaa353782013-05-17 20:36:22 +05306811#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08006812 tANI_U8 staIdx;
6813#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306814
Jeff Johnson295189b2012-06-20 16:38:30 -07006815 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306816
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05306817 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
6818 TRACE_CODE_HDD_CFG80211_DISCONNECT,
6819 pAdapter->sessionId, reason));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05306820 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s(%d)",
6821 __func__, hdd_device_modetoString(pAdapter->device_mode),
6822 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07006823
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306824 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Disconnect called with reason code %d",
6825 __func__, reason);
Jeff Johnson295189b2012-06-20 16:38:30 -07006826
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306827 status = wlan_hdd_validate_context(pHddCtx);
6828
6829 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -07006830 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306831 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6832 "%s: HDD context is not valid", __func__);
6833 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -07006834 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306835
Jeff Johnson295189b2012-06-20 16:38:30 -07006836 if (NULL != pRoamProfile)
6837 {
6838 /*issue disconnect request to SME, if station is in connected state*/
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +05306839 if ((pHddStaCtx->conn_info.connState == eConnectionState_Associated) ||
6840 (pHddStaCtx->conn_info.connState == eConnectionState_Connecting))
Jeff Johnson295189b2012-06-20 16:38:30 -07006841 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306842 eCsrRoamDisconnectReason reasonCode =
Jeff Johnson295189b2012-06-20 16:38:30 -07006843 eCSR_DISCONNECT_REASON_UNSPECIFIED;
Gopichand Nakkalaaa353782013-05-17 20:36:22 +05306844 hdd_scaninfo_t *pScanInfo;
Jeff Johnson295189b2012-06-20 16:38:30 -07006845 switch(reason)
6846 {
6847 case WLAN_REASON_MIC_FAILURE:
6848 reasonCode = eCSR_DISCONNECT_REASON_MIC_ERROR;
6849 break;
6850
6851 case WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY:
6852 case WLAN_REASON_DISASSOC_AP_BUSY:
6853 case WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA:
6854 reasonCode = eCSR_DISCONNECT_REASON_DISASSOC;
6855 break;
6856
6857 case WLAN_REASON_PREV_AUTH_NOT_VALID:
6858 case WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA:
6859 reasonCode = eCSR_DISCONNECT_REASON_DEAUTH;
6860 break;
6861
6862 case WLAN_REASON_DEAUTH_LEAVING:
6863 default:
6864 reasonCode = eCSR_DISCONNECT_REASON_UNSPECIFIED;
6865 break;
6866 }
Gopichand Nakkalaaa353782013-05-17 20:36:22 +05306867 pScanInfo = &pHddCtx->scan_info;
6868 if (pScanInfo->mScanPending)
6869 {
Srinivas, Dasari138af4f2014-02-07 11:13:45 +05306870 hddLog(VOS_TRACE_LEVEL_INFO, "Disconnect is in progress, "
Gopichand Nakkalaaa353782013-05-17 20:36:22 +05306871 "Aborting Scan");
Srinivas, Dasari138af4f2014-02-07 11:13:45 +05306872 hdd_abort_mac_scan(pHddCtx, pAdapter->sessionId,
6873 eCSR_SCAN_ABORT_DEFAULT);
Gopichand Nakkalaaa353782013-05-17 20:36:22 +05306874 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006875
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08006876#ifdef FEATURE_WLAN_TDLS
6877 /* First clean up the tdls peers if any */
Gopichand Nakkala4327a152013-03-04 23:22:42 -08006878 for (staIdx = 0 ; staIdx < HDD_MAX_NUM_TDLS_STA; staIdx++)
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08006879 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -08006880 if ((pHddCtx->tdlsConnInfo[staIdx].sessionId == pAdapter->sessionId) &&
6881 (pHddCtx->tdlsConnInfo[staIdx].staId))
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08006882 {
Hoonki Lee11f7dda2013-02-14 16:55:44 -08006883 uint8 *mac;
Gopichand Nakkala4327a152013-03-04 23:22:42 -08006884 mac = pHddCtx->tdlsConnInfo[staIdx].peerMac.bytes;
Hoonki Lee11f7dda2013-02-14 16:55:44 -08006885 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07006886 "%s: call sme_DeleteTdlsPeerSta staId %d sessionId %d " MAC_ADDRESS_STR,
Gopichand Nakkala4327a152013-03-04 23:22:42 -08006887 __func__, pHddCtx->tdlsConnInfo[staIdx].staId, pAdapter->sessionId,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07006888 MAC_ADDR_ARRAY(mac));
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08006889 sme_DeleteTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala4327a152013-03-04 23:22:42 -08006890 pAdapter->sessionId,
6891 mac);
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08006892 }
6893 }
6894#endif
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +05306895 hddLog(LOG1, FL("Disconnecting with reasoncode:%u"), reasonCode);
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05306896 status = wlan_hdd_disconnect(pAdapter, reasonCode);
6897 if ( 0 != status )
Jeff Johnson295189b2012-06-20 16:38:30 -07006898 {
6899 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006900 "%s wlan_hdd_disconnect failure, returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07006901 __func__, (int)status );
6902 return -EINVAL;
6903 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006904 }
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +05306905 else
6906 {
6907 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unexpected cfg disconnect API"
6908 "called while in %d state", __func__,
6909 pHddStaCtx->conn_info.connState);
6910 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006911 }
6912 else
6913 {
6914 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid roam profile", __func__);
6915 }
6916
6917 return status;
6918}
6919
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +05306920static int wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
6921 struct net_device *dev,
6922 u16 reason
6923 )
6924{
6925 int ret;
6926 vos_ssr_protect(__func__);
6927 ret = __wlan_hdd_cfg80211_disconnect(wiphy, dev, reason);
6928 vos_ssr_unprotect(__func__);
6929
6930 return ret;
6931}
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05306932
Jeff Johnson295189b2012-06-20 16:38:30 -07006933/*
6934 * FUNCTION: wlan_hdd_cfg80211_set_privacy_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306935 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -07006936 * settings in IBSS mode.
6937 */
6938static int wlan_hdd_cfg80211_set_privacy_ibss(
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306939 hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07006940 struct cfg80211_ibss_params *params
6941 )
6942{
6943 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306944 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07006945 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
6946 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306947
Jeff Johnson295189b2012-06-20 16:38:30 -07006948 ENTER();
6949
6950 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
Ravi Joshib58ca0d2013-10-29 09:50:23 -07006951 vos_mem_zero(&pHddStaCtx->ibss_enc_key, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -07006952
6953 if (params->ie_len && ( NULL != params->ie) )
6954 {
Shailender Karmuchi67edd312013-06-18 16:30:48 -07006955 if (wlan_hdd_cfg80211_get_ie_ptr (params->ie,
6956 params->ie_len, WLAN_EID_RSN ))
Jeff Johnson295189b2012-06-20 16:38:30 -07006957 {
6958 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
6959 encryptionType = eCSR_ENCRYPT_TYPE_AES;
6960 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -07006961 else if ( hdd_isWPAIEPresent (params->ie, params->ie_len ))
Jeff Johnson295189b2012-06-20 16:38:30 -07006962 {
Shailender Karmuchi642e9812013-05-30 14:34:49 -07006963 tDot11fIEWPA dot11WPAIE;
6964 tHalHandle halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
Shailender Karmuchi67edd312013-06-18 16:30:48 -07006965 u8 *ie;
Shailender Karmuchi642e9812013-05-30 14:34:49 -07006966
Wilson Yang00256342013-10-10 23:13:38 -07006967 memset(&dot11WPAIE, 0, sizeof(dot11WPAIE));
Shailender Karmuchi67edd312013-06-18 16:30:48 -07006968 ie = wlan_hdd_cfg80211_get_ie_ptr (params->ie,
6969 params->ie_len, DOT11F_EID_WPA);
6970 if ( NULL != ie )
6971 {
6972 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
6973 // Unpack the WPA IE
6974 //Skip past the EID byte and length byte - and four byte WiFi OUI
6975 dot11fUnpackIeWPA((tpAniSirGlobal) halHandle,
6976 &ie[2+4],
6977 ie[1] - 4,
6978 &dot11WPAIE);
6979 /*Extract the multicast cipher, the encType for unicast
6980 cipher for wpa-none is none*/
6981 encryptionType =
6982 hdd_TranslateWPAToCsrEncryptionType(dot11WPAIE.multicast_cipher);
6983 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006984 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -07006985
Jeff Johnson295189b2012-06-20 16:38:30 -07006986 status = wlan_hdd_cfg80211_set_ie(pAdapter, params->ie, params->ie_len);
6987
6988 if (0 > status)
6989 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306990 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -07006991 __func__);
6992 return status;
6993 }
6994 }
6995
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306996 pWextState->roamProfile.AuthType.authType[0] =
6997 pHddStaCtx->conn_info.authType =
Jeff Johnson295189b2012-06-20 16:38:30 -07006998 eCSR_AUTH_TYPE_OPEN_SYSTEM;
6999
7000 if (params->privacy)
7001 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307002 /* Security enabled IBSS, At this time there is no information available
7003 * about the security paramters, so initialise the encryption type to
Jeff Johnson295189b2012-06-20 16:38:30 -07007004 * eCSR_ENCRYPT_TYPE_WEP40_STATICKEY.
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307005 * The correct security parameters will be updated later in
Jeff Johnson295189b2012-06-20 16:38:30 -07007006 * wlan_hdd_cfg80211_add_key */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307007 /* Hal expects encryption type to be set inorder
Jeff Johnson295189b2012-06-20 16:38:30 -07007008 *enable privacy bit in beacons */
7009
7010 encryptionType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
7011 }
Shailender Karmuchi642e9812013-05-30 14:34:49 -07007012 VOS_TRACE (VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
7013 "encryptionType=%d", encryptionType);
Jeff Johnson295189b2012-06-20 16:38:30 -07007014 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
7015 pWextState->roamProfile.EncryptionType.numEntries = 1;
7016 pWextState->roamProfile.EncryptionType.encryptionType[0] = encryptionType;
Jeff Johnson295189b2012-06-20 16:38:30 -07007017 return status;
7018}
7019
7020/*
7021 * FUNCTION: wlan_hdd_cfg80211_join_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307022 * This function is used to create/join an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -07007023 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307024static int wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07007025 struct net_device *dev,
7026 struct cfg80211_ibss_params *params
7027 )
7028{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307029 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Jeff Johnson295189b2012-06-20 16:38:30 -07007030 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
7031 tCsrRoamProfile *pRoamProfile;
7032 int status;
krunal sonie9002db2013-11-25 14:24:17 -08007033 bool alloc_bssid = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07007034 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307035 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07007036
7037 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307038
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307039 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7040 TRACE_CODE_HDD_CFG80211_JOIN_IBSS,
7041 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307042 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05307043 "%s: device_mode = %s (%d)", __func__,
7044 hdd_device_modetoString(pAdapter->device_mode),
7045 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07007046
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307047 status = wlan_hdd_validate_context(pHddCtx);
7048
7049 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -07007050 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307051 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7052 "%s: HDD context is not valid", __func__);
7053 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -07007054 }
7055
7056 if (NULL == pWextState)
7057 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08007058 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -07007059 __func__);
7060 return -EIO;
7061 }
7062
Vinay Krishna Eranna21042322014-01-08 19:21:39 +05307063 /*Try disconnecting if already in connected state*/
7064 status = wlan_hdd_try_disconnect(pAdapter);
7065 if ( 0 > status)
7066 {
7067 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
7068 " IBSS connection"));
7069 return -EALREADY;
7070 }
7071
Jeff Johnson295189b2012-06-20 16:38:30 -07007072 pRoamProfile = &pWextState->roamProfile;
7073
7074 if ( eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType )
7075 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307076 hddLog (VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007077 "%s Interface type is not set to IBSS", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007078 return -EINVAL;
7079 }
7080
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -07007081 /* BSSID is provided by upper layers hence no need to AUTO generate */
7082 if (NULL != params->bssid) {
7083 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
7084 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) {
7085 hddLog (VOS_TRACE_LEVEL_ERROR,
7086 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
7087 return -EIO;
7088 }
7089 }
krunal sonie9002db2013-11-25 14:24:17 -08007090 else if(pHddCtx->cfg_ini->isCoalesingInIBSSAllowed == 0)
7091 {
7092 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
7093 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
7094 {
7095 hddLog (VOS_TRACE_LEVEL_ERROR,
7096 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
7097 return -EIO;
7098 }
7099 params->bssid = vos_mem_malloc(sizeof(VOS_MAC_ADDR_SIZE));
7100 if (!params->bssid)
7101 {
7102 hddLog (VOS_TRACE_LEVEL_ERROR,
7103 "%s:Failed memory allocation", __func__);
7104 return -EIO;
7105 }
7106 vos_mem_copy((v_U8_t *)params->bssid,
7107 (v_U8_t *)&pHddCtx->cfg_ini->IbssBssid.bytes[0],
7108 VOS_MAC_ADDR_SIZE);
7109 alloc_bssid = VOS_TRUE;
7110 }
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -07007111
Jeff Johnson295189b2012-06-20 16:38:30 -07007112 /* Set Channel */
Yue Maf49ba872013-08-19 12:04:25 -07007113 if (NULL !=
7114#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
7115 params->chandef.chan)
7116#else
7117 params->channel)
7118#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007119 {
7120 u8 channelNum;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07007121 v_U32_t numChans = WNI_CFG_VALID_CHANNEL_LIST_LEN;
7122 v_U8_t validChan[WNI_CFG_VALID_CHANNEL_LIST_LEN];
7123 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
7124 int indx;
Jeff Johnson295189b2012-06-20 16:38:30 -07007125
7126 /* Get channel number */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307127 channelNum =
Yue Maf49ba872013-08-19 12:04:25 -07007128 ieee80211_frequency_to_channel(
7129#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
7130 params->chandef.chan->center_freq);
7131#else
7132 params->channel->center_freq);
7133#endif
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07007134
7135 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
7136 validChan, &numChans))
Jeff Johnson295189b2012-06-20 16:38:30 -07007137 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07007138 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid channel list",
7139 __func__);
7140 return -EOPNOTSUPP;
Jeff Johnson295189b2012-06-20 16:38:30 -07007141 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07007142
7143 for (indx = 0; indx < numChans; indx++)
Jeff Johnson295189b2012-06-20 16:38:30 -07007144 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07007145 if (channelNum == validChan[indx])
7146 {
7147 break;
7148 }
7149 }
7150 if (indx >= numChans)
7151 {
7152 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Not valid Channel %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07007153 __func__, channelNum);
7154 return -EINVAL;
7155 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07007156 /* Set the Operational Channel */
7157 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: set channel %d", __func__,
7158 channelNum);
7159 pRoamProfile->ChannelInfo.numOfChannels = 1;
7160 pHddStaCtx->conn_info.operationChannel = channelNum;
7161 pRoamProfile->ChannelInfo.ChannelList =
7162 &pHddStaCtx->conn_info.operationChannel;
Jeff Johnson295189b2012-06-20 16:38:30 -07007163 }
7164
7165 /* Initialize security parameters */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307166 status = wlan_hdd_cfg80211_set_privacy_ibss(pAdapter, params);
Jeff Johnson295189b2012-06-20 16:38:30 -07007167 if (status < 0)
7168 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307169 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security parameters",
Jeff Johnson295189b2012-06-20 16:38:30 -07007170 __func__);
7171 return status;
7172 }
7173
7174 /* Issue connect start */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307175 status = wlan_hdd_cfg80211_connect_start(pAdapter, params->ssid,
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07007176 params->ssid_len, params->bssid,
7177 pHddStaCtx->conn_info.operationChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -07007178
7179 if (0 > status)
7180 {
7181 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: connect failed", __func__);
7182 return status;
7183 }
7184
krunal sonie9002db2013-11-25 14:24:17 -08007185 if (NULL != params->bssid &&
7186 pHddCtx->cfg_ini->isCoalesingInIBSSAllowed == 0 &&
7187 alloc_bssid == VOS_TRUE)
7188 {
7189 vos_mem_free(params->bssid);
7190 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007191 return 0;
7192}
7193
7194/*
7195 * FUNCTION: wlan_hdd_cfg80211_leave_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307196 * This function is used to leave an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -07007197 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307198static int wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07007199 struct net_device *dev
7200 )
7201{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307202 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Jeff Johnson295189b2012-06-20 16:38:30 -07007203 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
7204 tCsrRoamProfile *pRoamProfile;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307205 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7206 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07007207
7208 ENTER();
7209
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307210 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7211 TRACE_CODE_HDD_CFG80211_LEAVE_IBSS,
7212 pAdapter->sessionId, eCSR_DISCONNECT_REASON_IBSS_LEAVE));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307213 status = wlan_hdd_validate_context(pHddCtx);
7214
7215 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007216 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307217 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7218 "%s: HDD context is not valid", __func__);
7219 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007220 }
7221
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05307222 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)", __func__,
7223 hdd_device_modetoString(pAdapter->device_mode),
7224 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07007225 if (NULL == pWextState)
7226 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08007227 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -07007228 __func__);
7229 return -EIO;
7230 }
7231
7232 pRoamProfile = &pWextState->roamProfile;
7233
7234 /* Issue disconnect only if interface type is set to IBSS */
7235 if (eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType)
7236 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307237 hddLog (VOS_TRACE_LEVEL_ERROR, "%s: BSS Type is not set to IBSS",
Jeff Johnson295189b2012-06-20 16:38:30 -07007238 __func__);
7239 return -EINVAL;
7240 }
7241
7242 /* Issue Disconnect request */
7243 INIT_COMPLETION(pAdapter->disconnect_comp_var);
7244 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
7245 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
7246
7247 return 0;
7248}
7249
7250/*
7251 * FUNCTION: wlan_hdd_cfg80211_set_wiphy_params
7252 * This function is used to set the phy parameters
7253 * (RTS Threshold/FRAG Threshold/Retry Count etc ...)
7254 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307255static int wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07007256 u32 changed)
7257{
7258 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
7259 tHalHandle hHal = pHddCtx->hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307260 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07007261
7262 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307263 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7264 TRACE_CODE_HDD_CFG80211_SET_WIPHY_PARAMS,
7265 NO_SESSION, wiphy->rts_threshold));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307266 status = wlan_hdd_validate_context(pHddCtx);
7267
7268 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007269 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307270 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7271 "%s: HDD context is not valid", __func__);
7272 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007273 }
7274
Jeff Johnson295189b2012-06-20 16:38:30 -07007275 if (changed & WIPHY_PARAM_RTS_THRESHOLD)
7276 {
7277 u16 rts_threshold = (wiphy->rts_threshold == -1) ?
7278 WNI_CFG_RTS_THRESHOLD_STAMAX :
7279 wiphy->rts_threshold;
7280
7281 if ((WNI_CFG_RTS_THRESHOLD_STAMIN > rts_threshold) ||
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307282 (WNI_CFG_RTS_THRESHOLD_STAMAX < rts_threshold))
Jeff Johnson295189b2012-06-20 16:38:30 -07007283 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307284 hddLog(VOS_TRACE_LEVEL_ERROR,
7285 "%s: Invalid RTS Threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07007286 __func__, rts_threshold);
7287 return -EINVAL;
7288 }
7289
7290 if (0 != ccmCfgSetInt(hHal, WNI_CFG_RTS_THRESHOLD,
7291 rts_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307292 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -07007293 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307294 hddLog(VOS_TRACE_LEVEL_ERROR,
7295 "%s: ccmCfgSetInt failed for rts_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07007296 __func__, rts_threshold);
7297 return -EIO;
7298 }
7299
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307300 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set rts threshold %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07007301 rts_threshold);
7302 }
7303
7304 if (changed & WIPHY_PARAM_FRAG_THRESHOLD)
7305 {
7306 u16 frag_threshold = (wiphy->frag_threshold == -1) ?
7307 WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX :
7308 wiphy->frag_threshold;
7309
7310 if ((WNI_CFG_FRAGMENTATION_THRESHOLD_STAMIN > frag_threshold)||
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307311 (WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX < frag_threshold) )
Jeff Johnson295189b2012-06-20 16:38:30 -07007312 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307313 hddLog(VOS_TRACE_LEVEL_ERROR,
7314 "%s: Invalid frag_threshold value %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07007315 frag_threshold);
7316 return -EINVAL;
7317 }
7318
7319 if (0 != ccmCfgSetInt(hHal, WNI_CFG_FRAGMENTATION_THRESHOLD,
7320 frag_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307321 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -07007322 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307323 hddLog(VOS_TRACE_LEVEL_ERROR,
7324 "%s: ccmCfgSetInt failed for frag_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07007325 __func__, frag_threshold);
7326 return -EIO;
7327 }
7328
7329 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set frag threshold %hu", __func__,
7330 frag_threshold);
7331 }
7332
7333 if ((changed & WIPHY_PARAM_RETRY_SHORT)
7334 || (changed & WIPHY_PARAM_RETRY_LONG))
7335 {
7336 u8 retry_value = (changed & WIPHY_PARAM_RETRY_SHORT) ?
7337 wiphy->retry_short :
7338 wiphy->retry_long;
7339
7340 if ((WNI_CFG_LONG_RETRY_LIMIT_STAMIN > retry_value) ||
7341 (WNI_CFG_LONG_RETRY_LIMIT_STAMAX < retry_value))
7342 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307343 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07007344 __func__, retry_value);
7345 return -EINVAL;
7346 }
7347
7348 if (changed & WIPHY_PARAM_RETRY_SHORT)
7349 {
7350 if (0 != ccmCfgSetInt(hHal, WNI_CFG_LONG_RETRY_LIMIT,
7351 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307352 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -07007353 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307354 hddLog(VOS_TRACE_LEVEL_ERROR,
7355 "%s: ccmCfgSetInt failed for long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07007356 __func__, retry_value);
7357 return -EIO;
7358 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307359 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07007360 __func__, retry_value);
7361 }
7362 else if (changed & WIPHY_PARAM_RETRY_SHORT)
7363 {
7364 if (0 != ccmCfgSetInt(hHal, WNI_CFG_SHORT_RETRY_LIMIT,
7365 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307366 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -07007367 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307368 hddLog(VOS_TRACE_LEVEL_ERROR,
7369 "%s: ccmCfgSetInt failed for short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07007370 __func__, retry_value);
7371 return -EIO;
7372 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307373 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07007374 __func__, retry_value);
7375 }
7376 }
7377
7378 return 0;
7379}
7380
7381/*
7382 * FUNCTION: wlan_hdd_cfg80211_set_txpower
7383 * This function is used to set the txpower
7384 */
7385static int wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
Yue Maf49ba872013-08-19 12:04:25 -07007386#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
7387 struct wireless_dev *wdev,
7388#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007389#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307390 enum tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -07007391#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307392 enum nl80211_tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -07007393#endif
7394 int dbm)
7395{
7396 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307397 tHalHandle hHal = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07007398 tSirMacAddr bssid = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
7399 tSirMacAddr selfMac = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307400 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07007401
7402 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307403 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7404 TRACE_CODE_HDD_CFG80211_SET_TXPOWER,
7405 NO_SESSION, type ));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307406 status = wlan_hdd_validate_context(pHddCtx);
7407
7408 if (0 != status)
7409 {
7410 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7411 "%s: HDD context is not valid", __func__);
7412 return status;
7413 }
7414
7415 hHal = pHddCtx->hHal;
7416
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307417 if (0 != ccmCfgSetInt(hHal, WNI_CFG_CURRENT_TX_POWER_LEVEL,
7418 dbm, ccmCfgSetCallback,
7419 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -07007420 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307421 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07007422 "%s: ccmCfgSetInt failed for tx power %hu", __func__, dbm);
7423 return -EIO;
7424 }
7425
7426 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set tx power level %d dbm", __func__,
7427 dbm);
7428
7429 switch(type)
7430 {
7431 case NL80211_TX_POWER_AUTOMATIC: /*automatically determine transmit power*/
7432 /* Fall through */
7433 case NL80211_TX_POWER_LIMITED: /*limit TX power by the mBm parameter*/
7434 if( sme_SetMaxTxPower(hHal, bssid, selfMac, dbm) != eHAL_STATUS_SUCCESS )
7435 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307436 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Setting maximum tx power failed",
7437 __func__);
7438 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -07007439 }
7440 break;
7441 case NL80211_TX_POWER_FIXED: /*fix TX power to the mBm parameter*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307442 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: NL80211_TX_POWER_FIXED not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -07007443 __func__);
7444 return -EOPNOTSUPP;
7445 break;
7446 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307447 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid power setting type %d",
7448 __func__, type);
Jeff Johnson295189b2012-06-20 16:38:30 -07007449 return -EIO;
7450 }
7451
7452 return 0;
7453}
7454
7455/*
7456 * FUNCTION: wlan_hdd_cfg80211_get_txpower
7457 * This function is used to read the txpower
7458 */
Yue Maf49ba872013-08-19 12:04:25 -07007459static int wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy,
7460#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
7461 struct wireless_dev *wdev,
7462#endif
7463 int *dbm)
Jeff Johnson295189b2012-06-20 16:38:30 -07007464{
7465
7466 hdd_adapter_t *pAdapter;
7467 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307468 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07007469
Jeff Johnsone7245742012-09-05 17:12:55 -07007470 ENTER();
7471
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307472 status = wlan_hdd_validate_context(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07007473
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307474 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007475 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307476 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7477 "%s: HDD context is not valid", __func__);
7478 *dbm = 0;
7479 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007480 }
7481
Jeff Johnson295189b2012-06-20 16:38:30 -07007482 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
7483 if (NULL == pAdapter)
7484 {
7485 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Not in station context " ,__func__);
7486 return -ENOENT;
7487 }
7488
7489 wlan_hdd_get_classAstats(pAdapter);
7490 *dbm = pAdapter->hdd_stats.ClassA_stat.max_pwr;
7491
Jeff Johnsone7245742012-09-05 17:12:55 -07007492 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07007493 return 0;
7494}
7495
7496static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
7497 u8* mac, struct station_info *sinfo)
7498{
7499 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
7500 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7501 int ssidlen = pHddStaCtx->conn_info.SSID.SSID.length;
c_hpothu44ff4e02014-05-08 00:13:57 +05307502 tANI_U32 rate_flags;
Jeff Johnson295189b2012-06-20 16:38:30 -07007503
7504 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
7505 hdd_config_t *pCfg = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -07007506
7507 tANI_U8 OperationalRates[CSR_DOT11_SUPPORTED_RATES_MAX];
7508 tANI_U32 ORLeng = CSR_DOT11_SUPPORTED_RATES_MAX;
7509 tANI_U8 ExtendedRates[CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX];
7510 tANI_U32 ERLeng = CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX;
7511 tANI_U8 MCSRates[SIZE_OF_BASIC_MCS_SET];
7512 tANI_U32 MCSLeng = SIZE_OF_BASIC_MCS_SET;
7513 tANI_U16 maxRate = 0;
7514 tANI_U16 myRate;
7515 tANI_U16 currentRate = 0;
7516 tANI_U8 maxSpeedMCS = 0;
7517 tANI_U8 maxMCSIdx = 0;
7518 tANI_U8 rateFlag = 1;
7519 tANI_U8 i, j, rssidx;
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07007520 tANI_U16 temp;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307521 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07007522
Leo Chang6f8870f2013-03-26 18:11:36 -07007523#ifdef WLAN_FEATURE_11AC
7524 tANI_U32 vht_mcs_map;
7525 eDataRate11ACMaxMcs vhtMaxMcs;
7526#endif /* WLAN_FEATURE_11AC */
7527
Jeff Johnsone7245742012-09-05 17:12:55 -07007528 ENTER();
7529
Jeff Johnson295189b2012-06-20 16:38:30 -07007530 if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) ||
7531 (0 == ssidlen))
7532 {
7533 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Not associated or"
7534 " Invalid ssidlen, %d", __func__, ssidlen);
7535 /*To keep GUI happy*/
7536 return 0;
7537 }
7538
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307539 status = wlan_hdd_validate_context(pHddCtx);
7540
7541 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007542 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307543 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7544 "%s: HDD context is not valid", __func__);
7545 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007546 }
7547
Jeff Johnson295189b2012-06-20 16:38:30 -07007548
Kiet Lam3b17fc82013-09-27 05:24:08 +05307549 wlan_hdd_get_rssi(pAdapter, &sinfo->signal);
7550 sinfo->filled |= STATION_INFO_SIGNAL;
7551
c_hpothu44ff4e02014-05-08 00:13:57 +05307552 if ((eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed) ||
7553 (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed &&
7554 sinfo->signal >= pCfg->linkSpeedRssiHigh))
7555 {
7556 rate_flags = pAdapter->maxRateFlags;
7557 }
7558 else
7559 {
7560 wlan_hdd_get_station_stats(pAdapter);
7561 rate_flags = pAdapter->hdd_stats.ClassA_stat.tx_rate_flags;
7562 }
7563
Jeff Johnson295189b2012-06-20 16:38:30 -07007564 //convert to the UI units of 100kbps
7565 myRate = pAdapter->hdd_stats.ClassA_stat.tx_rate * 5;
7566
7567#ifdef LINKSPEED_DEBUG_ENABLED
Leo Chang6f8870f2013-03-26 18:11:36 -07007568 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 -07007569 sinfo->signal,
7570 pCfg->reportMaxLinkSpeed,
7571 myRate,
7572 (int) pCfg->linkSpeedRssiHigh,
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07007573 (int) pCfg->linkSpeedRssiMid,
7574 (int) pCfg->linkSpeedRssiLow,
Leo Chang6f8870f2013-03-26 18:11:36 -07007575 (int) rate_flags,
7576 (int) pAdapter->hdd_stats.ClassA_stat.mcs_index);
Jeff Johnson295189b2012-06-20 16:38:30 -07007577#endif //LINKSPEED_DEBUG_ENABLED
7578
7579 if (eHDD_LINK_SPEED_REPORT_ACTUAL != pCfg->reportMaxLinkSpeed)
7580 {
7581 // we do not want to necessarily report the current speed
7582 if (eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed)
7583 {
7584 // report the max possible speed
7585 rssidx = 0;
7586 }
7587 else if (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed)
7588 {
7589 // report the max possible speed with RSSI scaling
7590 if (sinfo->signal >= pCfg->linkSpeedRssiHigh)
7591 {
7592 // report the max possible speed
7593 rssidx = 0;
7594 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07007595 else if (sinfo->signal >= pCfg->linkSpeedRssiMid)
Jeff Johnson295189b2012-06-20 16:38:30 -07007596 {
7597 // report middle speed
7598 rssidx = 1;
7599 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07007600 else if (sinfo->signal >= pCfg->linkSpeedRssiLow)
7601 {
7602 // report middle speed
7603 rssidx = 2;
7604 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007605 else
7606 {
7607 // report actual speed
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07007608 rssidx = 3;
Jeff Johnson295189b2012-06-20 16:38:30 -07007609 }
7610 }
7611 else
7612 {
7613 // unknown, treat as eHDD_LINK_SPEED_REPORT_MAX
7614 hddLog(VOS_TRACE_LEVEL_ERROR,
7615 "%s: Invalid value for reportMaxLinkSpeed: %u",
7616 __func__, pCfg->reportMaxLinkSpeed);
7617 rssidx = 0;
7618 }
7619
7620 maxRate = 0;
7621
7622 /* Get Basic Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +05307623 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_OPERATIONAL_RATE_SET,
7624 OperationalRates, &ORLeng))
7625 {
7626 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
7627 /*To keep GUI happy*/
7628 return 0;
7629 }
7630
Jeff Johnson295189b2012-06-20 16:38:30 -07007631 for (i = 0; i < ORLeng; i++)
7632 {
Jeff Johnsone7245742012-09-05 17:12:55 -07007633 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -07007634 {
7635 /* Validate Rate Set */
7636 if (supported_data_rate[j].beacon_rate_index == (OperationalRates[i] & 0x7F))
7637 {
7638 currentRate = supported_data_rate[j].supported_rate[rssidx];
7639 break;
7640 }
7641 }
7642 /* Update MAX rate */
7643 maxRate = (currentRate > maxRate)?currentRate:maxRate;
7644 }
7645
7646 /* Get Extended Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +05307647 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET,
7648 ExtendedRates, &ERLeng))
7649 {
7650 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
7651 /*To keep GUI happy*/
7652 return 0;
7653 }
7654
Jeff Johnson295189b2012-06-20 16:38:30 -07007655 for (i = 0; i < ERLeng; i++)
7656 {
Jeff Johnsone7245742012-09-05 17:12:55 -07007657 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -07007658 {
7659 if (supported_data_rate[j].beacon_rate_index == (ExtendedRates[i] & 0x7F))
7660 {
7661 currentRate = supported_data_rate[j].supported_rate[rssidx];
7662 break;
7663 }
7664 }
7665 /* Update MAX rate */
7666 maxRate = (currentRate > maxRate)?currentRate:maxRate;
7667 }
Kiet Lamb69f8dc2013-11-15 15:34:27 +05307668 /* Get MCS Rate Set --
Kaushik, Sushantdc304d82014-01-22 10:58:37 +05307669 Only if we are always reporting max speed (or)
Kiet Lamb69f8dc2013-11-15 15:34:27 +05307670 if we have good rssi */
Kaushik, Sushantdc304d82014-01-22 10:58:37 +05307671 if ((0 == rssidx) ||
Kiet Lamb69f8dc2013-11-15 15:34:27 +05307672 (eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed))
Jeff Johnson295189b2012-06-20 16:38:30 -07007673 {
Gopichand Nakkala05ab1322013-02-15 11:28:38 +05307674 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_CURRENT_MCS_SET,
7675 MCSRates, &MCSLeng))
7676 {
7677 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
7678 /*To keep GUI happy*/
7679 return 0;
7680 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007681 rateFlag = 0;
Leo Chang6f8870f2013-03-26 18:11:36 -07007682#ifdef WLAN_FEATURE_11AC
7683 /* VHT80 rate has seperate rate table */
Gopichand Nakkala4c705372013-04-24 13:20:33 +05307684 if (rate_flags & (eHAL_TX_RATE_VHT20|eHAL_TX_RATE_VHT40|eHAL_TX_RATE_VHT80))
Jeff Johnson295189b2012-06-20 16:38:30 -07007685 {
Leo Chang6f8870f2013-03-26 18:11:36 -07007686 ccmCfgGetInt(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_VHT_TX_MCS_MAP, &vht_mcs_map);
Gopichand Nakkala4c705372013-04-24 13:20:33 +05307687 vhtMaxMcs = (eDataRate11ACMaxMcs)(vht_mcs_map & DATA_RATE_11AC_MCS_MASK );
Leo Chang6f8870f2013-03-26 18:11:36 -07007688 if (rate_flags & eHAL_TX_RATE_SGI)
Jeff Johnson295189b2012-06-20 16:38:30 -07007689 {
Leo Chang6f8870f2013-03-26 18:11:36 -07007690 rateFlag |= 1;
Jeff Johnson295189b2012-06-20 16:38:30 -07007691 }
Leo Chang6f8870f2013-03-26 18:11:36 -07007692 if (DATA_RATE_11AC_MAX_MCS_7 == vhtMaxMcs)
Jeff Johnson295189b2012-06-20 16:38:30 -07007693 {
Leo Chang6f8870f2013-03-26 18:11:36 -07007694 maxMCSIdx = 7;
7695 }
7696 else if (DATA_RATE_11AC_MAX_MCS_8 == vhtMaxMcs)
7697 {
7698 maxMCSIdx = 8;
7699 }
7700 else if (DATA_RATE_11AC_MAX_MCS_9 == vhtMaxMcs)
7701 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +05307702 //VHT20 is supporting 0~8
7703 if (rate_flags & eHAL_TX_RATE_VHT20)
7704 maxMCSIdx = 8;
7705 else
7706 maxMCSIdx = 9;
Leo Chang6f8870f2013-03-26 18:11:36 -07007707 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +05307708
7709 if (rate_flags & eHAL_TX_RATE_VHT80)
7710 {
7711 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT80_rate[rateFlag];
7712 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT80_rate[rateFlag];
7713 }
7714 else if (rate_flags & eHAL_TX_RATE_VHT40)
7715 {
7716 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT40_rate[rateFlag];
7717 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT40_rate[rateFlag];
7718 }
7719 else if (rate_flags & eHAL_TX_RATE_VHT20)
7720 {
7721 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT20_rate[rateFlag];
7722 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT20_rate[rateFlag];
7723 }
7724
Leo Chang6f8870f2013-03-26 18:11:36 -07007725 maxSpeedMCS = 1;
7726 if (currentRate > maxRate)
7727 {
7728 maxRate = currentRate;
7729 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +05307730
Leo Chang6f8870f2013-03-26 18:11:36 -07007731 }
7732 else
7733#endif /* WLAN_FEATURE_11AC */
7734 {
7735 if (rate_flags & eHAL_TX_RATE_HT40)
7736 {
7737 rateFlag |= 1;
7738 }
7739 if (rate_flags & eHAL_TX_RATE_SGI)
7740 {
7741 rateFlag |= 2;
7742 }
7743
7744 for (i = 0; i < MCSLeng; i++)
7745 {
7746 temp = sizeof(supported_mcs_rate) / sizeof(supported_mcs_rate[0]);
7747 for (j = 0; j < temp; j++)
7748 {
7749 if (supported_mcs_rate[j].beacon_rate_index == MCSRates[i])
7750 {
7751 currentRate = supported_mcs_rate[j].supported_rate[rateFlag];
7752 break;
7753 }
7754 }
7755 if ((j < temp) && (currentRate > maxRate))
7756 {
7757 maxRate = currentRate;
7758 maxSpeedMCS = 1;
7759 maxMCSIdx = supported_mcs_rate[j].beacon_rate_index;
7760 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007761 }
7762 }
7763 }
7764
Gopichand Nakkala4c705372013-04-24 13:20:33 +05307765 else if (!(rate_flags & eHAL_TX_RATE_LEGACY))
7766 {
7767 maxRate = myRate;
7768 maxSpeedMCS = 1;
7769 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
7770 }
7771
Jeff Johnson295189b2012-06-20 16:38:30 -07007772 // make sure we report a value at least as big as our current rate
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07007773 if (((maxRate < myRate) && (0 == rssidx)) ||
7774 (0 == maxRate))
Jeff Johnson295189b2012-06-20 16:38:30 -07007775 {
7776 maxRate = myRate;
7777 if (rate_flags & eHAL_TX_RATE_LEGACY)
7778 {
7779 maxSpeedMCS = 0;
7780 }
7781 else
7782 {
7783 maxSpeedMCS = 1;
7784 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
7785 }
7786 }
7787
Gopichand Nakkala4c705372013-04-24 13:20:33 +05307788 if (rate_flags & eHAL_TX_RATE_LEGACY)
Jeff Johnson295189b2012-06-20 16:38:30 -07007789 {
7790 sinfo->txrate.legacy = maxRate;
7791#ifdef LINKSPEED_DEBUG_ENABLED
7792 pr_info("Reporting legacy rate %d\n", sinfo->txrate.legacy);
7793#endif //LINKSPEED_DEBUG_ENABLED
7794 }
7795 else
7796 {
7797 sinfo->txrate.mcs = maxMCSIdx;
Leo Chang6f8870f2013-03-26 18:11:36 -07007798#ifdef WLAN_FEATURE_11AC
7799 sinfo->txrate.nss = 1;
7800 if (rate_flags & eHAL_TX_RATE_VHT80)
7801 {
7802 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
Gopichand Nakkala4c705372013-04-24 13:20:33 +05307803 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
Leo Chang6f8870f2013-03-26 18:11:36 -07007804 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +05307805 else if (rate_flags & eHAL_TX_RATE_VHT40)
Leo Chang6f8870f2013-03-26 18:11:36 -07007806 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +05307807 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
7808 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
7809 }
7810 else if (rate_flags & eHAL_TX_RATE_VHT20)
7811 {
7812 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
7813 }
7814#endif /* WLAN_FEATURE_11AC */
7815 if (rate_flags & (eHAL_TX_RATE_HT20 | eHAL_TX_RATE_HT40))
7816 {
7817 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
7818 if (rate_flags & eHAL_TX_RATE_HT40)
7819 {
7820 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
7821 }
Leo Chang6f8870f2013-03-26 18:11:36 -07007822 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007823 if (rate_flags & eHAL_TX_RATE_SGI)
7824 {
7825 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
7826 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +05307827
Jeff Johnson295189b2012-06-20 16:38:30 -07007828#ifdef LINKSPEED_DEBUG_ENABLED
7829 pr_info("Reporting MCS rate %d flags %x\n",
7830 sinfo->txrate.mcs,
7831 sinfo->txrate.flags );
7832#endif //LINKSPEED_DEBUG_ENABLED
7833 }
7834 }
7835 else
7836 {
7837 // report current rate instead of max rate
7838
7839 if (rate_flags & eHAL_TX_RATE_LEGACY)
7840 {
7841 //provide to the UI in units of 100kbps
7842 sinfo->txrate.legacy = myRate;
7843#ifdef LINKSPEED_DEBUG_ENABLED
7844 pr_info("Reporting actual legacy rate %d\n", sinfo->txrate.legacy);
7845#endif //LINKSPEED_DEBUG_ENABLED
7846 }
7847 else
7848 {
7849 //must be MCS
7850 sinfo->txrate.mcs = pAdapter->hdd_stats.ClassA_stat.mcs_index;
Leo Chang6f8870f2013-03-26 18:11:36 -07007851#ifdef WLAN_FEATURE_11AC
7852 sinfo->txrate.nss = 1;
7853 if (rate_flags & eHAL_TX_RATE_VHT80)
7854 {
7855 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
7856 }
7857 else
7858#endif /* WLAN_FEATURE_11AC */
7859 {
7860 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
7861 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007862 if (rate_flags & eHAL_TX_RATE_SGI)
7863 {
7864 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
7865 }
7866 if (rate_flags & eHAL_TX_RATE_HT40)
7867 {
7868 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
7869 }
Leo Chang6f8870f2013-03-26 18:11:36 -07007870#ifdef WLAN_FEATURE_11AC
7871 else if (rate_flags & eHAL_TX_RATE_VHT80)
7872 {
7873 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
7874 }
7875#endif /* WLAN_FEATURE_11AC */
Jeff Johnson295189b2012-06-20 16:38:30 -07007876#ifdef LINKSPEED_DEBUG_ENABLED
7877 pr_info("Reporting actual MCS rate %d flags %x\n",
7878 sinfo->txrate.mcs,
7879 sinfo->txrate.flags );
7880#endif //LINKSPEED_DEBUG_ENABLED
7881 }
7882 }
7883 sinfo->filled |= STATION_INFO_TX_BITRATE;
7884
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -07007885 sinfo->tx_packets =
7886 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[0] +
7887 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[1] +
7888 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[2] +
7889 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[3];
7890
7891 sinfo->tx_retries =
7892 pAdapter->hdd_stats.summary_stat.retry_cnt[0] +
7893 pAdapter->hdd_stats.summary_stat.retry_cnt[1] +
7894 pAdapter->hdd_stats.summary_stat.retry_cnt[2] +
7895 pAdapter->hdd_stats.summary_stat.retry_cnt[3];
7896
7897 sinfo->tx_failed =
7898 pAdapter->hdd_stats.summary_stat.fail_cnt[0] +
7899 pAdapter->hdd_stats.summary_stat.fail_cnt[1] +
7900 pAdapter->hdd_stats.summary_stat.fail_cnt[2] +
7901 pAdapter->hdd_stats.summary_stat.fail_cnt[3];
7902
7903 sinfo->filled |=
7904 STATION_INFO_TX_PACKETS |
7905 STATION_INFO_TX_RETRIES |
7906 STATION_INFO_TX_FAILED;
7907
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307908 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7909 TRACE_CODE_HDD_CFG80211_GET_STA,
7910 pAdapter->sessionId, maxRate));
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -07007911 EXIT();
7912 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07007913}
7914
7915static int wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
Sameer Thalappilc9f26e92013-06-07 10:11:06 -07007916 struct net_device *dev, bool mode, int timeout)
Jeff Johnson295189b2012-06-20 16:38:30 -07007917{
7918 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +05307919 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07007920 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307921 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07007922
Jeff Johnsone7245742012-09-05 17:12:55 -07007923 ENTER();
7924
Jeff Johnson295189b2012-06-20 16:38:30 -07007925 if (NULL == pAdapter)
7926 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08007927 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007928 return -ENODEV;
7929 }
7930
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307931 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7932 TRACE_CODE_HDD_CFG80211_SET_POWER_MGMT,
7933 pAdapter->sessionId, timeout));
7934
Gopichand Nakkala20c4c042013-04-19 22:08:55 +05307935 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307936 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +05307937
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307938 if (0 != status)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307939 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307940 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7941 "%s: HDD context is not valid", __func__);
7942 return status;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307943 }
7944
Gopichand Nakkala20c4c042013-04-19 22:08:55 +05307945 if ((DRIVER_POWER_MODE_AUTO == !mode) &&
7946 (TRUE == pHddCtx->hdd_wlan_suspended) &&
7947 (pHddCtx->cfg_ini->fhostArpOffload) &&
7948 (eConnectionState_Associated ==
7949 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
7950 {
Amar Singhald53568e2013-09-26 11:03:45 -07007951
7952 hddLog(VOS_TRACE_LEVEL_INFO,
7953 "offload: in cfg80211_set_power_mgmt, calling arp offload");
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05307954 vos_status = hdd_conf_arp_offload(pAdapter, TRUE);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +05307955 if (!VOS_IS_STATUS_SUCCESS(vos_status))
7956 {
7957 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007958 "%s:Failed to enable ARPOFFLOAD Feature %d",
Gopichand Nakkala20c4c042013-04-19 22:08:55 +05307959 __func__, vos_status);
7960 }
7961 }
7962
Jeff Johnson295189b2012-06-20 16:38:30 -07007963 /**The get power cmd from the supplicant gets updated by the nl only
7964 *on successful execution of the function call
7965 *we are oppositely mapped w.r.t mode in the driver
7966 **/
7967 vos_status = wlan_hdd_enter_bmps(pAdapter, !mode);
7968
Jeff Johnsone7245742012-09-05 17:12:55 -07007969 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07007970 if (VOS_STATUS_E_FAILURE == vos_status)
7971 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307972 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7973 "%s: failed to enter bmps mode", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007974 return -EINVAL;
7975 }
7976 return 0;
7977}
7978
7979
7980#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
7981static int wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
7982 struct net_device *netdev,
7983 u8 key_index)
7984{
Jeff Johnsone7245742012-09-05 17:12:55 -07007985 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07007986 return 0;
7987}
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307988#endif //LINUX_VERSION_CODE
Jeff Johnson295189b2012-06-20 16:38:30 -07007989
7990#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
7991static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
7992 struct net_device *dev,
7993 struct ieee80211_txq_params *params)
7994{
Jeff Johnsone7245742012-09-05 17:12:55 -07007995 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07007996 return 0;
7997}
7998#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
7999static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
8000 struct ieee80211_txq_params *params)
8001{
Jeff Johnsone7245742012-09-05 17:12:55 -07008002 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07008003 return 0;
8004}
8005#endif //LINUX_VERSION_CODE
8006
8007static int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
8008 struct net_device *dev, u8 *mac)
8009{
8010 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308011 hdd_context_t *pHddCtx;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08008012 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308013 int status;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08008014 v_U8_t staId;
Jeff Johnson295189b2012-06-20 16:38:30 -07008015
Jeff Johnsone7245742012-09-05 17:12:55 -07008016 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308017
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308018 if ( NULL == pAdapter )
Jeff Johnson295189b2012-06-20 16:38:30 -07008019 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308020 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008021 return -EINVAL;
8022 }
8023
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308024 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
8025 TRACE_CODE_HDD_CFG80211_DEL_STA,
8026 pAdapter->sessionId, pAdapter->device_mode));
8027
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308028 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8029 status = wlan_hdd_validate_context(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07008030
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308031 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008032 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308033 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8034 "%s: HDD context is not valid", __func__);
8035 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008036 }
8037
Jeff Johnson295189b2012-06-20 16:38:30 -07008038 if ( (WLAN_HDD_SOFTAP == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -07008039 || (WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -07008040 )
8041 {
8042 if( NULL == mac )
8043 {
8044 v_U16_t i;
8045 for(i = 0; i < WLAN_MAX_STA_COUNT; i++)
8046 {
Rajesh Chauhan18488fc2013-08-22 10:15:03 -07008047 if ((pAdapter->aStaInfo[i].isUsed) &&
8048 (!pAdapter->aStaInfo[i].isDeauthInProgress))
Jeff Johnson295189b2012-06-20 16:38:30 -07008049 {
8050 u8 *macAddr = pAdapter->aStaInfo[i].macAddrSTA.bytes;
8051 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -08008052 "%s: Delete STA with MAC::"
8053 MAC_ADDRESS_STR,
8054 __func__, MAC_ADDR_ARRAY(macAddr));
Rajesh Chauhan18488fc2013-08-22 10:15:03 -07008055 vos_status = hdd_softap_sta_deauth(pAdapter, macAddr);
8056 if (VOS_IS_STATUS_SUCCESS(vos_status))
8057 pAdapter->aStaInfo[i].isDeauthInProgress = TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -07008058 }
8059 }
8060 }
8061 else
8062 {
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08008063
8064 vos_status = hdd_softap_GetStaId(pAdapter,(v_MACADDR_t *)mac, &staId);
8065 if (!VOS_IS_STATUS_SUCCESS(vos_status))
8066 {
8067 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -08008068 "%s: Skip this DEL STA as this is not used::"
8069 MAC_ADDRESS_STR,
8070 __func__, MAC_ADDR_ARRAY(mac));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08008071 return -ENOENT;
8072 }
8073
8074 if( pAdapter->aStaInfo[staId].isDeauthInProgress == TRUE)
8075 {
8076 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -08008077 "%s: Skip this DEL STA as deauth is in progress::"
8078 MAC_ADDRESS_STR,
8079 __func__, MAC_ADDR_ARRAY(mac));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08008080 return -ENOENT;
8081 }
8082
8083 pAdapter->aStaInfo[staId].isDeauthInProgress = TRUE;
8084
Jeff Johnson295189b2012-06-20 16:38:30 -07008085 hddLog(VOS_TRACE_LEVEL_INFO,
8086 "%s: Delete STA with MAC::"
Arif Hussain24bafea2013-11-15 15:10:03 -08008087 MAC_ADDRESS_STR,
Jeff Johnson295189b2012-06-20 16:38:30 -07008088 __func__,
Arif Hussain24bafea2013-11-15 15:10:03 -08008089 MAC_ADDR_ARRAY(mac));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08008090
8091 vos_status = hdd_softap_sta_deauth(pAdapter, mac);
8092 if (!VOS_IS_STATUS_SUCCESS(vos_status))
8093 {
8094 pAdapter->aStaInfo[staId].isDeauthInProgress = FALSE;
8095 hddLog(VOS_TRACE_LEVEL_INFO,
8096 "%s: STA removal failed for ::"
Arif Hussain24bafea2013-11-15 15:10:03 -08008097 MAC_ADDRESS_STR,
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08008098 __func__,
Arif Hussain24bafea2013-11-15 15:10:03 -08008099 MAC_ADDR_ARRAY(mac));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08008100 return -ENOENT;
8101 }
8102
Jeff Johnson295189b2012-06-20 16:38:30 -07008103 }
8104 }
8105
8106 EXIT();
8107
8108 return 0;
8109}
8110
Hoonki Lee11f7dda2013-02-14 16:55:44 -08008111static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
8112 struct net_device *dev, u8 *mac, struct station_parameters *params)
8113{
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308114 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkalab977a972013-02-18 19:15:09 -08008115 int status = -EPERM;
Hoonki Lee11f7dda2013-02-14 16:55:44 -08008116#ifdef FEATURE_WLAN_TDLS
8117 u32 mask, set;
Hoonki Lee11f7dda2013-02-14 16:55:44 -08008118 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308119
8120 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
8121 TRACE_CODE_HDD_CFG80211_ADD_STA,
8122 pAdapter->sessionId, params->listen_interval));
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008123 mask = params->sta_flags_mask;
8124
8125 set = params->sta_flags_set;
8126
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07008127#ifdef WLAN_FEATURE_TDLS_DEBUG
8128 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8129 "%s: mask 0x%x set 0x%x " MAC_ADDRESS_STR,
8130 __func__, mask, set, MAC_ADDR_ARRAY(mac));
8131#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008132
8133 if (mask & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
8134 if (set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008135 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 0, NULL);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008136 }
8137 }
8138#endif
Gopichand Nakkalab977a972013-02-18 19:15:09 -08008139 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -07008140}
8141
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008142
8143#ifdef FEATURE_WLAN_LFR
Wilson Yang6507c4e2013-10-01 20:11:19 -07008144#define MAX_PMKSAIDS_IN_CACHE 8
8145
8146static tPmkidCacheInfo PMKIDCache[MAX_PMKSAIDS_IN_CACHE]; // HDD local cache
8147static tANI_U32 PMKIDCacheIndex; // HDD local Cache index
8148
8149
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008150static int wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
Jeff Johnsond13512a2012-07-17 11:42:19 -07008151 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008152{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308153 tANI_U32 j=0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008154 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
8155 tHalHandle halHandle;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308156 eHalStatus result;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308157 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008158 tANI_U8 BSSIDMatched = 0;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308159 hdd_context_t *pHddCtx;
Jeff Johnson0299d0a2013-10-30 12:37:43 -07008160 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: set PMKSA for " MAC_ADDRESS_STR,
8161 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
Jeff Johnsone7245742012-09-05 17:12:55 -07008162
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308163 // Validate pAdapter
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308164 if ( NULL == pAdapter )
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008165 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308166 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008167 return -EINVAL;
8168 }
8169
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308170 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8171 status = wlan_hdd_validate_context(pHddCtx);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008172
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308173 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008174 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308175 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8176 "%s: HDD context is not valid", __func__);
8177 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008178 }
8179
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308180 // Retrieve halHandle
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008181 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
8182
Wilson Yang6507c4e2013-10-01 20:11:19 -07008183 for (j = 0; j < PMKIDCacheIndex; j++)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008184 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308185 if(vos_mem_compare(PMKIDCache[j].BSSID,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008186 pmksa->bssid, WNI_CFG_BSSID_LEN))
8187 {
8188 /* BSSID matched previous entry. Overwrite it. */
8189 BSSIDMatched = 1;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308190 vos_mem_copy(PMKIDCache[j].BSSID,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008191 pmksa->bssid, WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308192 vos_mem_copy(PMKIDCache[j].PMKID,
8193 pmksa->pmkid,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008194 CSR_RSN_PMKID_SIZE);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308195 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Reusing cache entry %d.",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008196 __func__, j );
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008197 dump_bssid(pmksa->bssid);
8198 dump_pmkid(halHandle, pmksa->pmkid);
8199 break;
8200 }
8201 }
8202
Madan Mohan Koyyalamudic4b317d2012-10-18 19:43:08 -07008203 /* Check we compared all entries,if then take the first slot now */
Wilson Yang6507c4e2013-10-01 20:11:19 -07008204 if(j == MAX_PMKSAIDS_IN_CACHE) PMKIDCacheIndex=0;
Madan Mohan Koyyalamudic4b317d2012-10-18 19:43:08 -07008205
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008206 if (!BSSIDMatched)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308207 {
8208 // Now, we DON'T have a BSSID match, so take a new entry in the cache.
Wilson Yang6507c4e2013-10-01 20:11:19 -07008209 vos_mem_copy(PMKIDCache[PMKIDCacheIndex].BSSID,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308210 pmksa->bssid, ETHER_ADDR_LEN);
Wilson Yang6507c4e2013-10-01 20:11:19 -07008211 vos_mem_copy(PMKIDCache[PMKIDCacheIndex].PMKID,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308212 pmksa->pmkid,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008213 CSR_RSN_PMKID_SIZE);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308214 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Adding a new cache entry %d.",
Wilson Yang6507c4e2013-10-01 20:11:19 -07008215 __func__, PMKIDCacheIndex );
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008216 dump_bssid(pmksa->bssid);
8217 dump_pmkid(halHandle, pmksa->pmkid);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308218 // Increment the HDD Local Cache index
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008219 // The "i=0" doesn't work for the call to sme_RoamSetPMKIDCache() - LFR FIXME
Wilson Yang6507c4e2013-10-01 20:11:19 -07008220 if (PMKIDCacheIndex <= (MAX_PMKSAIDS_IN_CACHE-1)) PMKIDCacheIndex++; else PMKIDCacheIndex = 0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008221 }
8222
8223
8224 // Calling csrRoamSetPMKIDCache to configure the PMKIDs into the cache
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308225 //hddLog(LOG1, FL("%s: Calling csrRoamSetPMKIDCache with %d cache entries."),
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008226 // __func__, i );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308227 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Calling csrRoamSetPMKIDCache with %d cache entries.",
Wilson Yang6507c4e2013-10-01 20:11:19 -07008228 __func__, PMKIDCacheIndex );
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008229 // Finally set the PMKSA ID Cache in CSR
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308230 result = sme_RoamSetPMKIDCache(halHandle,pAdapter->sessionId,
8231 PMKIDCache,
Wilson Yang6507c4e2013-10-01 20:11:19 -07008232 PMKIDCacheIndex);
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308233 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
8234 TRACE_CODE_HDD_CFG80211_SET_PMKSA,
8235 pAdapter->sessionId, result));
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008236 return 0;
8237}
8238
8239
Wilson Yang6507c4e2013-10-01 20:11:19 -07008240
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008241static int wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
Wilson Yang6507c4e2013-10-01 20:11:19 -07008242 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008243{
Wilson Yang6507c4e2013-10-01 20:11:19 -07008244 tANI_U32 j=0;
8245 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
8246 tHalHandle halHandle;
Wilson Yang6507c4e2013-10-01 20:11:19 -07008247 tANI_U8 BSSIDMatched = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -07008248 hdd_context_t *pHddCtx;
Wilson Yangef657d32014-01-15 19:19:23 -08008249 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -07008250
Jeff Johnson0299d0a2013-10-30 12:37:43 -07008251 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: deleting PMKSA for " MAC_ADDRESS_STR,
8252 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
Wilson Yang6507c4e2013-10-01 20:11:19 -07008253
8254 /* Validate pAdapter */
8255 if (NULL == pAdapter)
8256 {
8257 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
8258 return -EINVAL;
8259 }
8260
8261 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8262 status = wlan_hdd_validate_context(pHddCtx);
8263
8264 if (0 != status)
8265 {
8266 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8267 "%s: HDD context is not valid", __func__);
8268 return status;
8269 }
8270
8271 /*Retrieve halHandle*/
8272 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
8273
8274 /*in case index is 0,no entry to delete*/
8275 if (0 == PMKIDCacheIndex)
8276 {
8277 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid entry to delete" ,
8278 __func__);
8279 return -EINVAL;
8280 }
8281
8282 /*find the matching PMKSA entry from j=0 to (index-1),
8283 * and delete the matched one
8284 */
8285 for (j = 0; j<PMKIDCacheIndex; j++)
8286 {
8287 if (vos_mem_compare(PMKIDCache[j].BSSID,
8288 pmksa->bssid,
8289 WNI_CFG_BSSID_LEN))
8290 {
8291 /* BSSID matched entry */
8292 BSSIDMatched = 1;
8293
8294 if (j<PMKIDCacheIndex-1)
8295 {
8296 /*replace the matching entry with the last entry in HDD local cache*/
8297 vos_mem_copy(PMKIDCache[j].BSSID,
8298 PMKIDCache[PMKIDCacheIndex-1].BSSID,
8299 WNI_CFG_BSSID_LEN);
8300 vos_mem_copy(PMKIDCache[j].PMKID,
8301 PMKIDCache[PMKIDCacheIndex-1].PMKID,
8302 CSR_RSN_PMKID_SIZE);
8303 }
8304
8305 /*clear the last entry in HDD cache ---[index-1]*/
Wilson Yang6507c4e2013-10-01 20:11:19 -07008306 vos_mem_zero(PMKIDCache[PMKIDCacheIndex-1].BSSID, WNI_CFG_BSSID_LEN);
8307 vos_mem_zero(PMKIDCache[PMKIDCacheIndex-1].PMKID, CSR_RSN_PMKID_SIZE);
8308
8309 /*reduce the PMKID array index*/
8310 PMKIDCacheIndex--;
8311
8312 /*delete the last PMKID cache in CSR*/
Wilson Yangef657d32014-01-15 19:19:23 -08008313 if (eHAL_STATUS_SUCCESS !=
8314 sme_RoamDelPMKIDfromCache(halHandle, pAdapter->sessionId, pmksa->bssid))
Wilson Yang6507c4e2013-10-01 20:11:19 -07008315 {
8316 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: cannot delete PMKSA %d CONTENT.",
8317 __func__,PMKIDCacheIndex);
Wilson Yangef657d32014-01-15 19:19:23 -08008318 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -07008319 }
8320
8321 dump_bssid(pmksa->bssid);
8322 dump_pmkid(halHandle,pmksa->pmkid);
8323
8324 break;
8325 }
8326 }
8327
8328 /* we compare all entries,but cannot find matching entry */
8329 if (j == MAX_PMKSAIDS_IN_CACHE && !BSSIDMatched)
8330 {
Jeff Johnson0299d0a2013-10-30 12:37:43 -07008331 hddLog(VOS_TRACE_LEVEL_FATAL,
8332 "%s: No such PMKSA entry existed " MAC_ADDRESS_STR,
8333 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
Wilson Yang6507c4e2013-10-01 20:11:19 -07008334 dump_bssid(pmksa->bssid);
8335 dump_pmkid(halHandle, pmksa->pmkid);
8336 return -EINVAL;
8337 }
Wilson Yangef657d32014-01-15 19:19:23 -08008338 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008339}
8340
Wilson Yang6507c4e2013-10-01 20:11:19 -07008341
8342
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008343static int wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
8344{
Wilson Yang6507c4e2013-10-01 20:11:19 -07008345 tANI_U32 j=0;
8346 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
8347 tHalHandle halHandle;
8348 hdd_context_t *pHddCtx;
8349 tANI_U8 *pBSSId;
Wilson Yangef657d32014-01-15 19:19:23 -08008350 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -07008351
8352 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: flushing PMKSA ",__func__);
8353
8354 /* Validate pAdapter */
8355 if (NULL == pAdapter)
8356 {
8357 hddLog(VOS_TRACE_LEVEL_ERROR,
8358 "%s: Invalid Adapter" ,__func__);
8359 return -EINVAL;
8360 }
8361
8362 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8363 status = wlan_hdd_validate_context(pHddCtx);
8364
8365 if (0 != status)
8366 {
8367 hddLog(VOS_TRACE_LEVEL_ERROR,
8368 "%s: HDD context is not valid", __func__);
8369 return status;
8370 }
8371
8372 /*Retrieve halHandle*/
8373 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
8374
8375 /*in case index is 0,no entry to delete*/
8376 if (0 == PMKIDCacheIndex)
8377 {
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +05308378 hddLog(VOS_TRACE_LEVEL_ERROR, FL("No entries to flush"));
Wilson Yang6507c4e2013-10-01 20:11:19 -07008379 return -EINVAL;
8380 }
8381
8382 /*delete all the PMKSA one by one */
8383 for (j = 0; j<PMKIDCacheIndex; j++)
8384 {
Wilson Yang6507c4e2013-10-01 20:11:19 -07008385 pBSSId =(tANI_U8 *)(PMKIDCache[j].BSSID);
Wilson Yang6507c4e2013-10-01 20:11:19 -07008386
8387 /*delete the PMKID in CSR*/
Wilson Yangef657d32014-01-15 19:19:23 -08008388 if (eHAL_STATUS_SUCCESS !=
8389 sme_RoamDelPMKIDfromCache(halHandle, pAdapter->sessionId, pBSSId))
Wilson Yang6507c4e2013-10-01 20:11:19 -07008390 {
8391 hddLog(VOS_TRACE_LEVEL_ERROR ,"%s cannot flush PMKIDCache %d.",
8392 __func__,j);
Wilson Yangef657d32014-01-15 19:19:23 -08008393 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -07008394 }
Kiet Lam8d21d5b2013-10-31 17:18:29 +05308395 /*clear the entry in HDD cache 0--index-1 */
8396 vos_mem_zero(PMKIDCache[j].BSSID, WNI_CFG_BSSID_LEN);
8397 vos_mem_zero(PMKIDCache[j].PMKID, CSR_RSN_PMKID_SIZE);
Wilson Yang6507c4e2013-10-01 20:11:19 -07008398 }
8399
8400 PMKIDCacheIndex = 0;
Wilson Yangef657d32014-01-15 19:19:23 -08008401 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008402}
8403#endif
8404
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07008405#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308406static int wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07008407 struct net_device *dev, struct cfg80211_update_ft_ies_params *ftie)
8408{
8409 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
8410 hdd_station_ctx_t *pHddStaCtx;
8411
8412 if (NULL == pAdapter)
8413 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08008414 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07008415 return -ENODEV;
8416 }
8417
8418 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
8419
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308420 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
8421 TRACE_CODE_HDD_CFG80211_UPDATE_FT_IES,
8422 pAdapter->sessionId, pHddStaCtx->conn_info.connState));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07008423 // Added for debug on reception of Re-assoc Req.
8424 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
8425 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08008426 hddLog(LOGE, FL("Called with Ie of length = %zu when not associated"),
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07008427 ftie->ie_len);
Arif Hussain6d2a3322013-11-17 19:50:10 -08008428 hddLog(LOGE, FL("Should be Re-assoc Req IEs"));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07008429 }
8430
8431#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG
Arif Hussain6d2a3322013-11-17 19:50:10 -08008432 hddLog(LOGE, FL("%s called with Ie of length = %zu"), __func__,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07008433 ftie->ie_len);
8434#endif
8435
8436 // Pass the received FT IEs to SME
Gopichand Nakkala356fb102013-03-06 12:34:04 +05308437 sme_SetFTIEs( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
8438 (const u8 *)ftie->ie,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07008439 ftie->ie_len);
8440 return 0;
8441}
8442#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008443
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308444#ifdef FEATURE_WLAN_SCAN_PNO
8445
8446void hdd_cfg80211_sched_scan_done_callback(void *callbackContext,
8447 tSirPrefNetworkFoundInd *pPrefNetworkFoundInd)
8448{
8449 int ret;
8450 hdd_adapter_t* pAdapter = (hdd_adapter_t*)callbackContext;
8451 hdd_context_t *pHddCtx;
8452
Nirav Shah80830bf2013-12-31 16:35:12 +05308453 ENTER();
8454
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308455 if (NULL == pAdapter)
8456 {
Agarwal Ashish971c2882013-10-30 20:11:12 +05308457 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308458 "%s: HDD adapter is Null", __func__);
8459 return ;
8460 }
8461
8462 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8463 if (NULL == pHddCtx)
8464 {
8465 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8466 "%s: HDD context is Null!!!", __func__);
8467 return ;
8468 }
8469
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05308470 spin_lock(&pHddCtx->schedScan_lock);
8471 if (TRUE == pHddCtx->isWiphySuspended)
8472 {
8473 pHddCtx->isSchedScanUpdatePending = TRUE;
8474 spin_unlock(&pHddCtx->schedScan_lock);
8475 hddLog(VOS_TRACE_LEVEL_INFO,
8476 "%s: Update cfg80211 scan database after it resume", __func__);
8477 return ;
8478 }
8479 spin_unlock(&pHddCtx->schedScan_lock);
8480
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308481 ret = wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter);
8482
8483 if (0 > ret)
8484 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
8485
8486 cfg80211_sched_scan_results(pHddCtx->wiphy);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05308487 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8488 "%s: cfg80211 scan result database updated", __func__);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308489}
8490
8491/*
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +05308492 * FUNCTION: wlan_hdd_is_pno_allowed
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +05308493 * Disallow pno if any session is active
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +05308494 */
8495static eHalStatus wlan_hdd_is_pno_allowed(hdd_adapter_t *pAdapter)
8496{
8497 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
8498 hdd_adapter_t *pTempAdapter = NULL;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +05308499 hdd_station_ctx_t *pStaCtx;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +05308500 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8501 int status = 0;
8502 status = hdd_get_front_adapter(pHddCtx, &pAdapterNode);
8503
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +05308504 /* The current firmware design does not allow PNO during any
8505 * active sessions. Hence, determine the active sessions
8506 * and return a failure.
8507 */
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +05308508 while ((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status))
8509 {
8510 pTempAdapter = pAdapterNode->pAdapter;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +05308511 pStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pTempAdapter);
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +05308512
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +05308513 if (((WLAN_HDD_INFRA_STATION == pTempAdapter->device_mode)
8514 && (eConnectionState_NotConnected != pStaCtx->conn_info.connState))
8515 || (WLAN_HDD_P2P_CLIENT == pTempAdapter->device_mode)
8516 || (WLAN_HDD_P2P_GO == pTempAdapter->device_mode)
8517 || (WLAN_HDD_SOFTAP == pTempAdapter->device_mode)
8518 )
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +05308519 {
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +05308520 return eHAL_STATUS_FAILURE;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +05308521 }
8522 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
8523 pAdapterNode = pNext;
8524 }
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +05308525 return eHAL_STATUS_SUCCESS;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +05308526}
8527
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +05308528void hdd_cfg80211_sched_scan_start_status_cb(void *callbackContext, VOS_STATUS status)
8529{
8530 hdd_adapter_t *pAdapter = callbackContext;
8531 hdd_context_t *pHddCtx;
8532
8533 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
8534 {
8535 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8536 FL("Invalid adapter or adapter has invalid magic"));
8537 return;
8538 }
8539
8540 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8541 if (0 != wlan_hdd_validate_context(pHddCtx))
8542 {
8543 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8544 FL("HDD context is not valid"));
8545 return;
8546 }
8547
8548 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8549 FL("PNO enable response status = %d"), status);
8550
8551 pAdapter->pno_req_status = (status == VOS_STATUS_SUCCESS) ? 0 : -EBUSY;
8552 complete(&pAdapter->pno_comp_var);
8553}
8554
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +05308555/*
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308556 * FUNCTION: wlan_hdd_cfg80211_sched_scan_start
8557 * NL interface to enable PNO
8558 */
8559static int wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
8560 struct net_device *dev, struct cfg80211_sched_scan_request *request)
8561{
8562 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
8563 tpSirPNOScanReq pPnoRequest = NULL;
8564 hdd_context_t *pHddCtx;
8565 tHalHandle hHal;
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +05308566 v_U32_t i, indx, num_ch, tempInterval;
Sushant Kaushikd62d9782014-02-19 15:39:40 +05308567 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
8568 u8 channels_allowed[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308569 v_U32_t num_channels_allowed = WNI_CFG_VALID_CHANNEL_LIST_LEN;
8570 eHalStatus status = eHAL_STATUS_FAILURE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308571 int ret = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308572
8573 if (NULL == pAdapter)
8574 {
8575 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
8576 "%s: HDD adapter is Null", __func__);
8577 return -ENODEV;
8578 }
8579
8580 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05308581 ret = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308582
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05308583 if (0 != ret)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308584 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05308585 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8586 "%s: HDD context is not valid", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308587 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308588 }
8589
8590 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
8591 if (NULL == hHal)
8592 {
8593 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8594 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05308595 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308596 }
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +05308597
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +05308598 if (eHAL_STATUS_SUCCESS != wlan_hdd_is_pno_allowed(pAdapter))
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +05308599 {
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +05308600 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +05308601 FL("Cannot handle sched_scan"));
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +05308602 return -EBUSY;
8603 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308604
c_hpothu37f21312014-04-09 21:49:54 +05308605 if (TRUE == pHddCtx->isPnoEnable)
8606 {
8607 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
8608 FL("already PNO is enabled"));
8609 return -EBUSY;
8610 }
8611 pHddCtx->isPnoEnable = TRUE;
8612
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308613 pPnoRequest = (tpSirPNOScanReq) vos_mem_malloc(sizeof (tSirPNOScanReq));
8614 if (NULL == pPnoRequest)
8615 {
8616 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
8617 "%s: vos_mem_malloc failed", __func__);
c_hpothu37f21312014-04-09 21:49:54 +05308618 pHddCtx->isPnoEnable = FALSE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308619 return -ENOMEM;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308620 }
8621
Madan Mohan Koyyalamudic3f04352013-09-26 19:21:48 +05308622 memset(pPnoRequest, 0, sizeof (tSirPNOScanReq));
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308623 pPnoRequest->enable = 1; /*Enable PNO */
8624 pPnoRequest->ucNetworksCount = request->n_match_sets;
8625
8626 if (( !pPnoRequest->ucNetworksCount ) ||
8627 ( pPnoRequest->ucNetworksCount > SIR_PNO_MAX_SUPP_NETWORKS ))
8628 {
8629 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik1e406c32014-05-09 15:57:52 +05308630 "%s: Network input is not correct %d Max Network supported is %d",
8631 __func__, pPnoRequest->ucNetworksCount,
8632 SIR_PNO_MAX_SUPP_NETWORKS);
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308633 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308634 goto error;
8635 }
8636
8637 if ( SIR_PNO_MAX_NETW_CHANNELS_EX < request->n_channels )
8638 {
8639 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +05308640 "%s: Incorrect number of channels %d",
8641 __func__, request->n_channels);
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308642 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308643 goto error;
8644 }
8645
8646 /* Framework provides one set of channels(all)
8647 * common for all saved profile */
8648 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
8649 channels_allowed, &num_channels_allowed))
8650 {
8651 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8652 "%s: failed to get valid channel list", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308653 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308654 goto error;
8655 }
8656 /* Checking each channel against allowed channel list */
8657 num_ch = 0;
Nirav Shah80830bf2013-12-31 16:35:12 +05308658 if (request->n_channels)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308659 {
Nirav Shah80830bf2013-12-31 16:35:12 +05308660 char chList [(request->n_channels*5)+1];
8661 int len;
8662 for (i = 0, len = 0; i < request->n_channels; i++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308663 {
Nirav Shah80830bf2013-12-31 16:35:12 +05308664 for (indx = 0; indx < num_channels_allowed; indx++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308665 {
Nirav Shah80830bf2013-12-31 16:35:12 +05308666 if (request->channels[i]->hw_value == channels_allowed[indx])
8667 {
8668 valid_ch[num_ch++] = request->channels[i]->hw_value;
8669 len += snprintf(chList+len, 5, "%d ",
8670 request->channels[i]->hw_value);
8671 break ;
8672 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308673 }
8674 }
Nirav Shah80830bf2013-12-31 16:35:12 +05308675 hddLog(VOS_TRACE_LEVEL_INFO,"Channel-List: %s ", chList);
8676 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308677
8678 /* Filling per profile params */
8679 for (i = 0; i < pPnoRequest->ucNetworksCount; i++)
8680 {
8681 pPnoRequest->aNetworks[i].ssId.length =
8682 request->match_sets[i].ssid.ssid_len;
8683
8684 if (( 0 == pPnoRequest->aNetworks[i].ssId.length ) ||
8685 ( pPnoRequest->aNetworks[i].ssId.length > 32 ) )
8686 {
8687 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +05308688 "%s: SSID Len %d is not correct for network %d",
8689 __func__, pPnoRequest->aNetworks[i].ssId.length, i);
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308690 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308691 goto error;
8692 }
8693
8694 memcpy(pPnoRequest->aNetworks[i].ssId.ssId,
8695 request->match_sets[i].ssid.ssid,
8696 request->match_sets[i].ssid.ssid_len);
Sushant Kaushik1e406c32014-05-09 15:57:52 +05308697 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8698 "%s: SSID of network %d is %s ", __func__,
8699 i, pPnoRequest->aNetworks[i].ssId.ssId);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308700 pPnoRequest->aNetworks[i].authentication = 0; /*eAUTH_TYPE_ANY*/
8701 pPnoRequest->aNetworks[i].encryption = 0; /*eED_ANY*/
8702 pPnoRequest->aNetworks[i].bcastNetwType = 0; /*eBCAST_UNKNOWN*/
8703
8704 /*Copying list of valid channel into request */
8705 memcpy(pPnoRequest->aNetworks[i].aChannels, valid_ch, num_ch);
8706 pPnoRequest->aNetworks[i].ucChannelCount = num_ch;
8707
8708 pPnoRequest->aNetworks[i].rssiThreshold = 0; //Default value
8709 }
8710
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +05308711 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnson59a121e2013-11-30 09:46:08 -08008712 "request->ie_len = %zu", request->ie_len);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +05308713 if ((0 < request->ie_len) && (NULL != request->ie))
8714 {
8715 pPnoRequest->us24GProbeTemplateLen = request->ie_len;
8716 memcpy(&pPnoRequest->p24GProbeTemplate, request->ie,
8717 pPnoRequest->us24GProbeTemplateLen);
8718
8719 pPnoRequest->us5GProbeTemplateLen = request->ie_len;
8720 memcpy(&pPnoRequest->p5GProbeTemplate, request->ie,
8721 pPnoRequest->us5GProbeTemplateLen);
8722 }
8723
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +05308724 /* Driver gets only one time interval which is hardcoded in
8725 * supplicant for 10000ms. Taking power consumption into account 6 timers
8726 * will be used, Timervalue is increased exponentially i.e 10,20,40,
8727 * 80,160,320 secs. And number of scan cycle for each timer
8728 * is configurable through INI param gPNOScanTimerRepeatValue.
8729 * If it is set to 0 only one timer will be used and PNO scan cycle
8730 * will be repeated after each interval specified by supplicant
8731 * till PNO is disabled.
8732 */
8733 if (0 == pHddCtx->cfg_ini->configPNOScanTimerRepeatValue)
8734 pPnoRequest->scanTimers.ucScanTimersCount = HDD_PNO_SCAN_TIMERS_SET_ONE;
8735 else
8736 pPnoRequest->scanTimers.ucScanTimersCount =
8737 HDD_PNO_SCAN_TIMERS_SET_MULTIPLE;
8738
8739 tempInterval = (request->interval)/1000;
8740 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8741 "Base scan interval = %d PNOScanTimerRepeatValue = %d",
8742 tempInterval, pHddCtx->cfg_ini->configPNOScanTimerRepeatValue);
8743 for ( i = 0; i < pPnoRequest->scanTimers.ucScanTimersCount; i++)
8744 {
8745 pPnoRequest->scanTimers.aTimerValues[i].uTimerRepeat =
8746 pHddCtx->cfg_ini->configPNOScanTimerRepeatValue;
8747 pPnoRequest->scanTimers.aTimerValues[i].uTimerValue = tempInterval;
8748 tempInterval *= 2;
8749 }
8750 //Repeat last timer until pno disabled.
8751 pPnoRequest->scanTimers.aTimerValues[i-1].uTimerRepeat = 0;
8752
Madan Mohan Koyyalamudid206c7b2013-09-26 22:54:51 +05308753 pPnoRequest->modePNO = SIR_PNO_MODE_IMMEDIATE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308754
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +05308755 INIT_COMPLETION(pAdapter->pno_comp_var);
8756 pPnoRequest->statusCallback = hdd_cfg80211_sched_scan_start_status_cb;
8757 pPnoRequest->callbackContext = pAdapter;
8758 pAdapter->pno_req_status = 0;
8759
Nirav Shah80830bf2013-12-31 16:35:12 +05308760 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8761 "SessionId %d, enable %d, modePNO %d, ucScanTimersCount %d",
8762 pAdapter->sessionId, pPnoRequest->enable, pPnoRequest->modePNO,
8763 pPnoRequest->scanTimers.ucScanTimersCount);
8764
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308765 status = sme_SetPreferredNetworkList(WLAN_HDD_GET_HAL_CTX(pAdapter),
8766 pPnoRequest, pAdapter->sessionId,
8767 hdd_cfg80211_sched_scan_done_callback, pAdapter);
8768 if (eHAL_STATUS_SUCCESS != status)
8769 {
8770 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +05308771 "%s: Failed to enable PNO", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308772 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308773 goto error;
8774 }
8775
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +05308776 ret = wait_for_completion_timeout(
8777 &pAdapter->pno_comp_var,
8778 msecs_to_jiffies(WLAN_WAIT_TIME_PNO));
8779 if (0 >= ret)
8780 {
8781 // Did not receive the response for PNO enable in time.
8782 // Assuming the PNO enable was success.
8783 // Returning error from here, because we timeout, results
8784 // in side effect of Wifi (Wifi Setting) not to work.
8785 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8786 FL("Timed out waiting for PNO to be Enabled"));
8787 ret = 0;
8788 goto error;
8789 }
8790
8791 ret = pAdapter->pno_req_status;
c_hpothu37f21312014-04-09 21:49:54 +05308792 return ret;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05308793
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308794error:
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +05308795 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8796 FL("PNO scanRequest offloaded ret = %d"), ret);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308797 vos_mem_free(pPnoRequest);
c_hpothu37f21312014-04-09 21:49:54 +05308798 pHddCtx->isPnoEnable = FALSE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308799 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308800}
8801
8802/*
8803 * FUNCTION: wlan_hdd_cfg80211_sched_scan_stop
8804 * NL interface to disable PNO
8805 */
8806static int wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
8807 struct net_device *dev)
8808{
8809 eHalStatus status = eHAL_STATUS_FAILURE;
8810 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
8811 hdd_context_t *pHddCtx;
8812 tHalHandle hHal;
8813 tpSirPNOScanReq pPnoRequest = NULL;
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308814 int ret = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308815
8816 ENTER();
8817
8818 if (NULL == pAdapter)
8819 {
8820 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
8821 "%s: HDD adapter is Null", __func__);
8822 return -ENODEV;
8823 }
8824
8825 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308826
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308827 if (NULL == pHddCtx)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308828 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05308829 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308830 "%s: HDD context is Null", __func__);
8831 return -ENODEV;
8832 }
8833
8834 /* The return 0 is intentional when isLogpInProgress and
8835 * isLoadUnloadInProgress. We did observe a crash due to a return of
8836 * failure in sched_scan_stop , especially for a case where the unload
8837 * of the happens at the same time. The function __cfg80211_stop_sched_scan
8838 * was clearing rdev->sched_scan_req only when the sched_scan_stop returns
8839 * success. If it returns a failure , then its next invocation due to the
8840 * clean up of the second interface will have the dev pointer corresponding
8841 * to the first one leading to a crash.
8842 */
8843 if (pHddCtx->isLogpInProgress)
8844 {
8845 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8846 "%s: LOGP in Progress. Ignore!!!", __func__);
8847 return ret;
8848 }
8849
Mihir Shete18156292014-03-11 15:38:30 +05308850 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308851 {
8852 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8853 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
8854 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308855 }
8856
8857 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
8858 if (NULL == hHal)
8859 {
8860 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8861 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05308862 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308863 }
8864
8865 pPnoRequest = (tpSirPNOScanReq) vos_mem_malloc(sizeof (tSirPNOScanReq));
8866 if (NULL == pPnoRequest)
8867 {
8868 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
8869 "%s: vos_mem_malloc failed", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308870 return -ENOMEM;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308871 }
8872
8873 memset(pPnoRequest, 0, sizeof (tSirPNOScanReq));
8874 pPnoRequest->enable = 0; /* Disable PNO */
8875 pPnoRequest->ucNetworksCount = 0;
8876
8877 status = sme_SetPreferredNetworkList(hHal, pPnoRequest,
8878 pAdapter->sessionId,
8879 NULL, pAdapter);
8880 if (eHAL_STATUS_SUCCESS != status)
8881 {
8882 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8883 "Failed to disabled PNO");
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308884 ret = -EINVAL;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +05308885 goto error;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308886 }
c_hpothu37f21312014-04-09 21:49:54 +05308887 pHddCtx->isPnoEnable = FALSE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308888
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +05308889error:
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05308890 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +05308891 FL("PNO scan disabled ret = %d"), ret);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308892 vos_mem_free(pPnoRequest);
8893
8894 EXIT();
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308895 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308896}
8897
8898#endif /*FEATURE_WLAN_SCAN_PNO*/
8899
8900
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008901#ifdef FEATURE_WLAN_TDLS
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +05308902#if TDLS_MGMT_VERSION2
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008903static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
8904 u8 *peer, u8 action_code, u8 dialog_token,
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +05308905 u16 status_code, u32 peer_capability, const u8 *buf, size_t len)
8906#else
8907static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
8908 u8 *peer, u8 action_code, u8 dialog_token,
8909 u16 status_code, const u8 *buf, size_t len)
8910#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008911{
8912
8913 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
8914 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008915 u8 peerMac[6];
8916 VOS_STATUS status;
Gopichand Nakkala05922802013-03-14 12:23:19 -07008917 int max_sta_failed = 0;
Hoonki Leea34dd892013-02-05 22:56:02 -08008918 int responder;
Hoonki Leed37cbb32013-04-20 00:31:14 -07008919 long rc;
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +05308920#if !(TDLS_MGMT_VERSION2)
8921 u32 peer_capability = 0;
8922#endif
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05308923 tANI_U16 numCurrTdlsPeers;
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008924
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308925 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
8926 TRACE_CODE_HDD_CFG80211_TDLS_MGMT,
8927 pAdapter->sessionId, action_code));
Hoonki Lee11f7dda2013-02-14 16:55:44 -08008928 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008929 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308930 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008931 "Invalid arguments");
8932 return -EINVAL;
8933 }
8934
Sameer Thalappil75ea31a2013-02-21 19:38:16 -08008935 if (pHddCtx->isLogpInProgress)
8936 {
8937 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8938 "%s:LOGP in Progress. Ignore!!!", __func__);
Gopichand Nakkala05922802013-03-14 12:23:19 -07008939 wlan_hdd_tdls_set_link_status(pAdapter, peer, eTDLS_LINK_IDLE);
Sameer Thalappil75ea31a2013-02-21 19:38:16 -08008940 return -EBUSY;
8941 }
8942
Hoonki Lee27511902013-03-14 18:19:06 -07008943 if (eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode)
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008944 {
Hoonki Lee27511902013-03-14 18:19:06 -07008945 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
8946 "%s: TDLS mode is disabled OR not enabled in FW."
8947 MAC_ADDRESS_STR " action %d declined.",
8948 __func__, MAC_ADDR_ARRAY(peer), action_code);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008949 return -ENOTSUPP;
8950 }
Lee Hoonkic1262f22013-01-24 21:59:00 -08008951
Hoonki Lee27511902013-03-14 18:19:06 -07008952 /* other than teardown frame, other mgmt frames are not sent if disabled */
8953 if (SIR_MAC_TDLS_TEARDOWN != action_code)
8954 {
8955 /* if tdls_mode is disabled to respond to peer's request */
8956 if (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode)
8957 {
8958 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
8959 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07008960 " TDLS mode is disabled. action %d declined.",
8961 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee27511902013-03-14 18:19:06 -07008962
8963 return -ENOTSUPP;
8964 }
8965 }
8966
Gopichand Nakkalab977a972013-02-18 19:15:09 -08008967 if (WLAN_IS_TDLS_SETUP_ACTION(action_code))
8968 {
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308969 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, peer, TRUE))
Gopichand Nakkalab977a972013-02-18 19:15:09 -08008970 {
8971 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07008972 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07008973 " TDLS setup is ongoing. action %d declined.",
8974 __func__, MAC_ADDR_ARRAY(peer), action_code);
8975 return -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -08008976 }
8977 }
8978
Hoonki Lee11f7dda2013-02-14 16:55:44 -08008979 if (SIR_MAC_TDLS_SETUP_REQ == action_code ||
8980 SIR_MAC_TDLS_SETUP_RSP == action_code )
Lee Hoonkic1262f22013-01-24 21:59:00 -08008981 {
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05308982 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
8983 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Lee Hoonkic1262f22013-01-24 21:59:00 -08008984 {
8985 /* supplicant still sends tdls_mgmt(SETUP_REQ) even after
8986 we return error code at 'add_station()'. Hence we have this
8987 check again in addtion to add_station().
8988 Anyway, there is no hard to double-check. */
Hoonki Lee11f7dda2013-02-14 16:55:44 -08008989 if (SIR_MAC_TDLS_SETUP_REQ == action_code)
Lee Hoonkic1262f22013-01-24 21:59:00 -08008990 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07008991 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8992 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05308993 " TDLS Max peer already connected. action (%d) declined. Num of peers (%d), Max allowed (%d).",
8994 __func__, MAC_ADDR_ARRAY(peer), action_code,
8995 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Sunil Dutt388ac8f2013-11-28 18:06:52 +05308996 return -EINVAL;
Lee Hoonkic1262f22013-01-24 21:59:00 -08008997 }
8998 else
8999 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -08009000 /* maximum reached. tweak to send error code to peer and return
9001 error code to supplicant */
Lee Hoonkic1262f22013-01-24 21:59:00 -08009002 status_code = eSIR_MAC_UNSPEC_FAILURE_STATUS;
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07009003 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9004 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05309005 " TDLS Max peer already connected, send response status (%d). Num of peers (%d), Max allowed (%d).",
9006 __func__, MAC_ADDR_ARRAY(peer), status_code,
9007 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -07009008 max_sta_failed = -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -08009009 /* fall through to send setup resp with failure status
9010 code */
Lee Hoonkic1262f22013-01-24 21:59:00 -08009011 }
9012 }
Hoonki Lee11f7dda2013-02-14 16:55:44 -08009013 else
9014 {
9015 hddTdlsPeer_t *pTdlsPeer;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05309016 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009017 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Hoonki Lee11f7dda2013-02-14 16:55:44 -08009018 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07009019 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07009020 "%s:" MAC_ADDRESS_STR " already connected. action %d declined.",
9021 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee11f7dda2013-02-14 16:55:44 -08009022 return -EPERM;
9023 }
9024 }
Lee Hoonkic1262f22013-01-24 21:59:00 -08009025 }
Hoonki Lee11f7dda2013-02-14 16:55:44 -08009026 vos_mem_copy(peerMac, peer, 6);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009027
Hoonki Lee1090c6a2013-01-16 17:40:54 -08009028#ifdef WLAN_FEATURE_TDLS_DEBUG
9029 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +05309030 "%s: " MAC_ADDRESS_STR " action %d, dialog_token %d status %d, len = %zu",
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07009031 "tdls_mgmt", MAC_ADDR_ARRAY(peer),
9032 action_code, dialog_token, status_code, len);
Hoonki Lee1090c6a2013-01-16 17:40:54 -08009033#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009034
Hoonki Leea34dd892013-02-05 22:56:02 -08009035 /*Except teardown responder will not be used so just make 0*/
9036 responder = 0;
Hoonki Lee11f7dda2013-02-14 16:55:44 -08009037 if (SIR_MAC_TDLS_TEARDOWN == action_code)
Hoonki Leea34dd892013-02-05 22:56:02 -08009038 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -07009039
9040 hddTdlsPeer_t *pTdlsPeer;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05309041 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peerMac, TRUE);
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -07009042
9043 if(pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
9044 responder = pTdlsPeer->is_responder;
9045 else
Hoonki Leea34dd892013-02-05 22:56:02 -08009046 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -07009047 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +05309048 "%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 -07009049 __func__, MAC_ADDR_ARRAY(peer), (NULL == pTdlsPeer) ? -1 : pTdlsPeer->link_status,
9050 dialog_token, status_code, len);
9051 return -EPERM;
Hoonki Leea34dd892013-02-05 22:56:02 -08009052 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009053 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009054
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +05309055 /* For explicit trigger of DIS_REQ come out of BMPS for
9056 successfully receiving DIS_RSP from peer. */
Hoonki Lee14621352013-04-16 17:51:19 -07009057 if ((SIR_MAC_TDLS_SETUP_RSP == action_code) ||
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +05309058 (SIR_MAC_TDLS_DIS_RSP == action_code) ||
9059 (SIR_MAC_TDLS_DIS_REQ == action_code))
Hoonki Lee14621352013-04-16 17:51:19 -07009060 {
9061 if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter)))
9062 {
9063 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +05309064 "%s: Sending frame action_code %u.Disable BMPS", __func__, action_code);
Hoonki Lee14621352013-04-16 17:51:19 -07009065 hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
9066 }
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +05309067 if (SIR_MAC_TDLS_DIS_REQ != action_code)
9068 wlan_hdd_tdls_set_cap(pAdapter, peerMac, eTDLS_CAP_SUPPORTED);
Hoonki Lee14621352013-04-16 17:51:19 -07009069 }
9070
Hoonki Lee5305c3a2013-04-29 23:28:59 -07009071 /* make sure doesn't call send_mgmt() while it is pending */
9072 if (TDLS_CTX_MAGIC == pAdapter->mgmtTxCompletionStatus)
9073 {
9074 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009075 "%s: " MAC_ADDRESS_STR " action %d couldn't sent, as one is pending. return EBUSY",
Hoonki Lee5305c3a2013-04-29 23:28:59 -07009076 __func__, MAC_ADDR_ARRAY(peer), action_code);
9077 return -EBUSY;
9078 }
9079
9080 pAdapter->mgmtTxCompletionStatus = TDLS_CTX_MAGIC;
Gopichand Nakkalab977a972013-02-18 19:15:09 -08009081 INIT_COMPLETION(pAdapter->tdls_mgmt_comp);
9082
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009083 status = sme_SendTdlsMgmtFrame(WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
Pradeep Reddy POTTETIca171f82014-03-21 14:17:35 +05309084 peerMac, action_code, dialog_token, status_code, peer_capability, (tANI_U8 *)buf, len, responder);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009085
Gopichand Nakkalab977a972013-02-18 19:15:09 -08009086 if (VOS_STATUS_SUCCESS != status)
9087 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009088 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9089 "%s: sme_SendTdlsMgmtFrame failed!", __func__);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07009090 pAdapter->mgmtTxCompletionStatus = FALSE;
Hoonki Lee14621352013-04-16 17:51:19 -07009091 wlan_hdd_tdls_check_bmps(pAdapter);
Sunil Dutt388ac8f2013-11-28 18:06:52 +05309092 return -EINVAL;
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009093 }
9094
Hoonki Leed37cbb32013-04-20 00:31:14 -07009095 rc = wait_for_completion_interruptible_timeout(&pAdapter->tdls_mgmt_comp,
9096 msecs_to_jiffies(WAIT_TIME_TDLS_MGMT));
9097
9098 if ((rc <= 0) || (TRUE != pAdapter->mgmtTxCompletionStatus))
Gopichand Nakkalab977a972013-02-18 19:15:09 -08009099 {
Hoonki Leed37cbb32013-04-20 00:31:14 -07009100 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07009101 "%s: Mgmt Tx Completion failed status %ld TxCompletion %u",
Hoonki Leed37cbb32013-04-20 00:31:14 -07009102 __func__, rc, pAdapter->mgmtTxCompletionStatus);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07009103 pAdapter->mgmtTxCompletionStatus = FALSE;
Yue Ma4f55ef32014-01-23 16:45:33 -08009104
9105 if (pHddCtx->isLogpInProgress)
9106 {
9107 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9108 "%s: LOGP in Progress. Ignore!!!", __func__);
9109 return -EAGAIN;
9110 }
9111
Hoonki Leed37cbb32013-04-20 00:31:14 -07009112 wlan_hdd_tdls_check_bmps(pAdapter);
Sunil Dutt388ac8f2013-11-28 18:06:52 +05309113 return -EINVAL;
Gopichand Nakkalab977a972013-02-18 19:15:09 -08009114 }
9115
Gopichand Nakkala05922802013-03-14 12:23:19 -07009116 if (max_sta_failed)
Hoonki Lee14621352013-04-16 17:51:19 -07009117 {
9118 wlan_hdd_tdls_check_bmps(pAdapter);
Gopichand Nakkala05922802013-03-14 12:23:19 -07009119 return max_sta_failed;
Hoonki Lee14621352013-04-16 17:51:19 -07009120 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -08009121
Hoonki Leea34dd892013-02-05 22:56:02 -08009122 if (SIR_MAC_TDLS_SETUP_RSP == action_code)
9123 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -08009124 wlan_hdd_tdls_set_responder(pAdapter, peerMac, TRUE);
Hoonki Leea34dd892013-02-05 22:56:02 -08009125 }
9126 else if (SIR_MAC_TDLS_SETUP_CNF == action_code)
9127 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -08009128 wlan_hdd_tdls_set_responder(pAdapter, peerMac, FALSE);
Hoonki Leea34dd892013-02-05 22:56:02 -08009129 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009130
9131 return 0;
9132}
9133
9134static int wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
9135 u8 *peer, enum nl80211_tdls_operation oper)
9136{
9137 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
9138 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309139 int status;
Hoonki Lee5305c3a2013-04-29 23:28:59 -07009140 hddTdlsPeer_t *pTdlsPeer;
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009141
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309142 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
9143 TRACE_CODE_HDD_CFG80211_TDLS_OPER,
9144 pAdapter->sessionId, oper));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309145 if ( NULL == peer )
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009146 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -08009147 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chilam Ngc4244af2013-04-01 15:37:32 -07009148 "%s: Invalid arguments", __func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009149 return -EINVAL;
9150 }
Hoonki Lee1090c6a2013-01-16 17:40:54 -08009151
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309152 status = wlan_hdd_validate_context(pHddCtx);
9153
9154 if (0 != status)
Sameer Thalappil75ea31a2013-02-21 19:38:16 -08009155 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309156 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9157 "%s: HDD context is not valid", __func__);
9158 return status;
Sameer Thalappil75ea31a2013-02-21 19:38:16 -08009159 }
9160
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009161
9162 if( FALSE == pHddCtx->cfg_ini->fEnableTDLSSupport ||
Hoonki Lee1090c6a2013-01-16 17:40:54 -08009163 FALSE == sme_IsFeatureSupportedByFW(TDLS))
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009164 {
Hoonki Lee1090c6a2013-01-16 17:40:54 -08009165 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chilam Ngc4244af2013-04-01 15:37:32 -07009166 "TDLS Disabled in INI OR not enabled in FW. "
9167 "Cannot process TDLS commands");
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009168 return -ENOTSUPP;
9169 }
9170
9171 switch (oper) {
9172 case NL80211_TDLS_ENABLE_LINK:
9173 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009174 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309175 long ret;
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05309176 tCsrTdlsLinkEstablishParams tdlsLinkEstablishParams;
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009177
Sunil Dutt41de4e22013-11-14 18:09:02 +05309178 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
9179
9180 if ( NULL == pTdlsPeer ) {
9181 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
9182 " (oper %d) not exsting. ignored",
9183 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
9184 return -EINVAL;
9185 }
9186
9187 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9188 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
9189 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
9190 "NL80211_TDLS_ENABLE_LINK");
9191
Gopichand Nakkala2f4a2822013-04-17 11:22:01 -07009192 if (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
9193 {
9194 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Staion Index %u "
9195 MAC_ADDRESS_STR " failed",
9196 __func__, pTdlsPeer->staId, MAC_ADDR_ARRAY(peer));
9197 return -EINVAL;
9198 }
9199
Hoonki Lee5305c3a2013-04-29 23:28:59 -07009200 if (eTDLS_LINK_CONNECTED != pTdlsPeer->link_status)
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07009201 {
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +05309202 if (IS_ADVANCE_TDLS_ENABLE) {
Gopichand Nakkala24be5312013-07-02 16:47:12 +05309203
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +05309204 if (0 != wlan_hdd_tdls_get_link_establish_params(
9205 pAdapter, peer,&tdlsLinkEstablishParams)) {
9206 return -EINVAL;
9207 }
9208 INIT_COMPLETION(pAdapter->tdls_link_establish_req_comp);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05309209
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +05309210 sme_SendTdlsLinkEstablishParams(WLAN_HDD_GET_HAL_CTX(pAdapter),
9211 pAdapter->sessionId, peer, &tdlsLinkEstablishParams);
9212 /* Send TDLS peer UAPSD capabilities to the firmware and
9213 * register with the TL on after the response for this operation
9214 * is received .
9215 */
9216 ret = wait_for_completion_interruptible_timeout(
9217 &pAdapter->tdls_link_establish_req_comp,
9218 msecs_to_jiffies(WAIT_TIME_TDLS_LINK_ESTABLISH_REQ));
9219 if (ret <= 0)
9220 {
9221 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9222 "%s: Link Establish Request Faled Status %ld",
9223 __func__, ret);
9224 return -EINVAL;
9225 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05309226 }
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -07009227 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer, eTDLS_LINK_CONNECTED);
Gopichand Nakkala471708b2013-06-04 20:03:01 +05309228 /* Mark TDLS client Authenticated .*/
9229 status = WLANTL_ChangeSTAState( pHddCtx->pvosContext,
9230 pTdlsPeer->staId,
9231 WLANTL_STA_AUTHENTICATED);
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -07009232 if (VOS_STATUS_SUCCESS == status)
9233 {
Hoonki Lee14621352013-04-16 17:51:19 -07009234 if (pTdlsPeer->is_responder == 0)
9235 {
9236 v_U8_t staId = (v_U8_t)pTdlsPeer->staId;
9237
9238 wlan_hdd_tdls_timer_restart(pAdapter,
9239 &pTdlsPeer->initiatorWaitTimeoutTimer,
9240 WAIT_TIME_TDLS_INITIATOR);
9241 /* suspend initiator TX until it receives direct packet from the
9242 reponder or WAIT_TIME_TDLS_INITIATOR timer expires */
9243 WLANTL_SuspendDataTx( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
9244 &staId, NULL);
9245 }
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -07009246 wlan_hdd_tdls_increment_peer_count(pAdapter);
9247 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07009248 wlan_hdd_tdls_check_bmps(pAdapter);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05309249
9250 /* Update TL about the UAPSD masks , to route the packets to firmware */
Gopichand Nakkala574f6d12013-06-27 19:38:43 +05309251 if ((TRUE == pHddCtx->cfg_ini->fEnableTDLSBufferSta)
9252 || pHddCtx->cfg_ini->fTDLSUapsdMask )
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05309253 {
Gopichand Nakkala574f6d12013-06-27 19:38:43 +05309254 int ac;
9255 uint8 ucAc[4] = { WLANTL_AC_VO,
9256 WLANTL_AC_VI,
9257 WLANTL_AC_BK,
9258 WLANTL_AC_BE };
9259 uint8 tlTid[4] = { 7, 5, 2, 3 } ;
9260 for(ac=0; ac < 4; ac++)
9261 {
9262 status = WLANTL_EnableUAPSDForAC( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
9263 pTdlsPeer->staId, ucAc[ac],
9264 tlTid[ac], tlTid[ac], 0, 0,
9265 WLANTL_BI_DIR );
9266 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05309267 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07009268 }
9269
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009270 }
9271 break;
9272 case NL80211_TDLS_DISABLE_LINK:
Lee Hoonkic1262f22013-01-24 21:59:00 -08009273 {
Sunil Dutt41de4e22013-11-14 18:09:02 +05309274 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
9275
9276 if ( NULL == pTdlsPeer ) {
9277 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
9278 " (oper %d) not exsting. ignored",
9279 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
9280 return -EINVAL;
9281 }
9282
9283 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9284 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
9285 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
9286 "NL80211_TDLS_DISABLE_LINK");
9287
Hoonki Lee5305c3a2013-04-29 23:28:59 -07009288 if(TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
Lee Hoonkic1262f22013-01-24 21:59:00 -08009289 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009290 long status;
9291
9292 INIT_COMPLETION(pAdapter->tdls_del_station_comp);
9293
Lee Hoonkic1262f22013-01-24 21:59:00 -08009294 sme_DeleteTdlsPeerSta( WLAN_HDD_GET_HAL_CTX(pAdapter),
9295 pAdapter->sessionId, peer );
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009296
9297 status = wait_for_completion_interruptible_timeout(&pAdapter->tdls_del_station_comp,
9298 msecs_to_jiffies(WAIT_TIME_TDLS_DEL_STA));
9299 if (status <= 0)
9300 {
Hoonki Lee5305c3a2013-04-29 23:28:59 -07009301 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer, eTDLS_LINK_IDLE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009302 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9303 "%s: Del station failed status %ld",
9304 __func__, status);
9305 return -EPERM;
9306 }
Hoonki Lee5305c3a2013-04-29 23:28:59 -07009307 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer, eTDLS_LINK_IDLE);
Lee Hoonkic1262f22013-01-24 21:59:00 -08009308 }
9309 else
9310 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07009311 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9312 "%s: TDLS Peer Station doesn't exist.", __func__);
Lee Hoonkic1262f22013-01-24 21:59:00 -08009313 }
Lee Hoonkic1262f22013-01-24 21:59:00 -08009314 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07009315 break;
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009316 case NL80211_TDLS_TEARDOWN:
Sunil Dutt41de4e22013-11-14 18:09:02 +05309317 {
9318 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9319 " %s : NL80211_TDLS_TEARDOWN for " MAC_ADDRESS_STR,
9320 __func__, MAC_ADDR_ARRAY(peer));
9321
9322 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
9323 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
9324
9325 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9326 " %s TDLS External control and Implicit Trigger not enabled ",
9327 __func__);
9328 return -ENOTSUPP;
9329 }
9330
Sunil Dutt41de4e22013-11-14 18:09:02 +05309331
9332 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
9333
9334 if ( NULL == pTdlsPeer ) {
9335 hddLog(VOS_TRACE_LEVEL_INFO, "%s: " MAC_ADDRESS_STR
9336 " peer not exsting",
9337 __func__, MAC_ADDR_ARRAY(peer));
Naresh Jayaram937abdf2013-11-26 19:50:25 +05309338 return -EINVAL;
Sunil Dutt41de4e22013-11-14 18:09:02 +05309339 }
9340 else {
9341 wlan_hdd_tdls_indicate_teardown(pAdapter, pTdlsPeer,
9342 eSIR_MAC_TDLS_TEARDOWN_UNSPEC_REASON);
9343 }
Naresh Jayaram937abdf2013-11-26 19:50:25 +05309344
9345 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, FALSE) )
9346 return -EINVAL;
Sunil Dutt41de4e22013-11-14 18:09:02 +05309347 break;
9348 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009349 case NL80211_TDLS_SETUP:
Sunil Dutt41de4e22013-11-14 18:09:02 +05309350 {
Naresh Jayaramdb4514b2013-11-25 18:08:10 +05309351 hddTdlsPeer_t *pTdlsPeer;
Sunil Dutt41de4e22013-11-14 18:09:02 +05309352 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9353 " %s : NL80211_TDLS_SETUP for " MAC_ADDRESS_STR,
9354 __func__, MAC_ADDR_ARRAY(peer));
9355
9356 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
9357 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
9358
9359 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9360 " %s TDLS External control and Implicit Trigger not enabled ",
9361 __func__);
9362 return -ENOTSUPP;
9363 }
9364
Naresh Jayaramdb4514b2013-11-25 18:08:10 +05309365 /* To cater the requirement of establishing the TDLS link
9366 * irrespective of the data traffic , get an entry of TDLS peer.
9367 */
9368 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, peer);
9369 if (pTdlsPeer == NULL) {
9370 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9371 "%s: peer " MAC_ADDRESS_STR " not existing",
9372 __func__, MAC_ADDR_ARRAY(peer));
9373 return -EINVAL;
9374 }
Naresh Jayaram937abdf2013-11-26 19:50:25 +05309375
9376 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, TRUE) ) {
9377
9378 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9379 " %s TDLS Add Force Peer Failed",
9380 __func__);
9381 return -EINVAL;
9382 }
Naresh Jayaramdb4514b2013-11-25 18:08:10 +05309383 break;
Sunil Dutt41de4e22013-11-14 18:09:02 +05309384 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009385 case NL80211_TDLS_DISCOVERY_REQ:
9386 /* We don't support in-driver setup/teardown/discovery */
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309387 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
9388 "%s: We don't support in-driver setup/teardown/discovery "
9389 ,__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009390 return -ENOTSUPP;
9391 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309392 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9393 "%s: unsupported event",__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009394 return -ENOTSUPP;
9395 }
9396 return 0;
9397}
Chilam NG571c65a2013-01-19 12:27:36 +05309398
9399int wlan_hdd_cfg80211_send_tdls_discover_req(struct wiphy *wiphy,
9400 struct net_device *dev, u8 *peer)
9401{
Arif Hussaina7c8e412013-11-20 11:06:42 -08009402 hddLog(VOS_TRACE_LEVEL_INFO,
9403 "tdls send discover req: "MAC_ADDRESS_STR,
9404 MAC_ADDR_ARRAY(peer));
Chilam NG571c65a2013-01-19 12:27:36 +05309405
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +05309406#if TDLS_MGMT_VERSION2
9407 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
9408 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
9409#else
Chilam NG571c65a2013-01-19 12:27:36 +05309410 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
9411 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, NULL, 0);
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +05309412#endif
Chilam NG571c65a2013-01-19 12:27:36 +05309413}
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009414#endif
9415
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309416#ifdef WLAN_FEATURE_GTK_OFFLOAD
9417/*
9418 * FUNCTION: wlan_hdd_cfg80211_update_replayCounterCallback
9419 * Callback rountine called upon receiving response for
9420 * get offload info
9421 */
9422void wlan_hdd_cfg80211_update_replayCounterCallback(void *callbackContext,
9423 tpSirGtkOffloadGetInfoRspParams pGtkOffloadGetInfoRsp)
9424{
9425
9426 hdd_adapter_t *pAdapter = (hdd_adapter_t *)callbackContext;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05309427 tANI_U8 tempReplayCounter[8];
9428 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309429
9430 ENTER();
9431
9432 if (NULL == pAdapter)
9433 {
Agarwal Ashish971c2882013-10-30 20:11:12 +05309434 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309435 "%s: HDD adapter is Null", __func__);
9436 return ;
9437 }
9438
9439 if (NULL == pGtkOffloadGetInfoRsp)
9440 {
9441 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9442 "%s: pGtkOffloadGetInfoRsp is Null", __func__);
9443 return ;
9444 }
9445
9446 if (VOS_STATUS_SUCCESS != pGtkOffloadGetInfoRsp->ulStatus)
9447 {
9448 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9449 "%s: wlan Failed to get replay counter value",
9450 __func__);
9451 return ;
9452 }
9453
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05309454 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9455 /* Update replay counter */
9456 pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter =
9457 pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
9458
9459 {
9460 /* changing from little to big endian since supplicant
9461 * works on big endian format
9462 */
9463 int i;
9464 tANI_U8 *p = (tANI_U8 *)&pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
9465
9466 for (i = 0; i < 8; i++)
9467 {
9468 tempReplayCounter[7-i] = (tANI_U8)p[i];
9469 }
9470 }
9471
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309472 /* Update replay counter to NL */
9473 cfg80211_gtk_rekey_notify(pAdapter->dev, pGtkOffloadGetInfoRsp->bssId,
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05309474 tempReplayCounter, GFP_KERNEL);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309475}
9476
9477/*
9478 * FUNCTION: wlan_hdd_cfg80211_set_rekey_data
9479 * This function is used to offload GTK rekeying job to the firmware.
9480 */
9481int wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
9482 struct cfg80211_gtk_rekey_data *data)
9483{
9484 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
9485 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
9486 hdd_station_ctx_t *pHddStaCtx;
9487 tHalHandle hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309488 int result;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05309489 tSirGtkOffloadParams hddGtkOffloadReqParams;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309490 eHalStatus status = eHAL_STATUS_FAILURE;
9491
9492 ENTER();
9493
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309494
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309495 if (NULL == pAdapter)
9496 {
9497 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
9498 "%s: HDD adapter is Null", __func__);
9499 return -ENODEV;
9500 }
9501
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309502 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
9503 TRACE_CODE_HDD_CFG80211_SET_REKEY_DATA,
9504 pAdapter->sessionId, pAdapter->device_mode));
9505
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309506 result = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309507
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309508 if (0 != result)
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309509 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309510 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9511 "%s: HDD context is not valid", __func__);
9512 return result;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309513 }
9514
9515 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9516 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
9517 if (NULL == hHal)
9518 {
9519 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9520 "%s: HAL context is Null!!!", __func__);
9521 return -EAGAIN;
9522 }
9523
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05309524 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_ENABLE;
9525 memcpy(pHddStaCtx->gtkOffloadReqParams.aKCK, data->kck, NL80211_KCK_LEN);
9526 memcpy(pHddStaCtx->gtkOffloadReqParams.aKEK, data->kek, NL80211_KEK_LEN);
9527 memcpy(pHddStaCtx->gtkOffloadReqParams.bssId, &pHddStaCtx->conn_info.bssId,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309528 WNI_CFG_BSSID_LEN);
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05309529 {
9530 /* changing from big to little endian since driver
9531 * works on little endian format
9532 */
9533 tANI_U8 *p =
9534 (tANI_U8 *)&pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter;
9535 int i;
9536
9537 for (i = 0; i < 8; i++)
9538 {
9539 p[7-i] = data->replay_ctr[i];
9540 }
9541 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309542
9543 if (TRUE == pHddCtx->hdd_wlan_suspended)
9544 {
9545 /* if wlan is suspended, enable GTK offload directly from here */
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05309546 memcpy(&hddGtkOffloadReqParams, &pHddStaCtx->gtkOffloadReqParams,
9547 sizeof (tSirGtkOffloadParams));
9548 status = sme_SetGTKOffload(hHal, &hddGtkOffloadReqParams,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309549 pAdapter->sessionId);
9550
9551 if (eHAL_STATUS_SUCCESS != status)
9552 {
9553 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9554 "%s: sme_SetGTKOffload failed, returned %d",
9555 __func__, status);
9556 return status;
9557 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309558 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9559 "%s: sme_SetGTKOffload successfull", __func__);
9560 }
9561 else
9562 {
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309563 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9564 "%s: wlan not suspended GTKOffload request is stored",
9565 __func__);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309566 }
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05309567
9568 return eHAL_STATUS_SUCCESS;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309569}
9570#endif /*WLAN_FEATURE_GTK_OFFLOAD*/
9571
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05309572/*
9573 * FUNCTION: wlan_hdd_cfg80211_set_mac_acl
9574 * This function is used to set access control policy
9575 */
9576static int wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy,
9577 struct net_device *dev, const struct cfg80211_acl_data *params)
9578{
9579 int i;
9580 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
9581 hdd_hostapd_state_t *pHostapdState;
9582 tsap_Config_t *pConfig;
9583 v_CONTEXT_t pVosContext = NULL;
9584 hdd_context_t *pHddCtx;
9585 int status;
9586
9587 ENTER();
9588
9589 if (NULL == pAdapter)
9590 {
9591 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
9592 "%s: HDD adapter is Null", __func__);
9593 return -ENODEV;
9594 }
9595
9596 if (NULL == params)
9597 {
9598 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
9599 "%s: params is Null", __func__);
9600 return -EINVAL;
9601 }
9602
9603 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9604 status = wlan_hdd_validate_context(pHddCtx);
9605
9606 if (0 != status)
9607 {
9608 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9609 "%s: HDD context is not valid", __func__);
9610 return status;
9611 }
9612
9613 pVosContext = pHddCtx->pvosContext;
9614 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
9615
9616 if (NULL == pHostapdState)
9617 {
9618 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
9619 "%s: pHostapdState is Null", __func__);
9620 return -EINVAL;
9621 }
9622
9623 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"acl policy: = %d"
9624 "no acl entries = %d", params->acl_policy, params->n_acl_entries);
9625
9626 if (WLAN_HDD_SOFTAP == pAdapter->device_mode)
9627 {
9628 pConfig = &pAdapter->sessionCtx.ap.sapConfig;
9629
9630 /* default value */
9631 pConfig->num_accept_mac = 0;
9632 pConfig->num_deny_mac = 0;
9633
9634 /**
9635 * access control policy
9636 * @NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED: Deny stations which are
9637 * listed in hostapd.deny file.
9638 * @NL80211_ACL_POLICY_DENY_UNLESS_LISTED: Allow stations which are
9639 * listed in hostapd.accept file.
9640 */
9641 if (NL80211_ACL_POLICY_DENY_UNLESS_LISTED == params->acl_policy)
9642 {
9643 pConfig->SapMacaddr_acl = eSAP_DENY_UNLESS_ACCEPTED;
9644 }
9645 else if (NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED == params->acl_policy)
9646 {
9647 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
9648 }
9649 else
9650 {
9651 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9652 "%s:Acl Policy : %d is not supported",
9653 __func__, params->acl_policy);
9654 return -ENOTSUPP;
9655 }
9656
9657 if (eSAP_DENY_UNLESS_ACCEPTED == pConfig->SapMacaddr_acl)
9658 {
9659 pConfig->num_accept_mac = params->n_acl_entries;
9660 for (i = 0; i < params->n_acl_entries; i++)
9661 {
9662 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9663 "** Add ACL MAC entry %i in WhiletList :"
9664 MAC_ADDRESS_STR, i,
9665 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
9666
9667 vos_mem_copy(&pConfig->accept_mac[i], params->mac_addrs[i].addr,
9668 sizeof(qcmacaddr));
9669 }
9670 }
9671 else if (eSAP_ACCEPT_UNLESS_DENIED == pConfig->SapMacaddr_acl)
9672 {
9673 pConfig->num_deny_mac = params->n_acl_entries;
9674 for (i = 0; i < params->n_acl_entries; i++)
9675 {
9676 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9677 "** Add ACL MAC entry %i in BlackList :"
9678 MAC_ADDRESS_STR, i,
9679 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
9680
9681 vos_mem_copy(&pConfig->deny_mac[i], params->mac_addrs[i].addr,
9682 sizeof(qcmacaddr));
9683 }
9684 }
9685
9686 if (VOS_STATUS_SUCCESS != WLANSAP_SetMacACL(pVosContext, pConfig))
9687 {
9688 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9689 "%s: SAP Set Mac Acl fail", __func__);
9690 return -EINVAL;
9691 }
9692 }
9693 else
9694 {
9695 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309696 "%s: Invalid device_mode = %s (%d)",
9697 __func__, hdd_device_modetoString(pAdapter->device_mode),
9698 pAdapter->device_mode);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05309699 return -EINVAL;
9700 }
9701
9702 return 0;
9703}
9704
Leo Chang9056f462013-08-01 19:21:11 -07009705#ifdef WLAN_NL80211_TESTMODE
9706#ifdef FEATURE_WLAN_LPHB
Leo Changd9df8aa2013-09-26 13:32:26 -07009707void wlan_hdd_cfg80211_lphb_ind_handler
Leo Chang9056f462013-08-01 19:21:11 -07009708(
9709 void *pAdapter,
9710 void *indCont
9711)
9712{
Leo Changd9df8aa2013-09-26 13:32:26 -07009713 tSirLPHBInd *lphbInd;
9714 struct sk_buff *skb;
c_hpothu73f35e62014-04-18 13:40:08 +05309715 hdd_context_t *pHddCtxt;
Leo Chang9056f462013-08-01 19:21:11 -07009716
9717 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -07009718 "LPHB indication arrived");
Leo Chang9056f462013-08-01 19:21:11 -07009719
c_hpothu73f35e62014-04-18 13:40:08 +05309720 if (pAdapter == NULL)
9721 {
9722 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9723 "%s: pAdapter is NULL\n",__func__);
9724 return;
9725 }
9726
Leo Chang9056f462013-08-01 19:21:11 -07009727 if (NULL == indCont)
9728 {
9729 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -07009730 "LPHB IND, invalid argument");
Leo Chang9056f462013-08-01 19:21:11 -07009731 return;
9732 }
9733
c_hpothu73f35e62014-04-18 13:40:08 +05309734 pHddCtxt = (hdd_context_t *)pAdapter;
Leo Changd9df8aa2013-09-26 13:32:26 -07009735 lphbInd = (tSirLPHBInd *)indCont;
Leo Chang9056f462013-08-01 19:21:11 -07009736 skb = cfg80211_testmode_alloc_event_skb(
c_hpothu73f35e62014-04-18 13:40:08 +05309737 pHddCtxt->wiphy,
Leo Changd9df8aa2013-09-26 13:32:26 -07009738 sizeof(tSirLPHBInd),
Leo Chang9056f462013-08-01 19:21:11 -07009739 GFP_ATOMIC);
9740 if (!skb)
9741 {
9742 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9743 "LPHB timeout, NL buffer alloc fail");
9744 return;
9745 }
9746
Leo Changac3ba772013-10-07 09:47:04 -07009747 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_CMD, WLAN_HDD_TM_CMD_WLAN_HB))
Leo Changd9df8aa2013-09-26 13:32:26 -07009748 {
9749 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9750 "WLAN_HDD_TM_ATTR_CMD put fail");
9751 goto nla_put_failure;
9752 }
Leo Changac3ba772013-10-07 09:47:04 -07009753 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_TYPE, lphbInd->protocolType))
Leo Changd9df8aa2013-09-26 13:32:26 -07009754 {
9755 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9756 "WLAN_HDD_TM_ATTR_TYPE put fail");
9757 goto nla_put_failure;
9758 }
Leo Changac3ba772013-10-07 09:47:04 -07009759 if(nla_put(skb, WLAN_HDD_TM_ATTR_DATA,
Leo Changd9df8aa2013-09-26 13:32:26 -07009760 sizeof(tSirLPHBInd), lphbInd))
9761 {
9762 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9763 "WLAN_HDD_TM_ATTR_DATA put fail");
9764 goto nla_put_failure;
9765 }
Leo Chang9056f462013-08-01 19:21:11 -07009766 cfg80211_testmode_event(skb, GFP_ATOMIC);
9767 return;
9768
9769nla_put_failure:
9770 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9771 "NLA Put fail");
9772 kfree_skb(skb);
9773
9774 return;
9775}
9776#endif /* FEATURE_WLAN_LPHB */
9777
9778static int wlan_hdd_cfg80211_testmode(struct wiphy *wiphy, void *data, int len)
9779{
9780 struct nlattr *tb[WLAN_HDD_TM_ATTR_MAX + 1];
9781 int err = 0;
9782#ifdef FEATURE_WLAN_LPHB
9783 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Leo Changd9df8aa2013-09-26 13:32:26 -07009784 eHalStatus smeStatus;
Leo Chang9056f462013-08-01 19:21:11 -07009785#endif /* FEATURE_WLAN_LPHB */
9786
9787 err = nla_parse(tb, WLAN_HDD_TM_ATTR_MAX, data, len, wlan_hdd_tm_policy);
9788 if (err)
9789 {
9790 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9791 "%s Testmode INV ATTR", __func__);
9792 return err;
9793 }
9794
9795 if (!tb[WLAN_HDD_TM_ATTR_CMD])
9796 {
9797 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9798 "%s Testmode INV CMD", __func__);
9799 return -EINVAL;
9800 }
9801
9802 switch (nla_get_u32(tb[WLAN_HDD_TM_ATTR_CMD]))
9803 {
9804#ifdef FEATURE_WLAN_LPHB
9805 /* Low Power Heartbeat configuration request */
9806 case WLAN_HDD_TM_CMD_WLAN_HB:
9807 {
9808 int buf_len;
9809 void *buf;
9810 tSirLPHBReq *hb_params = NULL;
Amar Singhal05852702014-02-04 14:40:00 -08009811 tSirLPHBReq *hb_params_temp = NULL;
Leo Chang9056f462013-08-01 19:21:11 -07009812
9813 if (!tb[WLAN_HDD_TM_ATTR_DATA])
9814 {
9815 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9816 "%s Testmode INV DATA", __func__);
9817 return -EINVAL;
9818 }
9819
9820 buf = nla_data(tb[WLAN_HDD_TM_ATTR_DATA]);
9821 buf_len = nla_len(tb[WLAN_HDD_TM_ATTR_DATA]);
Amar Singhal05852702014-02-04 14:40:00 -08009822
9823 hb_params_temp =(tSirLPHBReq *)buf;
9824 if ((hb_params_temp->cmd == LPHB_SET_TCP_PARAMS_INDID) &&
9825 (hb_params_temp->params.lphbTcpParamReq.timePeriodSec == 0))
9826 return -EINVAL;
9827
Leo Chang9056f462013-08-01 19:21:11 -07009828 hb_params = (tSirLPHBReq *)vos_mem_malloc(sizeof(tSirLPHBReq));
9829 if (NULL == hb_params)
9830 {
9831 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9832 "%s Request Buffer Alloc Fail", __func__);
9833 return -EINVAL;
9834 }
9835
9836 vos_mem_copy(hb_params, buf, buf_len);
Leo Changd9df8aa2013-09-26 13:32:26 -07009837 smeStatus = sme_LPHBConfigReq((tHalHandle)(pHddCtx->hHal),
9838 hb_params,
9839 wlan_hdd_cfg80211_lphb_ind_handler);
9840 if (eHAL_STATUS_SUCCESS != smeStatus)
Leo Chang9056f462013-08-01 19:21:11 -07009841 {
Leo Changd9df8aa2013-09-26 13:32:26 -07009842 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9843 "LPHB Config Fail, disable");
Leo Chang9056f462013-08-01 19:21:11 -07009844 vos_mem_free(hb_params);
9845 }
Leo Chang9056f462013-08-01 19:21:11 -07009846 return 0;
9847 }
9848#endif /* FEATURE_WLAN_LPHB */
9849 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309850 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9851 "%s: unsupported event",__func__);
Leo Chang9056f462013-08-01 19:21:11 -07009852 return -EOPNOTSUPP;
9853 }
9854
9855 return err;
9856}
9857#endif /* CONFIG_NL80211_TESTMODE */
9858
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +05309859static int wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
9860 struct net_device *dev,
9861 int idx, struct survey_info *survey)
9862{
9863 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
9864 hdd_context_t *pHddCtx;
Mihir Sheted9072e02013-08-21 17:02:29 +05309865 hdd_station_ctx_t *pHddStaCtx;
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +05309866 tHalHandle halHandle;
Mihir Sheted9072e02013-08-21 17:02:29 +05309867 v_U32_t channel = 0, freq = 0; /* Initialization Required */
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +05309868 v_S7_t snr,rssi;
9869 int status, i, j, filled = 0;
9870
9871 ENTER();
9872
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +05309873 if (NULL == pAdapter)
9874 {
9875 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
9876 "%s: HDD adapter is Null", __func__);
9877 return -ENODEV;
9878 }
9879
9880 if (NULL == wiphy)
9881 {
9882 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
9883 "%s: wiphy is Null", __func__);
9884 return -ENODEV;
9885 }
9886
9887 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9888 status = wlan_hdd_validate_context(pHddCtx);
9889
9890 if (0 != status)
9891 {
9892 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9893 "%s: HDD context is not valid", __func__);
9894 return status;
9895 }
9896
Mihir Sheted9072e02013-08-21 17:02:29 +05309897 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9898
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +05309899 if (0 == pHddCtx->cfg_ini->fEnableSNRMonitoring ||
Mihir Sheted9072e02013-08-21 17:02:29 +05309900 0 != pAdapter->survey_idx ||
9901 eConnectionState_Associated != pHddStaCtx->conn_info.connState)
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +05309902 {
9903 /* The survey dump ops when implemented completely is expected to
9904 * return a survey of all channels and the ops is called by the
9905 * kernel with incremental values of the argument 'idx' till it
9906 * returns -ENONET. But we can only support the survey for the
9907 * operating channel for now. survey_idx is used to track
9908 * that the ops is called only once and then return -ENONET for
9909 * the next iteration
9910 */
9911 pAdapter->survey_idx = 0;
9912 return -ENONET;
9913 }
9914
9915 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
9916
9917 wlan_hdd_get_snr(pAdapter, &snr);
9918 wlan_hdd_get_rssi(pAdapter, &rssi);
9919
9920 sme_GetOperationChannel(halHandle, &channel, pAdapter->sessionId);
9921 hdd_wlan_get_freq(channel, &freq);
9922
9923
9924 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
9925 {
9926 if (NULL == wiphy->bands[i])
9927 {
9928 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
9929 "%s: wiphy->bands[i] is NULL, i = %d", __func__, i);
9930 continue;
9931 }
9932
9933 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
9934 {
9935 struct ieee80211_supported_band *band = wiphy->bands[i];
9936
9937 if (band->channels[j].center_freq == (v_U16_t)freq)
9938 {
9939 survey->channel = &band->channels[j];
9940 /* The Rx BDs contain SNR values in dB for the received frames
9941 * while the supplicant expects noise. So we calculate and
9942 * return the value of noise (dBm)
9943 * SNR (dB) = RSSI (dBm) - NOISE (dBm)
9944 */
9945 survey->noise = rssi - snr;
9946 survey->filled = SURVEY_INFO_NOISE_DBM;
9947 filled = 1;
9948 }
9949 }
9950 }
9951
9952 if (filled)
9953 pAdapter->survey_idx = 1;
9954 else
9955 {
9956 pAdapter->survey_idx = 0;
9957 return -ENONET;
9958 }
9959
9960 return 0;
9961}
9962
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05309963/*
9964 * FUNCTION: wlan_hdd_cfg80211_resume_wlan
9965 * this is called when cfg80211 driver resume
9966 * driver updates latest sched_scan scan result(if any) to cfg80211 database
9967 */
9968int wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
9969{
9970 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
9971 hdd_adapter_t *pAdapter;
9972 hdd_adapter_list_node_t *pAdapterNode, *pNext;
9973 VOS_STATUS status = VOS_STATUS_SUCCESS;
9974
9975 ENTER();
9976
9977 if ( NULL == pHddCtx )
9978 {
9979 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
9980 "%s: HddCtx validation failed", __func__);
9981 return 0;
9982 }
9983
9984 if (pHddCtx->isLogpInProgress)
9985 {
9986 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9987 "%s: LOGP in Progress. Ignore!!!", __func__);
9988 return 0;
9989 }
9990
Mihir Shete18156292014-03-11 15:38:30 +05309991 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05309992 {
9993 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9994 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
9995 return 0;
9996 }
9997
9998 spin_lock(&pHddCtx->schedScan_lock);
9999 pHddCtx->isWiphySuspended = FALSE;
10000 if (TRUE != pHddCtx->isSchedScanUpdatePending)
10001 {
10002 spin_unlock(&pHddCtx->schedScan_lock);
10003 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
10004 "%s: Return resume is not due to PNO indication", __func__);
10005 return 0;
10006 }
10007 // Reset flag to avoid updatating cfg80211 data old results again
10008 pHddCtx->isSchedScanUpdatePending = FALSE;
10009 spin_unlock(&pHddCtx->schedScan_lock);
10010
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053010011
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053010012 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
10013
10014 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
10015 {
10016 pAdapter = pAdapterNode->pAdapter;
10017 if ( (NULL != pAdapter) &&
10018 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) )
10019 {
10020 if (0 != wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter))
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053010021 {
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053010022 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
10023 "%s: NO SCAN result", __func__);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053010024 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053010025 else
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053010026 {
10027 /* Acquire wakelock to handle the case where APP's tries to
10028 * suspend immediately after updating the scan results. Whis
10029 * results in app's is in suspended state and not able to
10030 * process the connect request to AP
10031 */
10032 hdd_prevent_suspend_timeout(2000);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053010033 cfg80211_sched_scan_results(pHddCtx->wiphy);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053010034 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053010035
10036 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
10037 "%s : cfg80211 scan result database updated", __func__);
10038
10039 return 0;
10040
10041 }
10042 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
10043 pAdapterNode = pNext;
10044 }
10045
10046 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
10047 "%s: Failed to find Adapter", __func__);
10048 return 0;
10049}
10050
10051/*
10052 * FUNCTION: wlan_hdd_cfg80211_suspend_wlan
10053 * this is called when cfg80211 driver suspends
10054 */
10055int wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
10056 struct cfg80211_wowlan *wow)
10057{
10058 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
10059
10060 ENTER();
10061 if (NULL == pHddCtx)
10062 {
10063 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
10064 "%s: HddCtx validation failed", __func__);
10065 return 0;
10066 }
10067
10068 pHddCtx->isWiphySuspended = TRUE;
10069
10070 EXIT();
10071
10072 return 0;
10073}
10074
Jeff Johnson295189b2012-06-20 16:38:30 -070010075/* cfg80211_ops */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010076static struct cfg80211_ops wlan_hdd_cfg80211_ops =
Jeff Johnson295189b2012-06-20 16:38:30 -070010077{
10078 .add_virtual_intf = wlan_hdd_add_virtual_intf,
10079 .del_virtual_intf = wlan_hdd_del_virtual_intf,
10080 .change_virtual_intf = wlan_hdd_cfg80211_change_iface,
10081 .change_station = wlan_hdd_change_station,
10082#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
10083 .add_beacon = wlan_hdd_cfg80211_add_beacon,
10084 .del_beacon = wlan_hdd_cfg80211_del_beacon,
10085 .set_beacon = wlan_hdd_cfg80211_set_beacon,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010086#else
10087 .start_ap = wlan_hdd_cfg80211_start_ap,
10088 .change_beacon = wlan_hdd_cfg80211_change_beacon,
10089 .stop_ap = wlan_hdd_cfg80211_stop_ap,
Jeff Johnson295189b2012-06-20 16:38:30 -070010090#endif
10091 .change_bss = wlan_hdd_cfg80211_change_bss,
10092 .add_key = wlan_hdd_cfg80211_add_key,
10093 .get_key = wlan_hdd_cfg80211_get_key,
10094 .del_key = wlan_hdd_cfg80211_del_key,
10095 .set_default_key = wlan_hdd_cfg80211_set_default_key,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080010096#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
Jeff Johnson295189b2012-06-20 16:38:30 -070010097 .set_channel = wlan_hdd_cfg80211_set_channel,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080010098#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010099 .scan = wlan_hdd_cfg80211_scan,
10100 .connect = wlan_hdd_cfg80211_connect,
10101 .disconnect = wlan_hdd_cfg80211_disconnect,
10102 .join_ibss = wlan_hdd_cfg80211_join_ibss,
10103 .leave_ibss = wlan_hdd_cfg80211_leave_ibss,
10104 .set_wiphy_params = wlan_hdd_cfg80211_set_wiphy_params,
10105 .set_tx_power = wlan_hdd_cfg80211_set_txpower,
10106 .get_tx_power = wlan_hdd_cfg80211_get_txpower,
Jeff Johnson295189b2012-06-20 16:38:30 -070010107 .remain_on_channel = wlan_hdd_cfg80211_remain_on_channel,
10108 .cancel_remain_on_channel = wlan_hdd_cfg80211_cancel_remain_on_channel,
DARAM SUDHA39eede62014-02-12 11:16:40 +053010109 .mgmt_tx = wlan_hdd_mgmt_tx,
Jeff Johnson295189b2012-06-20 16:38:30 -070010110#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
10111 .mgmt_tx_cancel_wait = wlan_hdd_cfg80211_mgmt_tx_cancel_wait,
10112 .set_default_mgmt_key = wlan_hdd_set_default_mgmt_key,
10113 .set_txq_params = wlan_hdd_set_txq_params,
10114#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010115 .get_station = wlan_hdd_cfg80211_get_station,
10116 .set_power_mgmt = wlan_hdd_cfg80211_set_power_mgmt,
10117 .del_station = wlan_hdd_cfg80211_del_station,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010118 .add_station = wlan_hdd_cfg80211_add_station,
10119#ifdef FEATURE_WLAN_LFR
10120 .set_pmksa = wlan_hdd_cfg80211_set_pmksa,
10121 .del_pmksa = wlan_hdd_cfg80211_del_pmksa,
10122 .flush_pmksa = wlan_hdd_cfg80211_flush_pmksa,
10123#endif
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070010124#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
10125 .update_ft_ies = wlan_hdd_cfg80211_update_ft_ies,
10126#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080010127#ifdef FEATURE_WLAN_TDLS
10128 .tdls_mgmt = wlan_hdd_cfg80211_tdls_mgmt,
10129 .tdls_oper = wlan_hdd_cfg80211_tdls_oper,
10130#endif
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053010131#ifdef WLAN_FEATURE_GTK_OFFLOAD
10132 .set_rekey_data = wlan_hdd_cfg80211_set_rekey_data,
10133#endif /* WLAN_FEATURE_GTK_OFFLOAD */
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053010134#ifdef FEATURE_WLAN_SCAN_PNO
10135 .sched_scan_start = wlan_hdd_cfg80211_sched_scan_start,
10136 .sched_scan_stop = wlan_hdd_cfg80211_sched_scan_stop,
10137#endif /*FEATURE_WLAN_SCAN_PNO */
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053010138 .resume = wlan_hdd_cfg80211_resume_wlan,
10139 .suspend = wlan_hdd_cfg80211_suspend_wlan,
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053010140 .set_mac_acl = wlan_hdd_cfg80211_set_mac_acl,
Leo Chang9056f462013-08-01 19:21:11 -070010141#ifdef WLAN_NL80211_TESTMODE
10142 .testmode_cmd = wlan_hdd_cfg80211_testmode,
10143#endif
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053010144 .dump_survey = wlan_hdd_cfg80211_dump_survey,
Jeff Johnson295189b2012-06-20 16:38:30 -070010145};
10146