blob: 74c2f46e1155424801e197c313ff59bce8dbfdb6 [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 Lanctot40142442014-05-20 13:39:25 -07001914 v_BOOL_t MFPCapable = VOS_FALSE;
1915 v_BOOL_t MFPRequired = VOS_FALSE;
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 Kaushik8bc7df22014-04-09 17:55:29 +05304038 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
4039 __func__, hdd_device_modetoString(pAdapter->device_mode),
4040 pAdapter->device_mode);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304041
Jeff Johnson295189b2012-06-20 16:38:30 -07004042 memset(&params, 0, sizeof(params));
4043
4044 if (CSR_MAX_NUM_KEY <= key_index)
4045 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05304046 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid key index %d"), key_index);
Jeff Johnson295189b2012-06-20 16:38:30 -07004047 return -EINVAL;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304048 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004049
4050 switch(pRoamProfile->EncryptionType.encryptionType[0])
4051 {
4052 case eCSR_ENCRYPT_TYPE_NONE:
4053 params.cipher = IW_AUTH_CIPHER_NONE;
4054 break;
4055
4056 case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY:
4057 case eCSR_ENCRYPT_TYPE_WEP40:
4058 params.cipher = WLAN_CIPHER_SUITE_WEP40;
4059 break;
4060
4061 case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY:
4062 case eCSR_ENCRYPT_TYPE_WEP104:
4063 params.cipher = WLAN_CIPHER_SUITE_WEP104;
4064 break;
4065
4066 case eCSR_ENCRYPT_TYPE_TKIP:
4067 params.cipher = WLAN_CIPHER_SUITE_TKIP;
4068 break;
4069
4070 case eCSR_ENCRYPT_TYPE_AES:
4071 params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
4072 break;
4073
4074 default:
4075 params.cipher = IW_AUTH_CIPHER_NONE;
4076 break;
4077 }
4078
c_hpothuaaf19692014-05-17 17:01:48 +05304079 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
4080 TRACE_CODE_HDD_CFG80211_GET_KEY,
4081 pAdapter->sessionId, params.cipher));
4082
Jeff Johnson295189b2012-06-20 16:38:30 -07004083 params.key_len = pRoamProfile->Keys.KeyLength[key_index];
4084 params.seq_len = 0;
4085 params.seq = NULL;
4086 params.key = &pRoamProfile->Keys.KeyMaterial[key_index][0];
4087 callback(cookie, &params);
4088 return 0;
4089}
4090
4091/*
4092 * FUNCTION: wlan_hdd_cfg80211_del_key
4093 * This function is used to delete the key information
4094 */
4095#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304096static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07004097 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304098 u8 key_index,
4099 bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -07004100 const u8 *mac_addr
4101 )
4102#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304103static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07004104 struct net_device *ndev,
4105 u8 key_index,
4106 const u8 *mac_addr
4107 )
4108#endif
4109{
4110 int status = 0;
4111
4112 //This code needs to be revisited. There is sme_removeKey API, we should
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304113 //plan to use that. After the change to use correct index in setkey,
Jeff Johnson295189b2012-06-20 16:38:30 -07004114 //it is observed that this is invalidating peer
4115 //key index whenever re-key is done. This is affecting data link.
4116 //It should be ok to ignore del_key.
4117#if 0
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304118 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
4119 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07004120 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
4121 tCsrRoamSetKey setKey;
4122 v_U32_t roamId= 0xFF;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304123
Jeff Johnson295189b2012-06-20 16:38:30 -07004124 ENTER();
4125
4126 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device_mode = %d\n",
4127 __func__,pAdapter->device_mode);
4128
4129 if (CSR_MAX_NUM_KEY <= key_index)
4130 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304131 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07004132 key_index);
4133
4134 return -EINVAL;
4135 }
4136
4137 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
4138 setKey.keyId = key_index;
4139
4140 if (mac_addr)
4141 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
4142 else
4143 vos_mem_copy(setKey.peerMac, groupmacaddr, WNI_CFG_BSSID_LEN);
4144
4145 setKey.encType = eCSR_ENCRYPT_TYPE_NONE;
4146
4147 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07004148 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304149 )
4150 {
4151
4152 hdd_hostapd_state_t *pHostapdState =
Jeff Johnson295189b2012-06-20 16:38:30 -07004153 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
4154 if( pHostapdState->bssState == BSS_START)
4155 {
4156 status = WLANSAP_SetKeySta( pVosContext, &setKey);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304157
Jeff Johnson295189b2012-06-20 16:38:30 -07004158 if ( status != eHAL_STATUS_SUCCESS )
4159 {
4160 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4161 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
4162 __LINE__, status );
4163 }
4164 }
4165 }
4166 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304167 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnson295189b2012-06-20 16:38:30 -07004168 )
4169 {
4170 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4171
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304172 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
4173
4174 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -07004175 "%s: delete key for peerMac %2x:%2x:%2x:%2x:%2x:%2x",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304176 __func__, setKey.peerMac[0], setKey.peerMac[1],
4177 setKey.peerMac[2], setKey.peerMac[3],
Jeff Johnson295189b2012-06-20 16:38:30 -07004178 setKey.peerMac[4], setKey.peerMac[5]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304179 if(pAdapter->sessionCtx.station.conn_info.connState ==
4180 eConnectionState_Associated)
Jeff Johnson295189b2012-06-20 16:38:30 -07004181 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304182 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07004183 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304184
Jeff Johnson295189b2012-06-20 16:38:30 -07004185 if ( 0 != status )
4186 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304187 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07004188 "%s: sme_RoamSetKey failure, returned %d",
4189 __func__, status);
4190 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
4191 return -EINVAL;
4192 }
4193 }
4194 }
4195#endif
Jeff Johnsone7245742012-09-05 17:12:55 -07004196 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07004197 return status;
4198}
4199
4200/*
4201 * FUNCTION: wlan_hdd_cfg80211_set_default_key
4202 * This function is used to set the default tx key index
4203 */
4204#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
4205static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
4206 struct net_device *ndev,
4207 u8 key_index,
4208 bool unicast, bool multicast)
4209#else
4210static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
4211 struct net_device *ndev,
4212 u8 key_index)
4213#endif
4214{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304215 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05304216 int status;
Gopichand Nakkala29149562013-05-10 21:43:41 +05304217 hdd_wext_state_t *pWextState;
4218 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05304219 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07004220
4221 ENTER();
4222
Gopichand Nakkala29149562013-05-10 21:43:41 +05304223 if ((NULL == pAdapter))
4224 {
4225 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
4226 "invalid adapter");
4227 return -EINVAL;
4228 }
4229
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05304230 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
4231 TRACE_CODE_HDD_CFG80211_SET_DEFAULT_KEY,
4232 pAdapter->sessionId, key_index));
4233
Gopichand Nakkala29149562013-05-10 21:43:41 +05304234 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
4235 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4236
4237 if ((NULL == pWextState) || (NULL == pHddStaCtx))
4238 {
4239 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
4240 "invalid Wext state or HDD context");
4241 return -EINVAL;
4242 }
4243
Arif Hussain6d2a3322013-11-17 19:50:10 -08004244 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d key_index = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07004245 __func__,pAdapter->device_mode, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304246
Jeff Johnson295189b2012-06-20 16:38:30 -07004247 if (CSR_MAX_NUM_KEY <= key_index)
4248 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304249 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07004250 key_index);
4251
4252 return -EINVAL;
4253 }
4254
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05304255 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
4256 status = wlan_hdd_validate_context(pHddCtx);
4257
4258 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004259 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05304260 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4261 "%s: HDD context is not valid", __func__);
4262 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004263 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304264
Jeff Johnson295189b2012-06-20 16:38:30 -07004265 if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -07004266 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304267 )
Jeff Johnson295189b2012-06-20 16:38:30 -07004268 {
Gopichand Nakkala29149562013-05-10 21:43:41 +05304269 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
Arif Hussain6943f522013-11-04 20:10:10 -08004270 pHddStaCtx->conn_info.ucEncryptionType) &&
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304271 (eCSR_ENCRYPT_TYPE_AES !=
Arif Hussain6943f522013-11-04 20:10:10 -08004272 pHddStaCtx->conn_info.ucEncryptionType)
Jeff Johnson295189b2012-06-20 16:38:30 -07004273 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304274 {
4275 /* if default key index is not same as previous one,
Jeff Johnson295189b2012-06-20 16:38:30 -07004276 * then update the default key index */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304277
Jeff Johnson295189b2012-06-20 16:38:30 -07004278 tCsrRoamSetKey setKey;
4279 v_U32_t roamId= 0xFF;
4280 tCsrKeys *Keys = &pWextState->roamProfile.Keys;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304281
4282 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: default tx key index %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07004283 __func__, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304284
Jeff Johnson295189b2012-06-20 16:38:30 -07004285 Keys->defaultIndex = (u8)key_index;
4286 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
4287 setKey.keyId = key_index;
4288 setKey.keyLength = Keys->KeyLength[key_index];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304289
4290 vos_mem_copy(&setKey.Key[0],
4291 &Keys->KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -07004292 Keys->KeyLength[key_index]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304293
Gopichand Nakkala29149562013-05-10 21:43:41 +05304294 setKey.keyDirection = eSIR_TX_RX;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304295
4296 vos_mem_copy(setKey.peerMac,
Jeff Johnson295189b2012-06-20 16:38:30 -07004297 &pHddStaCtx->conn_info.bssId[0],
4298 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304299
Gopichand Nakkala29149562013-05-10 21:43:41 +05304300 if (Keys->KeyLength[key_index] == CSR_WEP40_KEY_LEN &&
4301 pWextState->roamProfile.EncryptionType.encryptionType[0] ==
4302 eCSR_ENCRYPT_TYPE_WEP104)
4303 {
4304 /*In the case of dynamic wep supplicant hardcodes DWEP type to eCSR_ENCRYPT_TYPE_WEP104
4305 even though ap is configured for WEP-40 encryption. In this canse the key length
4306 is 5 but the encryption type is 104 hence checking the key langht(5) and encryption
4307 type(104) and switching encryption type to 40*/
4308 pWextState->roamProfile.EncryptionType.encryptionType[0] =
4309 eCSR_ENCRYPT_TYPE_WEP40;
4310 pWextState->roamProfile.mcEncryptionType.encryptionType[0] =
4311 eCSR_ENCRYPT_TYPE_WEP40;
4312 }
4313
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304314 setKey.encType =
Jeff Johnson295189b2012-06-20 16:38:30 -07004315 pWextState->roamProfile.EncryptionType.encryptionType[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304316
Jeff Johnson295189b2012-06-20 16:38:30 -07004317 /* issue set key request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304318 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07004319 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304320
Jeff Johnson295189b2012-06-20 16:38:30 -07004321 if ( 0 != status )
4322 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304323 hddLog(VOS_TRACE_LEVEL_ERROR,
4324 "%s: sme_RoamSetKey failed, returned %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07004325 status);
4326 return -EINVAL;
4327 }
4328 }
4329 }
4330
4331 /* In SoftAp mode setting key direction for default mode */
4332 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
4333 {
4334 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
4335 pWextState->roamProfile.EncryptionType.encryptionType[0]) &&
4336 (eCSR_ENCRYPT_TYPE_AES !=
4337 pWextState->roamProfile.EncryptionType.encryptionType[0])
4338 )
4339 {
4340 /* Saving key direction for default key index to TX default */
4341 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
4342 pAPCtx->wepKey[key_index].keyDirection = eSIR_TX_DEFAULT;
4343 }
4344 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304345
Jeff Johnson295189b2012-06-20 16:38:30 -07004346 return status;
4347}
4348
Jeff Johnson295189b2012-06-20 16:38:30 -07004349/*
4350 * FUNCTION: wlan_hdd_cfg80211_inform_bss
4351 * This function is used to inform the BSS details to nl80211 interface.
4352 */
4353static struct cfg80211_bss* wlan_hdd_cfg80211_inform_bss(
4354 hdd_adapter_t *pAdapter, tCsrRoamConnectedProfile *roamProfile)
4355{
4356 struct net_device *dev = pAdapter->dev;
4357 struct wireless_dev *wdev = dev->ieee80211_ptr;
4358 struct wiphy *wiphy = wdev->wiphy;
4359 tSirBssDescription *pBssDesc = roamProfile->pBssDesc;
4360 int chan_no;
4361 int ie_length;
4362 const char *ie;
4363 unsigned int freq;
4364 struct ieee80211_channel *chan;
4365 int rssi = 0;
4366 struct cfg80211_bss *bss = NULL;
4367
4368 ENTER();
4369
4370 if( NULL == pBssDesc )
4371 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08004372 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pBssDesc is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004373 return bss;
4374 }
4375
4376 chan_no = pBssDesc->channelId;
4377 ie_length = GET_IE_LEN_IN_BSS_DESC( pBssDesc->length );
4378 ie = ((ie_length != 0) ? (const char *)&pBssDesc->ieFields: NULL);
4379
4380 if( NULL == ie )
4381 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08004382 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: IE of BSS descriptor is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004383 return bss;
4384 }
4385
4386#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
4387 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
4388 {
4389 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
4390 }
4391 else
4392 {
4393 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
4394 }
4395#else
4396 freq = ieee80211_channel_to_frequency(chan_no);
4397#endif
4398
4399 chan = __ieee80211_get_channel(wiphy, freq);
4400
Santhosh Kumar Padmaa45fdb12014-04-15 15:54:38 +05304401 if (!chan) {
4402 hddLog(VOS_TRACE_LEVEL_ERROR, "%s chan pointer is NULL", __func__);
4403 return NULL;
4404 }
4405
Jeff Johnson295189b2012-06-20 16:38:30 -07004406 bss = cfg80211_get_bss(wiphy, chan, pBssDesc->bssId,
4407 &roamProfile->SSID.ssId[0], roamProfile->SSID.length,
4408 WLAN_CAPABILITY_ESS, WLAN_CAPABILITY_ESS);
4409 if (bss == NULL)
4410 {
4411 rssi = (VOS_MIN ((pBssDesc->rssi + pBssDesc->sinr), 0))*100;
4412
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304413 return (cfg80211_inform_bss(wiphy, chan, pBssDesc->bssId,
4414 le64_to_cpu(*(__le64 *)pBssDesc->timeStamp),
Jeff Johnson295189b2012-06-20 16:38:30 -07004415 pBssDesc->capabilityInfo,
4416 pBssDesc->beaconInterval, ie, ie_length,
4417 rssi, GFP_KERNEL ));
4418}
4419 else
4420 {
4421 return bss;
4422 }
4423}
4424
4425
4426
4427/*
4428 * FUNCTION: wlan_hdd_cfg80211_inform_bss_frame
4429 * This function is used to inform the BSS details to nl80211 interface.
4430 */
4431struct cfg80211_bss*
4432wlan_hdd_cfg80211_inform_bss_frame( hdd_adapter_t *pAdapter,
4433 tSirBssDescription *bss_desc
4434 )
4435{
4436 /*
4437 cfg80211_inform_bss() is not updating ie field of bss entry, if entry
4438 already exists in bss data base of cfg80211 for that particular BSS ID.
4439 Using cfg80211_inform_bss_frame to update the bss entry instead of
4440 cfg80211_inform_bss, But this call expects mgmt packet as input. As of
4441 now there is no possibility to get the mgmt(probe response) frame from PE,
4442 converting bss_desc to ieee80211_mgmt(probe response) and passing to
4443 cfg80211_inform_bss_frame.
4444 */
4445 struct net_device *dev = pAdapter->dev;
4446 struct wireless_dev *wdev = dev->ieee80211_ptr;
4447 struct wiphy *wiphy = wdev->wiphy;
4448 int chan_no = bss_desc->channelId;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08004449#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
4450 qcom_ie_age *qie_age = NULL;
4451 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length ) + sizeof(qcom_ie_age);
4452#else
Jeff Johnson295189b2012-06-20 16:38:30 -07004453 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length );
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08004454#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07004455 const char *ie =
4456 ((ie_length != 0) ? (const char *)&bss_desc->ieFields: NULL);
4457 unsigned int freq;
4458 struct ieee80211_channel *chan;
Abhishek Singh1e2bfa32014-01-02 15:44:15 +05304459 struct ieee80211_mgmt *mgmt = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07004460 struct cfg80211_bss *bss_status = NULL;
4461 size_t frame_len = sizeof (struct ieee80211_mgmt) + ie_length;
4462 int rssi = 0;
Wilson Yangf80a0542013-10-07 13:02:37 -07004463 hdd_context_t *pHddCtx;
4464 int status;
Jeff Johnsone7245742012-09-05 17:12:55 -07004465#ifdef WLAN_OPEN_SOURCE
4466 struct timespec ts;
4467#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07004468
Wilson Yangf80a0542013-10-07 13:02:37 -07004469 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
4470 status = wlan_hdd_validate_context(pHddCtx);
4471
4472 /*bss_update is not allowed during wlan driver loading or unloading*/
Mihir Shete18156292014-03-11 15:38:30 +05304473 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Wilson Yangf80a0542013-10-07 13:02:37 -07004474 {
4475 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4476 "%s:Loading_unloading in Progress. Ignore!!!",__func__);
4477 return NULL;
4478 }
4479
4480
4481 if (0 != status)
4482 {
4483 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4484 "%s: HDD context is not valid", __func__);
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -07004485 return NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -07004486 }
4487
Abhishek Singh1e2bfa32014-01-02 15:44:15 +05304488 mgmt = kzalloc((sizeof (struct ieee80211_mgmt) + ie_length), GFP_KERNEL);
Wilson Yangf80a0542013-10-07 13:02:37 -07004489 if (!mgmt)
4490 {
4491 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4492 "%s: memory allocation failed ", __func__);
4493 return NULL;
4494 }
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -07004495
Jeff Johnson295189b2012-06-20 16:38:30 -07004496 memcpy(mgmt->bssid, bss_desc->bssId, ETH_ALEN);
Jeff Johnsone7245742012-09-05 17:12:55 -07004497
4498#ifdef WLAN_OPEN_SOURCE
4499 /* Android does not want the timestamp from the frame.
4500 Instead it wants a monotonic increasing value */
4501 get_monotonic_boottime(&ts);
4502 mgmt->u.probe_resp.timestamp =
4503 ((u64)ts.tv_sec * 1000000) + (ts.tv_nsec / 1000);
4504#else
4505 /* keep old behavior for non-open source (for now) */
Jeff Johnson295189b2012-06-20 16:38:30 -07004506 memcpy(&mgmt->u.probe_resp.timestamp, bss_desc->timeStamp,
4507 sizeof (bss_desc->timeStamp));
Jeff Johnsone7245742012-09-05 17:12:55 -07004508
4509#endif
4510
Jeff Johnson295189b2012-06-20 16:38:30 -07004511 mgmt->u.probe_resp.beacon_int = bss_desc->beaconInterval;
4512 mgmt->u.probe_resp.capab_info = bss_desc->capabilityInfo;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08004513
4514#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
4515 /* GPS Requirement: need age ie per entry. Using vendor specific. */
4516 /* Assuming this is the last IE, copy at the end */
4517 ie_length -=sizeof(qcom_ie_age);
4518 qie_age = (qcom_ie_age *)(mgmt->u.probe_resp.variable + ie_length);
4519 qie_age->element_id = QCOM_VENDOR_IE_ID;
4520 qie_age->len = QCOM_VENDOR_IE_AGE_LEN;
4521 qie_age->oui_1 = QCOM_OUI1;
4522 qie_age->oui_2 = QCOM_OUI2;
4523 qie_age->oui_3 = QCOM_OUI3;
4524 qie_age->type = QCOM_VENDOR_IE_AGE_TYPE;
4525 qie_age->age = vos_timer_get_system_ticks() - bss_desc->nReceivedTime;
4526#endif
4527
Jeff Johnson295189b2012-06-20 16:38:30 -07004528 memcpy(mgmt->u.probe_resp.variable, ie, ie_length);
Gopichand Nakkalad908ec82013-05-16 19:32:19 +05304529 if (bss_desc->fProbeRsp)
4530 {
4531 mgmt->frame_control |=
4532 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_RESP);
4533 }
4534 else
4535 {
4536 mgmt->frame_control |=
4537 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_BEACON);
4538 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004539
4540#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304541 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ) &&
Jeff Johnson295189b2012-06-20 16:38:30 -07004542 (wiphy->bands[IEEE80211_BAND_2GHZ] != NULL))
4543 {
4544 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
4545 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304546 else if ((chan_no > ARRAY_SIZE(hdd_channels_2_4_GHZ)) &&
Jeff Johnson295189b2012-06-20 16:38:30 -07004547 (wiphy->bands[IEEE80211_BAND_5GHZ] != NULL))
4548
4549 {
4550 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
4551 }
4552 else
4553 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05304554 hddLog(VOS_TRACE_LEVEL_ERROR, "%s Invalid chan_no:%d",
4555 __func__, chan_no);
Jeff Johnson295189b2012-06-20 16:38:30 -07004556 kfree(mgmt);
4557 return NULL;
4558 }
4559#else
4560 freq = ieee80211_channel_to_frequency(chan_no);
4561#endif
4562 chan = __ieee80211_get_channel(wiphy, freq);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -08004563 /*when the band is changed on the fly using the GUI, three things are done
4564 * 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)
4565 * as part of the scan abort, message willbe queued to PE and we proceed with flushing and changinh the band.
4566 * pe will stop the scanning further and report back the results what ever it had till now by calling the call back function.
4567 * if the time between update band and scandone call back is sufficent enough the band change reflects in SME, SME validates the channels
4568 * and discards the channels correponding to previous band and calls back with zero bss results.
4569 * 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
4570 * all the channels correponding to previous band.this is due to race condition.but those channels are invalid to the new band and so
4571 * this function __ieee80211_get_channel will return NULL.Each time we report scan result with this pointer null warning kernel trace is printed.
4572 * if the scan results contain large number of APs continuosly kernel warning trace is printed and it will lead to apps watch dog bark.
4573 * So drop the bss and continue to next bss.
4574 */
4575 if(chan == NULL)
4576 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05304577 hddLog(VOS_TRACE_LEVEL_ERROR, "%s chan pointer is NULL", __func__);
Chilam Ngc4244af2013-04-01 15:37:32 -07004578 kfree(mgmt);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -08004579 return NULL;
4580 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004581 /*To keep the rssi icon of the connected AP in the scan window
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304582 *and the rssi icon of the wireless networks in sync
Jeff Johnson295189b2012-06-20 16:38:30 -07004583 * */
4584 if (( eConnectionState_Associated ==
4585 pAdapter->sessionCtx.station.conn_info.connState ) &&
4586 ( VOS_TRUE == vos_mem_compare(bss_desc->bssId,
4587 pAdapter->sessionCtx.station.conn_info.bssId,
4588 WNI_CFG_BSSID_LEN)))
4589 {
4590 /* supplicant takes the signal strength in terms of mBm(100*dBm) */
4591 rssi = (pAdapter->rssi * 100);
4592 }
4593 else
4594 {
4595 rssi = (VOS_MIN ((bss_desc->rssi + bss_desc->sinr), 0))*100;
4596 }
4597
Nirav Shah20ac06f2013-12-12 18:14:06 +05304598 hddLog(VOS_TRACE_LEVEL_INFO, "%s: BSSID:" MAC_ADDRESS_STR " Channel:%d"
4599 "RSSI:%d", __func__, MAC_ADDR_ARRAY(mgmt->bssid),
4600 chan->center_freq, (int)(rssi/100));
4601
Jeff Johnson295189b2012-06-20 16:38:30 -07004602 bss_status = cfg80211_inform_bss_frame(wiphy, chan, mgmt,
4603 frame_len, rssi, GFP_KERNEL);
4604 kfree(mgmt);
4605 return bss_status;
4606}
4607
4608/*
4609 * FUNCTION: wlan_hdd_cfg80211_update_bss_db
4610 * This function is used to update the BSS data base of CFG8011
4611 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304612struct cfg80211_bss* wlan_hdd_cfg80211_update_bss_db( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07004613 tCsrRoamInfo *pRoamInfo
4614 )
4615{
4616 tCsrRoamConnectedProfile roamProfile;
4617 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
4618 struct cfg80211_bss *bss = NULL;
4619
4620 ENTER();
4621
4622 memset(&roamProfile, 0, sizeof(tCsrRoamConnectedProfile));
4623 sme_RoamGetConnectProfile(hHal, pAdapter->sessionId, &roamProfile);
4624
4625 if (NULL != roamProfile.pBssDesc)
4626 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304627 bss = wlan_hdd_cfg80211_inform_bss(pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07004628 &roamProfile);
4629
4630 if (NULL == bss)
4631 {
4632 hddLog(VOS_TRACE_LEVEL_INFO, "%s: cfg80211_inform_bss return NULL",
4633 __func__);
4634 }
4635
4636 sme_RoamFreeConnectProfile(hHal, &roamProfile);
4637 }
4638 else
4639 {
4640 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: roamProfile.pBssDesc is NULL",
4641 __func__);
4642 }
4643 return bss;
4644}
4645
4646/*
4647 * FUNCTION: wlan_hdd_cfg80211_update_bss
4648 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304649static int wlan_hdd_cfg80211_update_bss( struct wiphy *wiphy,
4650 hdd_adapter_t *pAdapter
Jeff Johnson295189b2012-06-20 16:38:30 -07004651 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304652{
Jeff Johnson295189b2012-06-20 16:38:30 -07004653 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
4654 tCsrScanResultInfo *pScanResult;
4655 eHalStatus status = 0;
4656 tScanResultHandle pResult;
4657 struct cfg80211_bss *bss_status = NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -07004658 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07004659
4660 ENTER();
4661
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05304662 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
4663 TRACE_CODE_HDD_CFG80211_UPDATE_BSS,
4664 NO_SESSION, pAdapter->sessionId));
4665
Wilson Yangf80a0542013-10-07 13:02:37 -07004666 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
4667
4668 if (pHddCtx->isLogpInProgress)
Jeff Johnson295189b2012-06-20 16:38:30 -07004669 {
Wilson Yangf80a0542013-10-07 13:02:37 -07004670 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
4671 "%s:LOGP in Progress. Ignore!!!",__func__);
4672 return -EAGAIN;
Jeff Johnson295189b2012-06-20 16:38:30 -07004673 }
4674
Wilson Yangf80a0542013-10-07 13:02:37 -07004675
4676 /*bss_update is not allowed during wlan driver loading or unloading*/
Mihir Shete18156292014-03-11 15:38:30 +05304677 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Wilson Yangf80a0542013-10-07 13:02:37 -07004678 {
4679 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4680 "%s:Loading_unloading in Progress. Ignore!!!",__func__);
4681 return VOS_STATUS_E_PERM;
4682 }
4683
4684
Jeff Johnson295189b2012-06-20 16:38:30 -07004685 /*
4686 * start getting scan results and populate cgf80211 BSS database
4687 */
4688 status = sme_ScanGetResult(hHal, pAdapter->sessionId, NULL, &pResult);
4689
4690 /* no scan results */
4691 if (NULL == pResult)
4692 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05304693 hddLog(VOS_TRACE_LEVEL_INFO, "%s: No scan result Status %d",
4694 __func__, status);
Jeff Johnson295189b2012-06-20 16:38:30 -07004695 return status;
4696 }
4697
4698 pScanResult = sme_ScanResultGetFirst(hHal, pResult);
4699
4700 while (pScanResult)
4701 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304702 /*
4703 * cfg80211_inform_bss() is not updating ie field of bss entry, if
4704 * entry already exists in bss data base of cfg80211 for that
4705 * particular BSS ID. Using cfg80211_inform_bss_frame to update the
4706 * bss entry instead of cfg80211_inform_bss, But this call expects
4707 * mgmt packet as input. As of now there is no possibility to get
4708 * the mgmt(probe response) frame from PE, converting bss_desc to
Jeff Johnson295189b2012-06-20 16:38:30 -07004709 * ieee80211_mgmt(probe response) and passing to c
4710 * fg80211_inform_bss_frame.
4711 * */
4712
4713 bss_status = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
4714 &pScanResult->BssDescriptor);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304715
Jeff Johnson295189b2012-06-20 16:38:30 -07004716
4717 if (NULL == bss_status)
4718 {
4719 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -08004720 "%s: NULL returned by cfg80211_inform_bss", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004721 }
4722 else
4723 {
Yue Maf49ba872013-08-19 12:04:25 -07004724 cfg80211_put_bss(
4725#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0))
4726 wiphy,
4727#endif
4728 bss_status);
Jeff Johnson295189b2012-06-20 16:38:30 -07004729 }
4730
4731 pScanResult = sme_ScanResultGetNext(hHal, pResult);
4732 }
4733
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304734 sme_ScanResultPurge(hHal, pResult);
Jeff Johnson295189b2012-06-20 16:38:30 -07004735
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304736 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07004737}
4738
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004739void
4740hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel)
4741{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304742 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussaina7c8e412013-11-20 11:06:42 -08004743 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(macAddr));
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004744} /****** end hddPrintMacAddr() ******/
4745
4746void
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07004747hddPrintPmkId(tANI_U8 *pmkId, tANI_U8 logLevel)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004748{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304749 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussain6d2a3322013-11-17 19:50:10 -08004750 "%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X",
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07004751 pmkId[0], pmkId[1], pmkId[2], pmkId[3], pmkId[4],
4752 pmkId[5], pmkId[6], pmkId[7], pmkId[8], pmkId[9], pmkId[10],
4753 pmkId[11], pmkId[12], pmkId[13], pmkId[14], pmkId[15]);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004754} /****** end hddPrintPmkId() ******/
4755
4756//hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel);
4757//hddPrintMacAddr(macAddr, VOS_TRACE_LEVEL_FATAL);
4758
4759//void sirDumpBuf(tpAniSirGlobal pMac, tANI_U8 modId, tANI_U32 level, tANI_U8 *buf, tANI_U32 size);
4760//sirDumpBuf(pMac, VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, pmkid, 16);
4761
4762#define dump_bssid(bssid) \
4763 { \
Jeff Johnsone7245742012-09-05 17:12:55 -07004764 hddLog(VOS_TRACE_LEVEL_INFO, "BSSID (MAC) address:\t"); \
4765 hddPrintMacAddr(bssid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004766 }
4767
4768#define dump_pmkid(pMac, pmkid) \
4769 { \
Jeff Johnsone7245742012-09-05 17:12:55 -07004770 hddLog(VOS_TRACE_LEVEL_INFO, "PMKSA-ID:\t"); \
4771 hddPrintPmkId(pmkid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004772 }
4773
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -07004774#if defined(FEATURE_WLAN_LFR) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004775/*
4776 * FUNCTION: wlan_hdd_cfg80211_pmksa_candidate_notify
4777 * This function is used to notify the supplicant of a new PMKSA candidate.
4778 */
4779int wlan_hdd_cfg80211_pmksa_candidate_notify(
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304780 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004781 int index, bool preauth )
4782{
Jeff Johnsone7245742012-09-05 17:12:55 -07004783#ifdef FEATURE_WLAN_OKC
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004784 struct net_device *dev = pAdapter->dev;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004785 hdd_context_t *pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004786
4787 ENTER();
Jeff Johnsone7245742012-09-05 17:12:55 -07004788 hddLog(VOS_TRACE_LEVEL_INFO, "%s is going to notify supplicant of:", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004789
4790 if( NULL == pRoamInfo )
4791 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08004792 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pRoamInfo is NULL", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004793 return -EINVAL;
4794 }
4795
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004796 if (eANI_BOOLEAN_TRUE == hdd_is_okc_mode_enabled(pHddCtx))
4797 {
4798 dump_bssid(pRoamInfo->bssid);
4799 cfg80211_pmksa_candidate_notify(dev, index,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004800 pRoamInfo->bssid, preauth, GFP_KERNEL);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004801 }
Jeff Johnsone7245742012-09-05 17:12:55 -07004802#endif /* FEATURE_WLAN_OKC */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304803 return 0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004804}
4805#endif //FEATURE_WLAN_LFR
4806
Yue Maef608272013-04-08 23:09:17 -07004807#ifdef FEATURE_WLAN_LFR_METRICS
4808/*
4809 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth
4810 * 802.11r/LFR metrics reporting function to report preauth initiation
4811 *
4812 */
4813#define MAX_LFR_METRICS_EVENT_LENGTH 100
4814VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth(hdd_adapter_t *pAdapter,
4815 tCsrRoamInfo *pRoamInfo)
4816{
4817 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
4818 union iwreq_data wrqu;
4819
4820 ENTER();
4821
4822 if (NULL == pAdapter)
4823 {
4824 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
4825 return VOS_STATUS_E_FAILURE;
4826 }
4827
4828 /* create the event */
4829 memset(&wrqu, 0, sizeof(wrqu));
4830 memset(metrics_notification, 0, sizeof(metrics_notification));
4831
4832 wrqu.data.pointer = metrics_notification;
4833 wrqu.data.length = scnprintf(metrics_notification,
4834 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_INIT "
4835 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
4836
4837 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
4838
4839 EXIT();
4840
4841 return VOS_STATUS_SUCCESS;
4842}
4843
4844/*
4845 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth_status
4846 * 802.11r/LFR metrics reporting function to report preauth completion
4847 * or failure
4848 */
4849VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth_status(
4850 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo, bool preauth_status)
4851{
4852 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
4853 union iwreq_data wrqu;
4854
4855 ENTER();
4856
4857 if (NULL == pAdapter)
4858 {
4859 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
4860 return VOS_STATUS_E_FAILURE;
4861 }
4862
4863 /* create the event */
4864 memset(&wrqu, 0, sizeof(wrqu));
4865 memset(metrics_notification, 0, sizeof(metrics_notification));
4866
4867 scnprintf(metrics_notification, sizeof(metrics_notification),
4868 "QCOM: LFR_PREAUTH_STATUS "MAC_ADDRESS_STR,
4869 MAC_ADDR_ARRAY(pRoamInfo->bssid));
4870
4871 if (1 == preauth_status)
4872 strncat(metrics_notification, " TRUE", 5);
4873 else
4874 strncat(metrics_notification, " FALSE", 6);
4875
4876 wrqu.data.pointer = metrics_notification;
4877 wrqu.data.length = strlen(metrics_notification);
4878
4879 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
4880
4881 EXIT();
4882
4883 return VOS_STATUS_SUCCESS;
4884}
4885
4886/*
4887 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_handover
4888 * 802.11r/LFR metrics reporting function to report handover initiation
4889 *
4890 */
4891VOS_STATUS wlan_hdd_cfg80211_roam_metrics_handover(hdd_adapter_t * pAdapter,
4892 tCsrRoamInfo *pRoamInfo)
4893{
4894 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
4895 union iwreq_data wrqu;
4896
4897 ENTER();
4898
4899 if (NULL == pAdapter)
4900 {
4901 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
4902 return VOS_STATUS_E_FAILURE;
4903 }
4904
4905 /* create the event */
4906 memset(&wrqu, 0, sizeof(wrqu));
4907 memset(metrics_notification, 0, sizeof(metrics_notification));
4908
4909 wrqu.data.pointer = metrics_notification;
4910 wrqu.data.length = scnprintf(metrics_notification,
4911 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_HANDOVER "
4912 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
4913
4914 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
4915
4916 EXIT();
4917
4918 return VOS_STATUS_SUCCESS;
4919}
4920#endif
4921
Jeff Johnson295189b2012-06-20 16:38:30 -07004922/*
4923 * FUNCTION: hdd_cfg80211_scan_done_callback
4924 * scanning callback function, called after finishing scan
4925 *
4926 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304927static eHalStatus hdd_cfg80211_scan_done_callback(tHalHandle halHandle,
Jeff Johnson295189b2012-06-20 16:38:30 -07004928 void *pContext, tANI_U32 scanId, eCsrScanStatus status)
4929{
4930 struct net_device *dev = (struct net_device *) pContext;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304931 //struct wireless_dev *wdev = dev->ieee80211_ptr;
Jeff Johnson295189b2012-06-20 16:38:30 -07004932 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07004933 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
4934 hdd_scaninfo_t *pScanInfo = &pHddCtx->scan_info;
Jeff Johnson295189b2012-06-20 16:38:30 -07004935 struct cfg80211_scan_request *req = NULL;
4936 int ret = 0;
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +05304937 bool aborted = false;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05304938 long waitRet = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07004939
4940 ENTER();
4941
4942 hddLog(VOS_TRACE_LEVEL_INFO,
4943 "%s called with halHandle = %p, pContext = %p,"
Arif Hussain6d2a3322013-11-17 19:50:10 -08004944 "scanID = %d, returned status = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07004945 __func__, halHandle, pContext, (int) scanId, (int) status);
4946
Kiet Lamac06e2c2013-10-23 16:25:07 +05304947 pScanInfo->mScanPendingCounter = 0;
4948
Jeff Johnson295189b2012-06-20 16:38:30 -07004949 //Block on scan req completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +05304950 waitRet = wait_for_completion_interruptible_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07004951 &pScanInfo->scan_req_completion_event,
4952 msecs_to_jiffies(WLAN_WAIT_TIME_SCAN_REQ));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05304953 if (waitRet <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -07004954 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05304955 hddLog(VOS_TRACE_LEVEL_ERROR,
4956 "%s wait on scan_req_completion_event failed %ld",__func__, waitRet);
Jeff Johnson295189b2012-06-20 16:38:30 -07004957 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -07004958 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -07004959 }
4960
Yue Maef608272013-04-08 23:09:17 -07004961 if (pScanInfo->mScanPending != VOS_TRUE)
Jeff Johnson295189b2012-06-20 16:38:30 -07004962 {
4963 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -07004964 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -07004965 }
4966
4967 /* Check the scanId */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304968 if (pScanInfo->scanId != scanId)
Jeff Johnson295189b2012-06-20 16:38:30 -07004969 {
4970 hddLog(VOS_TRACE_LEVEL_INFO,
4971 "%s called with mismatched scanId pScanInfo->scanId = %d "
Arif Hussain6d2a3322013-11-17 19:50:10 -08004972 "scanId = %d", __func__, (int) pScanInfo->scanId,
Jeff Johnson295189b2012-06-20 16:38:30 -07004973 (int) scanId);
4974 }
4975
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304976 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07004977 pAdapter);
4978
4979 if (0 > ret)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304980 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004981
4982
4983 /* If any client wait scan result through WEXT
4984 * send scan done event to client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07004985 if (pHddCtx->scan_info.waitScanResult)
Jeff Johnson295189b2012-06-20 16:38:30 -07004986 {
4987 /* The other scan request waiting for current scan finish
4988 * Send event to notify current scan finished */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07004989 if(WEXT_SCAN_PENDING_DELAY == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -07004990 {
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07004991 vos_event_set(&pHddCtx->scan_info.scan_finished_event);
Jeff Johnson295189b2012-06-20 16:38:30 -07004992 }
4993 /* Send notify to WEXT client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07004994 else if(WEXT_SCAN_PENDING_PIGGYBACK == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -07004995 {
4996 struct net_device *dev = pAdapter->dev;
4997 union iwreq_data wrqu;
4998 int we_event;
4999 char *msg;
5000
5001 memset(&wrqu, '\0', sizeof(wrqu));
5002 we_event = SIOCGIWSCAN;
5003 msg = NULL;
5004 wireless_send_event(dev, we_event, &wrqu, msg);
5005 }
5006 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07005007 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07005008
5009 /* Get the Scan Req */
5010 req = pAdapter->request;
5011
5012 if (!req)
5013 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08005014 hddLog(VOS_TRACE_LEVEL_ERROR, "request is became NULL");
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07005015 pScanInfo->mScanPending = VOS_FALSE;
Jeff Johnsone7245742012-09-05 17:12:55 -07005016 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -07005017 }
5018
5019 /*
5020 * setting up 0, just in case.
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305021 */
Jeff Johnson295189b2012-06-20 16:38:30 -07005022 req->n_ssids = 0;
5023 req->n_channels = 0;
5024 req->ie = 0;
5025
Jeff Johnson295189b2012-06-20 16:38:30 -07005026 pAdapter->request = NULL;
Jeff Johnsone7245742012-09-05 17:12:55 -07005027 /* Scan is no longer pending */
5028 pScanInfo->mScanPending = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07005029
Madan Mohan Koyyalamudib764bf82012-10-11 16:38:51 -07005030 /*
5031 * cfg80211_scan_done informing NL80211 about completion
5032 * of scanning
5033 */
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +05305034 if (status == eCSR_SCAN_ABORT || status == eCSR_SCAN_FAILURE)
5035 {
5036 aborted = true;
5037 }
5038 cfg80211_scan_done(req, aborted);
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -08005039 complete(&pScanInfo->abortscan_event_var);
Jeff Johnson295189b2012-06-20 16:38:30 -07005040
Jeff Johnsone7245742012-09-05 17:12:55 -07005041allow_suspend:
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07005042 /* release the wake lock at the end of the scan*/
5043 hdd_allow_suspend();
Jeff Johnsone7245742012-09-05 17:12:55 -07005044
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -07005045 /* Acquire wakelock to handle the case where APP's tries to suspend
5046 * immediatly after the driver gets connect request(i.e after scan)
5047 * from supplicant, this result in app's is suspending and not able
5048 * to process the connect request to AP */
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +05305049 hdd_prevent_suspend_timeout(1000);
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -07005050
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07005051#ifdef FEATURE_WLAN_TDLS
5052 wlan_hdd_tdls_scan_done_callback(pAdapter);
5053#endif
5054
Jeff Johnson295189b2012-06-20 16:38:30 -07005055 EXIT();
5056 return 0;
5057}
5058
5059/*
Rashmi Ramannab1429032014-04-26 14:59:09 +05305060 * FUNCTION: hdd_isConnectionInProgress
5061 * Go through each adapter and check if Connection is in progress
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08005062 *
5063 */
Rashmi Ramannab1429032014-04-26 14:59:09 +05305064v_BOOL_t hdd_isConnectionInProgress( hdd_context_t *pHddCtx )
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08005065{
5066 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
5067 hdd_station_ctx_t *pHddStaCtx = NULL;
5068 hdd_adapter_t *pAdapter = NULL;
5069 VOS_STATUS status = 0;
5070 v_U8_t staId = 0;
5071 v_U8_t *staMac = NULL;
5072
c_hpothu9b781ba2013-12-30 20:57:45 +05305073 if (TRUE == pHddCtx->btCoexModeSet)
5074 {
5075 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Rashmi Ramannab1429032014-04-26 14:59:09 +05305076 FL("BTCoex Mode operation in progress"));
5077 return VOS_TRUE;
c_hpothu9b781ba2013-12-30 20:57:45 +05305078 }
5079
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08005080 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
5081
5082 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
5083 {
5084 pAdapter = pAdapterNode->pAdapter;
5085
5086 if( pAdapter )
5087 {
5088 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05305089 "%s: Adapter with device mode %s (%d) exists",
5090 __func__, hdd_device_modetoString(pAdapter->device_mode),
5091 pAdapter->device_mode);
Rashmi Ramannab1429032014-04-26 14:59:09 +05305092 if (((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
5093 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
5094 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode)) &&
5095 (eConnectionState_Connecting ==
5096 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
5097 {
5098 hddLog(VOS_TRACE_LEVEL_ERROR,
5099 "%s: %p(%d) Connection is in progress", __func__,
5100 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
5101 return VOS_TRUE;
5102 }
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08005103 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05305104 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
5105 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08005106 {
5107 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
5108 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05305109 (VOS_FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08005110 {
5111 staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]);
5112 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain24bafea2013-11-15 15:10:03 -08005113 "%s: client " MAC_ADDRESS_STR
5114 " is in the middle of WPS/EAPOL exchange.", __func__,
5115 MAC_ADDR_ARRAY(staMac));
Rashmi Ramannab1429032014-04-26 14:59:09 +05305116 return VOS_TRUE;
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08005117 }
5118 }
5119 else if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) ||
5120 (WLAN_HDD_P2P_GO == pAdapter->device_mode))
5121 {
5122 for (staId = 0; staId < WLAN_MAX_STA_COUNT; staId++)
5123 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305124 if ((pAdapter->aStaInfo[staId].isUsed) &&
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08005125 (WLANTL_STA_CONNECTED == pAdapter->aStaInfo[staId].tlSTAState))
5126 {
5127 staMac = (v_U8_t *) &(pAdapter->aStaInfo[staId].macAddrSTA.bytes[0]);
5128
5129 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain24bafea2013-11-15 15:10:03 -08005130 "%s: client " MAC_ADDRESS_STR " of SoftAP/P2P-GO is in the "
5131 "middle of WPS/EAPOL exchange.", __func__,
5132 MAC_ADDR_ARRAY(staMac));
Rashmi Ramannab1429032014-04-26 14:59:09 +05305133 return VOS_TRUE;
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08005134 }
5135 }
5136 }
5137 }
5138 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
5139 pAdapterNode = pNext;
5140 }
Rashmi Ramannab1429032014-04-26 14:59:09 +05305141 return VOS_FALSE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305142}
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08005143
5144/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +05305145 * FUNCTION: __wlan_hdd_cfg80211_scan
Jeff Johnson295189b2012-06-20 16:38:30 -07005146 * this scan respond to scan trigger and update cfg80211 scan database
5147 * later, scan dump command can be used to recieve scan results
5148 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +05305149int __wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -08005150#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
5151 struct net_device *dev,
5152#endif
5153 struct cfg80211_scan_request *request)
5154{
Siddharth Bhal0c162d02014-05-06 19:50:42 +05305155 hdd_adapter_t *pAdapter = NULL;
5156 hdd_context_t *pHddCtx = NULL;
5157 hdd_wext_state_t *pwextBuf = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305158 hdd_config_t *cfg_param = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07005159 tCsrScanRequest scanRequest;
5160 tANI_U8 *channelList = NULL, i;
5161 v_U32_t scanId = 0;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305162 int status;
5163 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07005164 v_U8_t* pP2pIe = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07005165
Siddharth Bhal0c162d02014-05-06 19:50:42 +05305166#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
5167 struct net_device *dev = NULL;
5168 if (NULL == request)
5169 {
5170 hddLog(VOS_TRACE_LEVEL_ERROR,
5171 "%s: scan req param null", __func__);
5172 return -EINVAL;
5173 }
5174 dev = request->wdev->netdev;
5175#endif
5176
5177 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
5178 pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
5179 pwextBuf = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
5180
Jeff Johnson295189b2012-06-20 16:38:30 -07005181 ENTER();
5182
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05305183
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05305184 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
5185 __func__, hdd_device_modetoString(pAdapter->device_mode),
5186 pAdapter->device_mode);
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08005187
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305188 status = wlan_hdd_validate_context(pHddCtx);
5189
5190 if (0 != status)
5191 {
5192 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5193 "%s: HDD context is not valid", __func__);
5194 return status;
5195 }
5196
Siddharth Bhal0c162d02014-05-06 19:50:42 +05305197 if (NULL == pwextBuf)
5198 {
5199 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: invalid WEXT state\n",
5200 __func__);
5201 return -EIO;
5202 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305203 cfg_param = pHddCtx->cfg_ini;
5204 pScanInfo = &pHddCtx->scan_info;
5205
Jeff Johnson295189b2012-06-20 16:38:30 -07005206#ifdef WLAN_BTAMP_FEATURE
5207 //Scan not supported when AMP traffic is on.
Gopichand Nakkala681989c2013-03-06 22:27:48 -08005208 if (VOS_TRUE == WLANBAP_AmpSessionOn())
Jeff Johnson295189b2012-06-20 16:38:30 -07005209 {
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08005210 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07005211 "%s: No scanning when AMP is on", __func__);
5212 return -EOPNOTSUPP;
5213 }
5214#endif
5215 //Scan on any other interface is not supported.
Gopichand Nakkala681989c2013-03-06 22:27:48 -08005216 if (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07005217 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -08005218 hddLog(VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05305219 "%s: Not scanning on device_mode = %s (%d)",
5220 __func__, hdd_device_modetoString(pAdapter->device_mode),
5221 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07005222 return -EOPNOTSUPP;
5223 }
5224
5225 if (TRUE == pScanInfo->mScanPending)
5226 {
Kiet Lamac06e2c2013-10-23 16:25:07 +05305227 if ( MAX_PENDING_LOG > pScanInfo->mScanPendingCounter++ )
5228 {
5229 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: mScanPending is TRUE", __func__);
5230 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08005231 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -07005232 }
5233
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305234 //Don't Allow Scan and return busy if Remain On
Jeff Johnson32d95a32012-09-10 13:15:23 -07005235 //Channel and action frame is pending
5236 //Otherwise Cancel Remain On Channel and allow Scan
5237 //If no action frame pending
Gopichand Nakkala681989c2013-03-06 22:27:48 -08005238 if (0 != wlan_hdd_check_remain_on_channel(pAdapter))
Jeff Johnson32d95a32012-09-10 13:15:23 -07005239 {
Kiet Lamac06e2c2013-10-23 16:25:07 +05305240 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Remain On Channel Pending", __func__);
Jeff Johnson32d95a32012-09-10 13:15:23 -07005241 return -EBUSY;
5242 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08005243#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07005244 /* if tdls disagree scan right now, return immediately.
5245 tdls will schedule the scan when scan is allowed. (return SUCCESS)
5246 or will reject the scan if any TDLS is in progress. (return -EBUSY)
5247 */
5248 status = wlan_hdd_tdls_scan_callback (pAdapter,
5249 wiphy,
5250#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
5251 dev,
Gopichand Nakkalac3c42b92013-03-20 19:42:34 -07005252#endif
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07005253 request);
5254 if(status <= 0)
5255 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05305256 if(!status)
5257 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS in progress."
5258 "scan rejected %d", __func__, status);
5259 else
5260 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS teardown is ongoing %d",
5261 __func__, status);
5262
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07005263 return status;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08005264 }
5265#endif
Jeff Johnson32d95a32012-09-10 13:15:23 -07005266
Jeff Johnson295189b2012-06-20 16:38:30 -07005267 if (mutex_lock_interruptible(&pHddCtx->tmInfo.tmOperationLock))
5268 {
5269 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_ERROR,
Jeff Johnson1250df42012-12-10 14:31:52 -08005270 "%s: Acquire lock fail", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005271 return -EAGAIN;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305272 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005273 if (TRUE == pHddCtx->tmInfo.tmAction.enterImps)
5274 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05305275 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07005276 "%s: MAX TM Level Scan not allowed", __func__);
5277 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305278 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -07005279 }
5280 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
5281
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08005282 /* Check if scan is allowed at this point of time.
5283 */
Rashmi Ramannab1429032014-04-26 14:59:09 +05305284 if (hdd_isConnectionInProgress(pHddCtx))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08005285 {
5286 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Scan not allowed", __func__);
5287 return -EBUSY;
5288 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305289
Jeff Johnson295189b2012-06-20 16:38:30 -07005290 vos_mem_zero( &scanRequest, sizeof(scanRequest));
5291
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05305292 hddLog(VOS_TRACE_LEVEL_INFO, "scan request for ssid = %d",
5293 (int)request->n_ssids);
5294
5295 /* Even though supplicant doesn't provide any SSIDs, n_ssids is set to 1.
5296 * Becasue of this, driver is assuming that this is not wildcard scan and so
5297 * is not aging out the scan results.
5298 */
5299 if (request->ssids && '\0' == request->ssids->ssid[0])
Jeff Johnson295189b2012-06-20 16:38:30 -07005300 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05305301 request->n_ssids = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07005302 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05305303
5304 if ((request->ssids) && (0 < request->n_ssids))
5305 {
5306 tCsrSSIDInfo *SsidInfo;
5307 int j;
5308 scanRequest.SSIDs.numOfSSIDs = request->n_ssids;
5309 /* Allocate num_ssid tCsrSSIDInfo structure */
5310 SsidInfo = scanRequest.SSIDs.SSIDList =
5311 ( tCsrSSIDInfo *)vos_mem_malloc(
5312 request->n_ssids*sizeof(tCsrSSIDInfo));
5313
5314 if(NULL == scanRequest.SSIDs.SSIDList)
5315 {
5316 hddLog(VOS_TRACE_LEVEL_ERROR,
5317 "%s: memory alloc failed SSIDInfo buffer", __func__);
5318 return -ENOMEM;
5319 }
5320
5321 /* copy all the ssid's and their length */
5322 for(j = 0; j < request->n_ssids; j++, SsidInfo++)
5323 {
5324 /* get the ssid length */
5325 SsidInfo->SSID.length = request->ssids[j].ssid_len;
5326 vos_mem_copy(SsidInfo->SSID.ssId, &request->ssids[j].ssid[0],
5327 SsidInfo->SSID.length);
5328 SsidInfo->SSID.ssId[SsidInfo->SSID.length] = '\0';
5329 hddLog(VOS_TRACE_LEVEL_INFO, "SSID number %d: %s",
5330 j, SsidInfo->SSID.ssId);
5331 }
5332 /* set the scan type to active */
5333 scanRequest.scanType = eSIR_ACTIVE_SCAN;
5334 }
5335 else if(WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -07005336 {
Siddharth Bhal0c162d02014-05-06 19:50:42 +05305337 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
5338 TRACE_CODE_HDD_CFG80211_SCAN,
5339 pAdapter->sessionId, 0));
Jeff Johnson295189b2012-06-20 16:38:30 -07005340 /* set the scan type to active */
5341 scanRequest.scanType = eSIR_ACTIVE_SCAN;
Jeff Johnson295189b2012-06-20 16:38:30 -07005342 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05305343 else
5344 {
5345 /*Set the scan type to default type, in this case it is ACTIVE*/
5346 scanRequest.scanType = pScanInfo->scan_mode;
5347 }
5348 scanRequest.minChnTime = cfg_param->nActiveMinChnTime;
5349 scanRequest.maxChnTime = cfg_param->nActiveMaxChnTime;
Jeff Johnson295189b2012-06-20 16:38:30 -07005350
5351 /* set BSSType to default type */
5352 scanRequest.BSSType = eCSR_BSS_TYPE_ANY;
5353
5354 /*TODO: scan the requested channels only*/
5355
5356 /*Right now scanning all the channels */
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05305357 if (MAX_CHANNEL < request->n_channels)
Jeff Johnson295189b2012-06-20 16:38:30 -07005358 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05305359 hddLog(VOS_TRACE_LEVEL_WARN,
5360 "No of Scan Channels exceeded limit: %d", request->n_channels);
5361 request->n_channels = MAX_CHANNEL;
5362 }
5363
5364 hddLog(VOS_TRACE_LEVEL_INFO,
5365 "No of Scan Channels: %d", request->n_channels);
5366
5367
5368 if( request->n_channels )
5369 {
5370 char chList [(request->n_channels*5)+1];
5371 int len;
5372 channelList = vos_mem_malloc( request->n_channels );
5373 if( NULL == channelList )
c_hpothu53512302014-04-15 18:49:53 +05305374 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05305375 hddLog(VOS_TRACE_LEVEL_ERROR,
5376 "%s: memory alloc failed channelList", __func__);
5377 status = -ENOMEM;
5378 goto free_mem;
c_hpothu53512302014-04-15 18:49:53 +05305379 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05305380
5381 for( i = 0, len = 0; i < request->n_channels ; i++ )
5382 {
5383 channelList[i] = request->channels[i]->hw_value;
5384 len += snprintf(chList+len, 5, "%d ", channelList[i]);
5385 }
5386
Nirav Shah20ac06f2013-12-12 18:14:06 +05305387 hddLog(VOS_TRACE_LEVEL_INFO,
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05305388 "Channel-List: %s ", chList);
5389 }
c_hpothu53512302014-04-15 18:49:53 +05305390
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05305391 scanRequest.ChannelInfo.numOfChannels = request->n_channels;
5392 scanRequest.ChannelInfo.ChannelList = channelList;
5393
5394 /* set requestType to full scan */
5395 scanRequest.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
5396
5397 /* Flush the scan results(only p2p beacons) for STA scan and P2P
5398 * search (Flush on both full scan and social scan but not on single
5399 * channel scan).P2P search happens on 3 social channels (1, 6, 11)
5400 */
5401
5402 /* Supplicant does single channel scan after 8-way handshake
5403 * and in that case driver shoudnt flush scan results. If
5404 * driver flushes the scan results here and unfortunately if
5405 * the AP doesnt respond to our probe req then association
5406 * fails which is not desired
5407 */
5408
5409 if( request->n_channels != WLAN_HDD_P2P_SINGLE_CHANNEL_SCAN )
5410 {
5411 hddLog(VOS_TRACE_LEVEL_DEBUG, "Flushing P2P Results");
5412 sme_ScanFlushP2PResult( WLAN_HDD_GET_HAL_CTX(pAdapter),
5413 pAdapter->sessionId );
5414 }
5415
5416 if( request->ie_len )
5417 {
5418 /* save this for future association (join requires this) */
5419 /*TODO: Array needs to be converted to dynamic allocation,
5420 * as multiple ie.s can be sent in cfg80211_scan_request structure
5421 * CR 597966
5422 */
5423 memset( &pScanInfo->scanAddIE, 0, sizeof(pScanInfo->scanAddIE) );
5424 memcpy( pScanInfo->scanAddIE.addIEdata, request->ie, request->ie_len);
5425 pScanInfo->scanAddIE.length = request->ie_len;
5426
5427 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
5428 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
5429 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -07005430 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05305431 if ( request->ie_len <= SIR_MAC_MAX_IE_LENGTH)
Jeff Johnson295189b2012-06-20 16:38:30 -07005432 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05305433 pwextBuf->roamProfile.nAddIEScanLength = request->ie_len;
5434 memcpy( pwextBuf->roamProfile.addIEScan,
5435 request->ie, request->ie_len);
5436 }
5437 else
5438 {
5439 hddLog(VOS_TRACE_LEVEL_ERROR, "Scan Ie length is invalid:"
5440 "%zu", request->ie_len);
Jeff Johnson295189b2012-06-20 16:38:30 -07005441 }
5442
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05305443 }
5444 scanRequest.uIEFieldLen = pScanInfo->scanAddIE.length;
5445 scanRequest.pIEField = pScanInfo->scanAddIE.addIEdata;
5446
5447 pP2pIe = wlan_hdd_get_p2p_ie_ptr((v_U8_t*)request->ie,
5448 request->ie_len);
5449 if (pP2pIe != NULL)
5450 {
5451#ifdef WLAN_FEATURE_P2P_DEBUG
5452 if (((globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED) ||
5453 (globalP2PConnectionStatus == P2P_GO_NEG_PROCESS)) &&
5454 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Nirav Shah20ac06f2013-12-12 18:14:06 +05305455 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05305456 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_1;
5457 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
5458 "Go nego completed to Connection is started");
5459 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
5460 "for 8way Handshake");
Nirav Shah20ac06f2013-12-12 18:14:06 +05305461 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05305462 else if((globalP2PConnectionStatus == P2P_CLIENT_DISCONNECTED_STATE) &&
5463 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -07005464 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05305465 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_2;
5466 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
5467 "Disconnected state to Connection is started");
5468 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
5469 "for 4way Handshake");
5470 }
5471#endif
5472
5473 /* no_cck will be set during p2p find to disable 11b rates */
5474 if(TRUE == request->no_cck)
5475 {
5476 hddLog(VOS_TRACE_LEVEL_INFO,
5477 "%s: This is a P2P Search", __func__);
5478 scanRequest.p2pSearch = 1;
5479
5480 if( request->n_channels == WLAN_HDD_P2P_SOCIAL_CHANNELS )
Agarwal Ashish4f616132013-12-30 23:32:50 +05305481 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05305482 /* set requestType to P2P Discovery */
5483 scanRequest.requestType = eCSR_SCAN_P2P_DISCOVERY;
5484 }
5485
5486 /*
5487 Skip Dfs Channel in case of P2P Search
5488 if it is set in ini file
5489 */
5490 if(cfg_param->skipDfsChnlInP2pSearch)
5491 {
5492 scanRequest.skipDfsChnlInP2pSearch = 1;
Agarwal Ashish4f616132013-12-30 23:32:50 +05305493 }
5494 else
5495 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +05305496 scanRequest.skipDfsChnlInP2pSearch = 0;
Agarwal Ashish4f616132013-12-30 23:32:50 +05305497 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005498
Agarwal Ashish4f616132013-12-30 23:32:50 +05305499 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005500 }
5501 }
5502
5503 INIT_COMPLETION(pScanInfo->scan_req_completion_event);
5504
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07005505 /* acquire the wakelock to avoid the apps suspend during the scan. To
5506 * address the following issues.
5507 * 1) Disconnected scenario: we are not allowing the suspend as WLAN is not in
5508 * BMPS/IMPS this result in android trying to suspend aggressively and backing off
5509 * for long time, this result in apps running at full power for long time.
5510 * 2) Connected scenario: If we allow the suspend during the scan, RIVA will
5511 * be stuck in full power because of resume BMPS
5512 */
5513 hdd_prevent_suspend();
Jeff Johnsone7245742012-09-05 17:12:55 -07005514
Nirav Shah20ac06f2013-12-12 18:14:06 +05305515 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
5516 "requestType %d, scanType %d, minChnTime %d, maxChnTime %d,"
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05305517 "p2pSearch %d, skipDfsChnlInP2pSearch %d",
5518 scanRequest.requestType, scanRequest.scanType,
5519 scanRequest.minChnTime, scanRequest.maxChnTime,
Nirav Shah20ac06f2013-12-12 18:14:06 +05305520 scanRequest.p2pSearch, scanRequest.skipDfsChnlInP2pSearch);
5521
Jeff Johnsone7245742012-09-05 17:12:55 -07005522 status = sme_ScanRequest( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07005523 pAdapter->sessionId, &scanRequest, &scanId,
5524 &hdd_cfg80211_scan_done_callback, dev );
Jeff Johnsone7245742012-09-05 17:12:55 -07005525
Jeff Johnson295189b2012-06-20 16:38:30 -07005526 if (eHAL_STATUS_SUCCESS != status)
5527 {
5528 hddLog(VOS_TRACE_LEVEL_ERROR,
5529 "%s: sme_ScanRequest returned error %d", __func__, status);
5530 complete(&pScanInfo->scan_req_completion_event);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -07005531 if(eHAL_STATUS_RESOURCES == status)
5532 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05305533 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: HO is in progress."
5534 "So defer the scan by informing busy",__func__);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -07005535 status = -EBUSY;
5536 } else {
5537 status = -EIO;
5538 }
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07005539 hdd_allow_suspend();
Jeff Johnson295189b2012-06-20 16:38:30 -07005540 goto free_mem;
5541 }
5542
5543 pScanInfo->mScanPending = TRUE;
5544 pAdapter->request = request;
5545 pScanInfo->scanId = scanId;
5546
5547 complete(&pScanInfo->scan_req_completion_event);
5548
5549free_mem:
5550 if( scanRequest.SSIDs.SSIDList )
5551 {
5552 vos_mem_free(scanRequest.SSIDs.SSIDList);
5553 }
5554
5555 if( channelList )
5556 vos_mem_free( channelList );
5557
5558 EXIT();
5559
5560 return status;
5561}
5562
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +05305563int wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
5564#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
5565 struct net_device *dev,
5566#endif
5567 struct cfg80211_scan_request *request)
5568{
5569 int ret;
5570
5571 vos_ssr_protect(__func__);
5572 ret = __wlan_hdd_cfg80211_scan(wiphy,
5573#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
5574 dev,
5575#endif
5576 request);
5577 vos_ssr_unprotect(__func__);
5578
5579 return ret;
5580}
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07005581
5582void hdd_select_cbmode( hdd_adapter_t *pAdapter,v_U8_t operationChannel)
5583{
5584 v_U8_t iniDot11Mode =
5585 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->dot11Mode;
5586 eHddDot11Mode hddDot11Mode = iniDot11Mode;
5587
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +05305588 hddLog(LOG1, FL("Channel Bonding Mode Selected is %u"),
5589 iniDot11Mode);
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07005590 switch ( iniDot11Mode )
5591 {
5592 case eHDD_DOT11_MODE_AUTO:
5593 case eHDD_DOT11_MODE_11ac:
5594 case eHDD_DOT11_MODE_11ac_ONLY:
5595#ifdef WLAN_FEATURE_11AC
5596 hddDot11Mode = eHDD_DOT11_MODE_11ac;
5597#else
5598 hddDot11Mode = eHDD_DOT11_MODE_11n;
5599#endif
5600 break;
5601 case eHDD_DOT11_MODE_11n:
5602 case eHDD_DOT11_MODE_11n_ONLY:
5603 hddDot11Mode = eHDD_DOT11_MODE_11n;
5604 break;
5605 default:
5606 hddDot11Mode = iniDot11Mode;
5607 break;
5608 }
5609 /* This call decides required channel bonding mode */
5610 sme_SelectCBMode((WLAN_HDD_GET_CTX(pAdapter)->hHal),
5611 hdd_cfg_xlate_to_csr_phy_mode(hddDot11Mode),
5612 operationChannel);
5613}
5614
Jeff Johnson295189b2012-06-20 16:38:30 -07005615/*
5616 * FUNCTION: wlan_hdd_cfg80211_connect_start
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305617 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -07005618 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305619int wlan_hdd_cfg80211_connect_start( hdd_adapter_t *pAdapter,
Jeff Johnson32d95a32012-09-10 13:15:23 -07005620 const u8 *ssid, size_t ssid_len, const u8 *bssid, u8 operatingChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -07005621{
5622 int status = 0;
5623 hdd_wext_state_t *pWextState;
Yue Mae36e3552014-03-05 17:06:20 -08005624 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07005625 v_U32_t roamId;
5626 tCsrRoamProfile *pRoamProfile;
Jeff Johnson295189b2012-06-20 16:38:30 -07005627 eCsrAuthType RSNAuthType;
5628
5629 ENTER();
5630
5631 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Yue Mae36e3552014-03-05 17:06:20 -08005632 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
5633
5634 status = wlan_hdd_validate_context(pHddCtx);
5635 if (status)
5636 {
5637 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5638 "%s: HDD context is not valid!", __func__);
5639 return status;
5640 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305641
Jeff Johnson295189b2012-06-20 16:38:30 -07005642 if (SIR_MAC_MAX_SSID_LENGTH < ssid_len)
5643 {
5644 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wrong SSID len", __func__);
5645 return -EINVAL;
5646 }
5647
5648 pRoamProfile = &pWextState->roamProfile;
5649
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305650 if (pRoamProfile)
Jeff Johnson295189b2012-06-20 16:38:30 -07005651 {
Jeff Johnsone7245742012-09-05 17:12:55 -07005652 hdd_station_ctx_t *pHddStaCtx;
5653 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07005654
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305655 if (HDD_WMM_USER_MODE_NO_QOS ==
Jeff Johnson295189b2012-06-20 16:38:30 -07005656 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->WmmMode)
5657 {
5658 /*QoS not enabled in cfg file*/
5659 pRoamProfile->uapsd_mask = 0;
5660 }
5661 else
5662 {
5663 /*QoS enabled, update uapsd mask from cfg file*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305664 pRoamProfile->uapsd_mask =
Jeff Johnson295189b2012-06-20 16:38:30 -07005665 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask;
5666 }
5667
5668 pRoamProfile->SSIDs.numOfSSIDs = 1;
5669 pRoamProfile->SSIDs.SSIDList->SSID.length = ssid_len;
5670 vos_mem_zero(pRoamProfile->SSIDs.SSIDList->SSID.ssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305671 sizeof(pRoamProfile->SSIDs.SSIDList->SSID.ssId));
Jeff Johnson295189b2012-06-20 16:38:30 -07005672 vos_mem_copy((void *)(pRoamProfile->SSIDs.SSIDList->SSID.ssId),
5673 ssid, ssid_len);
5674
5675 if (bssid)
5676 {
5677 pRoamProfile->BSSIDs.numOfBSSIDs = 1;
5678 vos_mem_copy((void *)(pRoamProfile->BSSIDs.bssid), bssid,
5679 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305680 /* Save BSSID in seperate variable as well, as RoamProfile
5681 BSSID is getting zeroed out in the association process. And in
Jeff Johnson295189b2012-06-20 16:38:30 -07005682 case of join failure we should send valid BSSID to supplicant
5683 */
5684 vos_mem_copy((void *)(pWextState->req_bssId), bssid,
5685 WNI_CFG_BSSID_LEN);
5686 }
Dhanashri Atre51981c62013-06-13 11:47:57 -07005687 else
5688 {
5689 vos_mem_zero((void *)(pRoamProfile->BSSIDs.bssid),WNI_CFG_BSSID_LEN);
5690 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005691
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +05305692 hddLog(LOG1, FL("Connect to SSID: %s opertating Channel: %u"),
5693 pRoamProfile->SSIDs.SSIDList->SSID.ssId, operatingChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -07005694 if ((IW_AUTH_WPA_VERSION_WPA == pWextState->wpaVersion) ||
5695 (IW_AUTH_WPA_VERSION_WPA2 == pWextState->wpaVersion))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305696 {
Jeff Johnson295189b2012-06-20 16:38:30 -07005697 /*set gen ie*/
5698 hdd_SetGENIEToCsr(pAdapter, &RSNAuthType);
5699 /*set auth*/
5700 hdd_set_csr_auth_type(pAdapter, RSNAuthType);
5701 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005702#ifdef FEATURE_WLAN_WAPI
5703 if (pAdapter->wapi_info.nWapiMode)
5704 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005705 hddLog(LOG1, "%s: Setting WAPI AUTH Type and Encryption Mode values", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005706 switch (pAdapter->wapi_info.wapiAuthMode)
5707 {
5708 case WAPI_AUTH_MODE_PSK:
5709 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005710 hddLog(LOG1, "%s: WAPI AUTH TYPE: PSK: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07005711 pAdapter->wapi_info.wapiAuthMode);
5712 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_PSK;
5713 break;
5714 }
5715 case WAPI_AUTH_MODE_CERT:
5716 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005717 hddLog(LOG1, "%s: WAPI AUTH TYPE: CERT: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07005718 pAdapter->wapi_info.wapiAuthMode);
5719 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE;
5720 break;
5721 }
5722 } // End of switch
5723 if ( pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_PSK ||
5724 pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_CERT)
5725 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005726 hddLog(LOG1, "%s: WAPI PAIRWISE/GROUP ENCRYPTION: WPI", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005727 pRoamProfile->AuthType.numEntries = 1;
5728 pRoamProfile->EncryptionType.numEntries = 1;
5729 pRoamProfile->EncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
5730 pRoamProfile->mcEncryptionType.numEntries = 1;
5731 pRoamProfile->mcEncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
5732 }
5733 }
5734#endif /* FEATURE_WLAN_WAPI */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05305735#ifdef WLAN_FEATURE_GTK_OFFLOAD
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05305736 /* Initializing gtkOffloadReqParams */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05305737 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
5738 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
5739 {
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05305740 memset(&pHddStaCtx->gtkOffloadReqParams, 0,
5741 sizeof (tSirGtkOffloadParams));
5742 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_DISABLE;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05305743 }
5744#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005745 pRoamProfile->csrPersona = pAdapter->device_mode;
5746
Jeff Johnson32d95a32012-09-10 13:15:23 -07005747 if( operatingChannel )
5748 {
5749 pRoamProfile->ChannelInfo.ChannelList = &operatingChannel;
5750 pRoamProfile->ChannelInfo.numOfChannels = 1;
5751 }
Chet Lanctot186b5732013-03-18 10:26:30 -07005752 else
5753 {
5754 pRoamProfile->ChannelInfo.ChannelList = NULL;
5755 pRoamProfile->ChannelInfo.numOfChannels = 0;
5756 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07005757 if ( (WLAN_HDD_IBSS == pAdapter->device_mode) && operatingChannel)
5758 {
5759 hdd_select_cbmode(pAdapter,operatingChannel);
5760 }
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +05305761
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08005762 /* change conn_state to connecting before sme_RoamConnect(), because sme_RoamConnect()
5763 * has a direct path to call hdd_smeRoamCallback(), which will change the conn_state
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305764 * If direct path, conn_state will be accordingly changed to NotConnected or Associated
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08005765 * by either hdd_AssociationCompletionHandler() or hdd_DisConnectHandler() in sme_RoamCallback()
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -08005766 * if sme_RomConnect is to be queued, Connecting state will remain until it is completed.
5767 */
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05305768 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
5769 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode)
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -08005770 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
5771 eConnectionState_Connecting);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305772
5773 status = sme_RoamConnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07005774 pAdapter->sessionId, pRoamProfile, &roamId);
5775
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05305776 if ((eHAL_STATUS_SUCCESS != status) &&
5777 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
5778 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +05305779
5780 {
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08005781 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: sme_RoamConnect (session %d) failed with "
5782 "status %d. -> NotConnected", __func__, pAdapter->sessionId, status);
5783 /* change back to NotAssociated */
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +05305784 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08005785 eConnectionState_NotConnected);
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +05305786 }
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -08005787
5788 pRoamProfile->ChannelInfo.ChannelList = NULL;
5789 pRoamProfile->ChannelInfo.numOfChannels = 0;
5790
Jeff Johnson295189b2012-06-20 16:38:30 -07005791 }
5792 else
5793 {
5794 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid Roam profile", __func__);
5795 return -EINVAL;
5796 }
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08005797 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07005798 return status;
5799}
5800
5801/*
5802 * FUNCTION: wlan_hdd_set_cfg80211_auth_type
5803 * This function is used to set the authentication type (OPEN/SHARED).
5804 *
5805 */
5806static int wlan_hdd_cfg80211_set_auth_type(hdd_adapter_t *pAdapter,
5807 enum nl80211_auth_type auth_type)
5808{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305809 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07005810 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
5811
5812 ENTER();
5813
5814 /*set authentication type*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305815 switch (auth_type)
Jeff Johnson295189b2012-06-20 16:38:30 -07005816 {
Jeff Johnson295189b2012-06-20 16:38:30 -07005817 case NL80211_AUTHTYPE_AUTOMATIC:
Gopichand Nakkala29149562013-05-10 21:43:41 +05305818 hddLog(VOS_TRACE_LEVEL_INFO,
5819 "%s: set authentication type to AUTOSWITCH", __func__);
5820 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_AUTOSWITCH;
5821 break;
5822
5823 case NL80211_AUTHTYPE_OPEN_SYSTEM:
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07005824#ifdef WLAN_FEATURE_VOWIFI_11R
5825 case NL80211_AUTHTYPE_FT:
5826#endif /* WLAN_FEATURE_VOWIFI_11R */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305827 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -07005828 "%s: set authentication type to OPEN", __func__);
5829 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
5830 break;
5831
5832 case NL80211_AUTHTYPE_SHARED_KEY:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305833 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -07005834 "%s: set authentication type to SHARED", __func__);
5835 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_SHARED_KEY;
5836 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005837#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -07005838 case NL80211_AUTHTYPE_NETWORK_EAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305839 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -07005840 "%s: set authentication type to CCKM WPA", __func__);
5841 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_CCKM_WPA;//eCSR_AUTH_TYPE_CCKM_RSN needs to be handled as well if required.
5842 break;
5843#endif
5844
5845
5846 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305847 hddLog(VOS_TRACE_LEVEL_ERROR,
5848 "%s: Unsupported authentication type %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07005849 auth_type);
5850 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_UNKNOWN;
5851 return -EINVAL;
5852 }
5853
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305854 pWextState->roamProfile.AuthType.authType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -07005855 pHddStaCtx->conn_info.authType;
5856 return 0;
5857}
5858
5859/*
5860 * FUNCTION: wlan_hdd_set_akm_suite
5861 * This function is used to set the key mgmt type(PSK/8021x).
5862 *
5863 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305864static int wlan_hdd_set_akm_suite( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07005865 u32 key_mgmt
5866 )
5867{
5868 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
5869 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305870
Jeff Johnson295189b2012-06-20 16:38:30 -07005871 /*set key mgmt type*/
5872 switch(key_mgmt)
5873 {
5874 case WLAN_AKM_SUITE_PSK:
Gopichand Nakkala356fb102013-03-06 12:34:04 +05305875#ifdef WLAN_FEATURE_VOWIFI_11R
5876 case WLAN_AKM_SUITE_FT_PSK:
5877#endif
5878 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to PSK",
Jeff Johnson295189b2012-06-20 16:38:30 -07005879 __func__);
5880 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_PSK;
5881 break;
5882
5883 case WLAN_AKM_SUITE_8021X:
Gopichand Nakkala356fb102013-03-06 12:34:04 +05305884#ifdef WLAN_FEATURE_VOWIFI_11R
5885 case WLAN_AKM_SUITE_FT_8021X:
5886#endif
5887 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to 8021x",
Jeff Johnson295189b2012-06-20 16:38:30 -07005888 __func__);
5889 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
5890 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005891#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -07005892#define WLAN_AKM_SUITE_CCKM 0x00409600 /* Should be in ieee802_11_defs.h */
5893#define IW_AUTH_KEY_MGMT_CCKM 8 /* Should be in linux/wireless.h */
5894 case WLAN_AKM_SUITE_CCKM:
5895 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to CCKM",
5896 __func__);
5897 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_CCKM;
5898 break;
5899#endif
Leela Venkata Kiran Kumar Reddy Chiralae208a832014-04-27 22:34:25 -07005900#ifndef WLAN_AKM_SUITE_OSEN
5901#define WLAN_AKM_SUITE_OSEN 0x506f9a01 /* Should be in ieee802_11_defs.h */
5902 case WLAN_AKM_SUITE_OSEN:
5903 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to OSEN",
5904 __func__);
5905 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
5906 break;
5907#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005908
5909 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305910 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported key mgmt type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07005911 __func__, key_mgmt);
5912 return -EINVAL;
5913
5914 }
5915 return 0;
5916}
5917
5918/*
5919 * FUNCTION: wlan_hdd_cfg80211_set_cipher
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305920 * This function is used to set the encryption type
Jeff Johnson295189b2012-06-20 16:38:30 -07005921 * (NONE/WEP40/WEP104/TKIP/CCMP).
5922 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305923static int wlan_hdd_cfg80211_set_cipher( hdd_adapter_t *pAdapter,
5924 u32 cipher,
Jeff Johnson295189b2012-06-20 16:38:30 -07005925 bool ucast
5926 )
5927{
5928 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305929 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07005930 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
5931
5932 ENTER();
5933
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305934 if (!cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -07005935 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305936 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: received cipher %d - considering none",
Jeff Johnson295189b2012-06-20 16:38:30 -07005937 __func__, cipher);
5938 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
5939 }
5940 else
5941 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305942
Jeff Johnson295189b2012-06-20 16:38:30 -07005943 /*set encryption method*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305944 switch (cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -07005945 {
5946 case IW_AUTH_CIPHER_NONE:
5947 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
5948 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305949
Jeff Johnson295189b2012-06-20 16:38:30 -07005950 case WLAN_CIPHER_SUITE_WEP40:
Gopichand Nakkala29149562013-05-10 21:43:41 +05305951 encryptionType = eCSR_ENCRYPT_TYPE_WEP40;
Jeff Johnson295189b2012-06-20 16:38:30 -07005952 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305953
Jeff Johnson295189b2012-06-20 16:38:30 -07005954 case WLAN_CIPHER_SUITE_WEP104:
Gopichand Nakkala29149562013-05-10 21:43:41 +05305955 encryptionType = eCSR_ENCRYPT_TYPE_WEP104;
Jeff Johnson295189b2012-06-20 16:38:30 -07005956 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305957
Jeff Johnson295189b2012-06-20 16:38:30 -07005958 case WLAN_CIPHER_SUITE_TKIP:
5959 encryptionType = eCSR_ENCRYPT_TYPE_TKIP;
5960 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305961
Jeff Johnson295189b2012-06-20 16:38:30 -07005962 case WLAN_CIPHER_SUITE_CCMP:
5963 encryptionType = eCSR_ENCRYPT_TYPE_AES;
5964 break;
5965#ifdef FEATURE_WLAN_WAPI
5966 case WLAN_CIPHER_SUITE_SMS4:
5967 encryptionType = eCSR_ENCRYPT_TYPE_WPI;
5968 break;
5969#endif
5970
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005971#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -07005972 case WLAN_CIPHER_SUITE_KRK:
5973 encryptionType = eCSR_ENCRYPT_TYPE_KRK;
5974 break;
5975#endif
5976 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305977 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported cipher type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07005978 __func__, cipher);
5979 return -EOPNOTSUPP;
5980 }
5981 }
5982
5983 if (ucast)
5984 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305985 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting unicast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07005986 __func__, encryptionType);
5987 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
5988 pWextState->roamProfile.EncryptionType.numEntries = 1;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305989 pWextState->roamProfile.EncryptionType.encryptionType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -07005990 encryptionType;
5991 }
5992 else
5993 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305994 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting mcast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07005995 __func__, encryptionType);
5996 pHddStaCtx->conn_info.mcEncryptionType = encryptionType;
5997 pWextState->roamProfile.mcEncryptionType.numEntries = 1;
5998 pWextState->roamProfile.mcEncryptionType.encryptionType[0] = encryptionType;
5999 }
6000
6001 return 0;
6002}
6003
6004
6005/*
6006 * FUNCTION: wlan_hdd_cfg80211_set_ie
6007 * This function is used to parse WPA/RSN IE's.
6008 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306009int wlan_hdd_cfg80211_set_ie( hdd_adapter_t *pAdapter,
6010 u8 *ie,
Jeff Johnson295189b2012-06-20 16:38:30 -07006011 size_t ie_len
6012 )
6013{
6014 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
6015 u8 *genie = ie;
6016 v_U16_t remLen = ie_len;
6017#ifdef FEATURE_WLAN_WAPI
6018 v_U32_t akmsuite[MAX_NUM_AKM_SUITES];
6019 u16 *tmp;
6020 v_U16_t akmsuiteCount;
6021 int *akmlist;
6022#endif
6023 ENTER();
6024
6025 /* clear previous assocAddIE */
6026 pWextState->assocAddIE.length = 0;
6027 pWextState->roamProfile.bWPSAssociation = VOS_FALSE;
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -07006028 pWextState->roamProfile.bOSENAssociation = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07006029
6030 while (remLen >= 2)
6031 {
6032 v_U16_t eLen = 0;
6033 v_U8_t elementId;
6034 elementId = *genie++;
6035 eLen = *genie++;
6036 remLen -= 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306037
Arif Hussain6d2a3322013-11-17 19:50:10 -08006038 hddLog(VOS_TRACE_LEVEL_INFO, "%s: IE[0x%X], LEN[%d]",
Jeff Johnson295189b2012-06-20 16:38:30 -07006039 __func__, elementId, eLen);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306040
6041 switch ( elementId )
Jeff Johnson295189b2012-06-20 16:38:30 -07006042 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306043 case DOT11F_EID_WPA:
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07006044 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 -07006045 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306046 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07006047 "%s: Invalid WPA IE", __func__);
6048 return -EINVAL;
6049 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306050 else if (0 == memcmp(&genie[0], "\x00\x50\xf2\x04", 4))
Jeff Johnson295189b2012-06-20 16:38:30 -07006051 {
6052 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306053 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPS IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -07006054 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306055
Jeff Johnson295189b2012-06-20 16:38:30 -07006056 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
6057 {
Jeff Johnson902c9832012-12-10 14:28:09 -08006058 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE. "
6059 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -07006060 VOS_ASSERT(0);
6061 return -ENOMEM;
6062 }
6063 // WSC IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
6064 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
6065 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306066
Jeff Johnson295189b2012-06-20 16:38:30 -07006067 pWextState->roamProfile.bWPSAssociation = VOS_TRUE;
6068 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
6069 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
6070 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306071 else if (0 == memcmp(&genie[0], "\x00\x50\xf2", 3))
6072 {
Jeff Johnson295189b2012-06-20 16:38:30 -07006073 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPA IE (len %d)",__func__, eLen + 2);
6074 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
6075 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2) /*ie_len*/);
6076 pWextState->roamProfile.pWPAReqIE = pWextState->WPARSNIE;
6077 pWextState->roamProfile.nWPAReqIELength = eLen + 2;//ie_len;
6078 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306079 else if ( (0 == memcmp(&genie[0], P2P_OUI_TYPE,
Kiet Lam8da98992013-11-21 15:59:07 +05306080 P2P_OUI_TYPE_SIZE)))
Jeff Johnson295189b2012-06-20 16:38:30 -07006081 {
6082 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306083 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set P2P IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -07006084 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306085
Jeff Johnson295189b2012-06-20 16:38:30 -07006086 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
6087 {
Jeff Johnson902c9832012-12-10 14:28:09 -08006088 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
6089 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -07006090 VOS_ASSERT(0);
6091 return -ENOMEM;
6092 }
6093 // P2P IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
6094 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
6095 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306096
Jeff Johnson295189b2012-06-20 16:38:30 -07006097 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
6098 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
6099 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006100#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306101 else if ( (0 == memcmp(&genie[0], WFD_OUI_TYPE,
6102 WFD_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07006103 /*Consider WFD IE, only for P2P Client */
6104 && (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
6105 {
6106 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306107 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WFD IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -07006108 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306109
Jeff Johnson295189b2012-06-20 16:38:30 -07006110 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
6111 {
Jeff Johnson902c9832012-12-10 14:28:09 -08006112 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
6113 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -07006114 VOS_ASSERT(0);
6115 return -ENOMEM;
6116 }
6117 // WFD IE is saved to Additional IE ; it should be accumulated to handle
6118 // WPS IE + P2P IE + WFD IE
6119 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
6120 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306121
Jeff Johnson295189b2012-06-20 16:38:30 -07006122 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
6123 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
6124 }
6125#endif
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07006126 /* Appending HS 2.0 Indication Element in Assiciation Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306127 else if ( (0 == memcmp(&genie[0], HS20_OUI_TYPE,
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07006128 HS20_OUI_TYPE_SIZE)) )
6129 {
6130 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306131 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set HS20 IE(len %d)",
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07006132 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07006133
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07006134 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
6135 {
Jeff Johnson902c9832012-12-10 14:28:09 -08006136 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
6137 "Need bigger buffer space");
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07006138 VOS_ASSERT(0);
6139 return -ENOMEM;
6140 }
6141 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
6142 pWextState->assocAddIE.length += eLen + 2;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07006143
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07006144 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
6145 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
6146 }
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -07006147 /* Appending OSEN Information Element in Assiciation Request */
6148 else if ( (0 == memcmp(&genie[0], OSEN_OUI_TYPE,
6149 OSEN_OUI_TYPE_SIZE)) )
6150 {
6151 v_U16_t curAddIELen = pWextState->assocAddIE.length;
6152 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set OSEN IE(len %d)",
6153 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07006154
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -07006155 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
6156 {
6157 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
6158 "Need bigger buffer space");
6159 VOS_ASSERT(0);
6160 return -ENOMEM;
6161 }
6162 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
6163 pWextState->assocAddIE.length += eLen + 2;
6164
6165 pWextState->roamProfile.bOSENAssociation = VOS_TRUE;
6166 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
6167 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
6168 }
6169
6170 break;
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -07006171 if (WLAN_HDD_IBSS == pAdapter->device_mode) {
6172
6173 /* populating as ADDIE in beacon frames */
6174 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
6175 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, genie - 2, eLen + 2,
6176 NULL, eANI_BOOLEAN_FALSE)== eHAL_STATUS_SUCCESS)
6177 {
6178 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
6179 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
6180 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
6181 {
6182 hddLog(LOGE,
6183 "Coldn't pass "
6184 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
6185 }
6186 }/* ccmCfgSetStr(,WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, , )*/
6187 else
6188 hddLog(LOGE,
6189 "Could not pass on "
6190 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
6191
6192 /* IBSS mode doesn't contain params->proberesp_ies still
6193 beaconIE's need to be populated in probe response frames */
6194 if ( (NULL != (genie - 2)) && (0 != eLen + 2) )
6195 {
6196 u16 rem_probe_resp_ie_len = eLen + 2;
6197 u8 probe_rsp_ie_len[3] = {0};
6198 u8 counter = 0;
6199
6200 /* Check Probe Resp Length if it is greater then 255 then
6201 Store Probe Rsp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1
6202 & WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are
6203 not able Store More then 255 bytes into One Variable */
6204
6205 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
6206 {
6207 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
6208 {
6209 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
6210 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
6211 }
6212 else
6213 {
6214 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
6215 rem_probe_resp_ie_len = 0;
6216 }
6217 }
6218
6219 rem_probe_resp_ie_len = 0;
6220
6221 if (probe_rsp_ie_len[0] > 0)
6222 {
6223 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
6224 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
6225 (tANI_U8*)(genie - 2),
6226 probe_rsp_ie_len[0], NULL,
6227 eANI_BOOLEAN_FALSE)
6228 == eHAL_STATUS_FAILURE)
6229 {
6230 hddLog(LOGE,
6231 "Could not pass"
6232 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
6233 }
6234 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
6235 }
6236
6237 if (probe_rsp_ie_len[1] > 0)
6238 {
6239 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
6240 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
6241 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
6242 probe_rsp_ie_len[1], NULL,
6243 eANI_BOOLEAN_FALSE)
6244 == eHAL_STATUS_FAILURE)
6245 {
6246 hddLog(LOGE,
6247 "Could not pass"
6248 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
6249 }
6250 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
6251 }
6252
6253 if (probe_rsp_ie_len[2] > 0)
6254 {
6255 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
6256 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
6257 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
6258 probe_rsp_ie_len[2], NULL,
6259 eANI_BOOLEAN_FALSE)
6260 == eHAL_STATUS_FAILURE)
6261 {
6262 hddLog(LOGE,
6263 "Could not pass"
6264 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
6265 }
6266 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
6267 }
6268
6269 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
6270 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
6271 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
6272 {
6273 hddLog(LOGE,
6274 "Could not pass"
6275 "on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
6276 }
6277 }
6278 else
6279 {
6280 // Reset WNI_CFG_PROBE_RSP Flags
6281 wlan_hdd_reset_prob_rspies(pAdapter);
6282
6283 hddLog(VOS_TRACE_LEVEL_INFO,
6284 "%s: No Probe Response IE received in set beacon",
6285 __func__);
6286 }
6287 } /* end of if (WLAN_HDD_IBSS == pAdapter->device_mode) */
Jeff Johnson295189b2012-06-20 16:38:30 -07006288 break;
6289 case DOT11F_EID_RSN:
6290 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set RSN IE(len %d)",__func__, eLen + 2);
6291 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
6292 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2)/*ie_len*/);
6293 pWextState->roamProfile.pRSNReqIE = pWextState->WPARSNIE;
6294 pWextState->roamProfile.nRSNReqIELength = eLen + 2; //ie_len;
6295 break;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07006296 /* Appending Extended Capabilities with Interworking bit set in Assoc Req */
6297 case DOT11F_EID_EXTCAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306298 {
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07006299 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306300 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set Extended CAPS IE(len %d)",
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07006301 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306302
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07006303 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
6304 {
Jeff Johnson902c9832012-12-10 14:28:09 -08006305 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
6306 "Need bigger buffer space");
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07006307 VOS_ASSERT(0);
6308 return -ENOMEM;
6309 }
6310 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
6311 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306312
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07006313 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
6314 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
6315 break;
6316 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006317#ifdef FEATURE_WLAN_WAPI
6318 case WLAN_EID_WAPI:
6319 pAdapter->wapi_info.nWapiMode = 1; //Setting WAPI Mode to ON=1
Jeff Johnson0299d0a2013-10-30 12:37:43 -07006320 hddLog(VOS_TRACE_LEVEL_INFO, "WAPI MODE IS %u",
Jeff Johnson295189b2012-06-20 16:38:30 -07006321 pAdapter->wapi_info.nWapiMode);
6322 tmp = (u16 *)ie;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306323 tmp = tmp + 2; // Skip element Id and Len, Version
Jeff Johnson295189b2012-06-20 16:38:30 -07006324 akmsuiteCount = WPA_GET_LE16(tmp);
6325 tmp = tmp + 1;
6326 akmlist = (int *)(tmp);
6327 if(akmsuiteCount <= MAX_NUM_AKM_SUITES)
6328 {
6329 memcpy(akmsuite, akmlist, (4*akmsuiteCount));
6330 }
6331 else
6332 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08006333 hddLog(VOS_TRACE_LEVEL_FATAL, "Invalid akmSuite count");
Jeff Johnson295189b2012-06-20 16:38:30 -07006334 VOS_ASSERT(0);
6335 return -EINVAL;
6336 }
6337
6338 if (WAPI_PSK_AKM_SUITE == akmsuite[0])
6339 {
6340 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO PSK",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006341 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006342 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_PSK;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306343 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006344 if (WAPI_CERT_AKM_SUITE == akmsuite[0])
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306345 {
Jeff Johnson295189b2012-06-20 16:38:30 -07006346 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO CERTIFICATE",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006347 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006348 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_CERT;
6349 }
6350 break;
6351#endif
6352 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306353 hddLog (VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07006354 "%s Set UNKNOWN IE %X", __func__, elementId);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07006355 /* when Unknown IE is received we should break and continue
6356 * to the next IE in the buffer instead we were returning
6357 * so changing this to break */
6358 break;
Jeff Johnson295189b2012-06-20 16:38:30 -07006359 }
6360 genie += eLen;
6361 remLen -= eLen;
6362 }
6363 EXIT();
6364 return 0;
6365}
6366
6367/*
Gopichand Nakkala18f0c262013-05-07 23:25:08 +05306368 * FUNCTION: hdd_isWPAIEPresent
6369 * Parse the received IE to find the WPA IE
6370 *
6371 */
6372static bool hdd_isWPAIEPresent(u8 *ie, u8 ie_len)
6373{
6374 v_U8_t eLen = 0;
6375 v_U16_t remLen = ie_len;
6376 v_U8_t elementId = 0;
6377
6378 while (remLen >= 2)
6379 {
6380 elementId = *ie++;
6381 eLen = *ie++;
6382 remLen -= 2;
6383 if (eLen > remLen)
6384 {
6385 hddLog(VOS_TRACE_LEVEL_ERROR,
6386 "%s: IE length is wrong %d", __func__, eLen);
6387 return FALSE;
6388 }
6389 if ((elementId == DOT11F_EID_WPA) && (remLen > 5))
6390 {
6391 /* OUI - 0x00 0X50 0XF2
6392 WPA Information Element - 0x01
6393 WPA version - 0x01*/
6394 if (0 == memcmp(&ie[0], "\x00\x50\xf2\x01\x01", 5))
6395 return TRUE;
6396 }
6397 ie += eLen;
6398 remLen -= eLen;
6399 }
6400 return FALSE;
6401}
6402
6403/*
Jeff Johnson295189b2012-06-20 16:38:30 -07006404 * FUNCTION: wlan_hdd_cfg80211_set_privacy
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306405 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -07006406 * parameters during connect operation.
6407 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306408int wlan_hdd_cfg80211_set_privacy( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07006409 struct cfg80211_connect_params *req
6410 )
6411{
6412 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306413 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07006414 ENTER();
6415
6416 /*set wpa version*/
6417 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
6418
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306419 if (req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -07006420 {
Gopichand Nakkala781ded42013-06-28 12:10:45 +05306421 if (NL80211_WPA_VERSION_1 == req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -07006422 {
6423 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
6424 }
6425 else if (NL80211_WPA_VERSION_2 == req->crypto.wpa_versions)
6426 {
6427 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
6428 }
6429 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306430
6431 hddLog(VOS_TRACE_LEVEL_INFO, "%s: set wpa version to %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07006432 pWextState->wpaVersion);
6433
6434 /*set authentication type*/
6435 status = wlan_hdd_cfg80211_set_auth_type(pAdapter, req->auth_type);
6436
6437 if (0 > status)
6438 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306439 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07006440 "%s: failed to set authentication type ", __func__);
6441 return status;
6442 }
6443
6444 /*set key mgmt type*/
6445 if (req->crypto.n_akm_suites)
6446 {
6447 status = wlan_hdd_set_akm_suite(pAdapter, req->crypto.akm_suites[0]);
6448 if (0 > status)
6449 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306450 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set akm suite",
Jeff Johnson295189b2012-06-20 16:38:30 -07006451 __func__);
6452 return status;
6453 }
6454 }
6455
6456 /*set pairwise cipher type*/
6457 if (req->crypto.n_ciphers_pairwise)
6458 {
6459 status = wlan_hdd_cfg80211_set_cipher(pAdapter,
6460 req->crypto.ciphers_pairwise[0], true);
6461 if (0 > status)
6462 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306463 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07006464 "%s: failed to set unicast cipher type", __func__);
6465 return status;
6466 }
6467 }
6468 else
6469 {
6470 /*Reset previous cipher suite to none*/
6471 status = wlan_hdd_cfg80211_set_cipher(pAdapter, 0, true);
6472 if (0 > status)
6473 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306474 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07006475 "%s: failed to set unicast cipher type", __func__);
6476 return status;
6477 }
6478 }
6479
6480 /*set group cipher type*/
6481 status = wlan_hdd_cfg80211_set_cipher(pAdapter, req->crypto.cipher_group,
6482 false);
6483
6484 if (0 > status)
6485 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306486 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set mcast cipher type",
Jeff Johnson295189b2012-06-20 16:38:30 -07006487 __func__);
6488 return status;
6489 }
6490
Chet Lanctot186b5732013-03-18 10:26:30 -07006491#ifdef WLAN_FEATURE_11W
6492 pWextState->roamProfile.MFPEnabled = (req->mfp == NL80211_MFP_REQUIRED);
6493#endif
6494
Jeff Johnson295189b2012-06-20 16:38:30 -07006495 /*parse WPA/RSN IE, and set the correspoing fileds in Roam profile*/
6496 if (req->ie_len)
6497 {
6498 status = wlan_hdd_cfg80211_set_ie(pAdapter, req->ie, req->ie_len);
6499 if ( 0 > status)
6500 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306501 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse the WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -07006502 __func__);
6503 return status;
6504 }
6505 }
6506
6507 /*incase of WEP set default key information*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306508 if (req->key && req->key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -07006509 {
6510 if ( (WLAN_CIPHER_SUITE_WEP40 == req->crypto.ciphers_pairwise[0])
6511 || (WLAN_CIPHER_SUITE_WEP104 == req->crypto.ciphers_pairwise[0])
6512 )
6513 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306514 if ( IW_AUTH_KEY_MGMT_802_1X
Jeff Johnson295189b2012-06-20 16:38:30 -07006515 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X ))
6516 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306517 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Dynamic WEP not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -07006518 __func__);
6519 return -EOPNOTSUPP;
6520 }
6521 else
6522 {
6523 u8 key_len = req->key_len;
6524 u8 key_idx = req->key_idx;
6525
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306526 if ((eCSR_SECURITY_WEP_KEYSIZE_MAX_BYTES >= key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -07006527 && (CSR_MAX_NUM_KEY > key_idx)
6528 )
6529 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306530 hddLog(VOS_TRACE_LEVEL_INFO,
6531 "%s: setting default wep key, key_idx = %hu key_len %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07006532 __func__, key_idx, key_len);
6533 vos_mem_copy(
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306534 &pWextState->roamProfile.Keys.KeyMaterial[key_idx][0],
Jeff Johnson295189b2012-06-20 16:38:30 -07006535 req->key, key_len);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306536 pWextState->roamProfile.Keys.KeyLength[key_idx] =
Jeff Johnson295189b2012-06-20 16:38:30 -07006537 (u8)key_len;
6538 pWextState->roamProfile.Keys.defaultIndex = (u8)key_idx;
6539 }
6540 }
6541 }
6542 }
6543
6544 return status;
6545}
6546
6547/*
Vinay Krishna Eranna21042322014-01-08 19:21:39 +05306548 * FUNCTION: wlan_hdd_try_disconnect
6549 * This function is used to disconnect from previous
6550 * connection
6551 */
6552static int wlan_hdd_try_disconnect( hdd_adapter_t *pAdapter )
6553{
6554 long ret = 0;
6555 hdd_station_ctx_t *pHddStaCtx;
6556 eMib_dot11DesiredBssType connectedBssType;
6557
6558 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6559
6560 hdd_connGetConnectedBssType(pHddStaCtx,&connectedBssType );
6561
6562 if((eMib_dot11DesiredBssType_independent == connectedBssType) ||
6563 (eConnectionState_Associated == pHddStaCtx->conn_info.connState) ||
6564 (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState))
6565 {
6566 /* Issue disconnect to CSR */
6567 INIT_COMPLETION(pAdapter->disconnect_comp_var);
6568 if( eHAL_STATUS_SUCCESS ==
6569 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
6570 pAdapter->sessionId,
6571 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
6572 {
6573 ret = wait_for_completion_interruptible_timeout(
6574 &pAdapter->disconnect_comp_var,
6575 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
6576 if (0 >= ret)
6577 {
6578 hddLog(LOGE, FL("Failed to receive disconnect event"));
6579 return -EALREADY;
6580 }
6581 }
6582 }
6583 else if(eConnectionState_Disconnecting == pHddStaCtx->conn_info.connState)
6584 {
6585 ret = wait_for_completion_interruptible_timeout(
6586 &pAdapter->disconnect_comp_var,
6587 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
6588 if (0 >= ret)
6589 {
6590 hddLog(LOGE, FL("Failed to receive disconnect event"));
6591 return -EALREADY;
6592 }
6593 }
6594
6595 return 0;
6596}
6597
6598/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +05306599 * FUNCTION: __wlan_hdd_cfg80211_set_privacy
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306600 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -07006601 * parameters during connect operation.
6602 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +05306603static int __wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07006604 struct net_device *ndev,
6605 struct cfg80211_connect_params *req
6606 )
6607{
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306608 int status;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306609 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -07006610 VOS_STATUS exitbmpsStatus = VOS_STATUS_E_INVAL;
Rajesh Chauhana0516c62014-01-30 16:11:18 -08006611 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07006612
6613 ENTER();
6614
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05306615 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
6616 TRACE_CODE_HDD_CFG80211_CONNECT,
6617 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306618 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05306619 "%s: device_mode = %s (%d)", __func__,
6620 hdd_device_modetoString(pAdapter->device_mode),
6621 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07006622
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306623 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -08006624 if (!pHddCtx)
6625 {
6626 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6627 "%s: HDD context is null", __func__);
6628 return VOS_STATUS_E_FAILURE;
6629 }
6630
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306631 status = wlan_hdd_validate_context(pHddCtx);
6632
6633 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -07006634 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306635 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6636 "%s: HDD context is not valid", __func__);
6637 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -07006638 }
6639
6640#ifdef WLAN_BTAMP_FEATURE
6641 //Infra connect not supported when AMP traffic is on.
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306642 if( VOS_TRUE == WLANBAP_AmpSessionOn() )
Jeff Johnson295189b2012-06-20 16:38:30 -07006643 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306644 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07006645 "%s: No connection when AMP is on", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08006646 return -ECONNREFUSED;
Jeff Johnson295189b2012-06-20 16:38:30 -07006647 }
6648#endif
Vinay Krishna Eranna21042322014-01-08 19:21:39 +05306649
6650 //If Device Mode is Station Concurrent Sessions Exit BMps
6651 //P2P Mode will be taken care in Open/close adapter
6652 if((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
6653 (vos_concurrent_sessions_running()))
6654 {
6655 exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
6656 }
6657
6658 /*Try disconnecting if already in connected state*/
6659 status = wlan_hdd_try_disconnect(pAdapter);
6660 if ( 0 > status)
6661 {
6662 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
6663 " connection"));
6664 return -EALREADY;
6665 }
6666
Jeff Johnson295189b2012-06-20 16:38:30 -07006667 /*initialise security parameters*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306668 status = wlan_hdd_cfg80211_set_privacy(pAdapter, req);
Jeff Johnson295189b2012-06-20 16:38:30 -07006669
6670 if ( 0 > status)
6671 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306672 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security params",
Jeff Johnson295189b2012-06-20 16:38:30 -07006673 __func__);
6674 return status;
6675 }
6676
Mohit Khanna765234a2012-09-11 15:08:35 -07006677 if ( req->channel )
6678 {
6679 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
6680 req->ssid_len, req->bssid,
6681 req->channel->hw_value);
6682 }
6683 else
6684 {
6685 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306686 req->ssid_len, req->bssid, 0);
Mohit Khanna765234a2012-09-11 15:08:35 -07006687 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006688
6689 if (0 > status)
6690 {
6691 //ReEnable BMPS if disabled
6692 if((VOS_STATUS_SUCCESS == exitbmpsStatus) &&
6693 (NULL != pHddCtx))
6694 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306695 if (pHddCtx->hdd_wlan_suspended)
6696 {
6697 hdd_set_pwrparams(pHddCtx);
6698 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006699 //ReEnable Bmps and Imps back
6700 hdd_enable_bmps_imps(pHddCtx);
6701 }
6702
6703 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: connect failed", __func__);
6704 return status;
6705 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306706 pHddCtx->isAmpAllowed = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07006707 EXIT();
6708 return status;
6709}
6710
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +05306711static int wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
6712 struct net_device *ndev,
6713 struct cfg80211_connect_params *req)
6714{
6715 int ret;
6716 vos_ssr_protect(__func__);
6717 ret = __wlan_hdd_cfg80211_connect(wiphy, ndev, req);
6718 vos_ssr_unprotect(__func__);
6719
6720 return ret;
6721}
Jeff Johnson295189b2012-06-20 16:38:30 -07006722
6723/*
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05306724 * FUNCTION: wlan_hdd_disconnect
6725 * This function is used to issue a disconnect request to SME
6726 */
6727int wlan_hdd_disconnect( hdd_adapter_t *pAdapter, u16 reason )
6728{
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306729 int status;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05306730 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306731 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
6732
6733 status = wlan_hdd_validate_context(pHddCtx);
6734
6735 if (0 != status)
6736 {
6737 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6738 "%s: HDD context is not valid", __func__);
6739 return status;
6740 }
6741
6742 pHddCtx->isAmpAllowed = VOS_TRUE;
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +05306743 pHddStaCtx->conn_info.connState = eConnectionState_Disconnecting;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05306744 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306745
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05306746 /*issue disconnect*/
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +05306747
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05306748 status = sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
6749 pAdapter->sessionId, reason);
6750
6751 if ( 0 != status )
6752 {
6753 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006754 "%s csrRoamDisconnect failure, returned %d",
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05306755 __func__, (int)status );
6756 return -EINVAL;
6757 }
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +05306758 status = wait_for_completion_interruptible_timeout(
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05306759 &pAdapter->disconnect_comp_var,
6760 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +05306761 if (!status)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306762 {
6763 hddLog(VOS_TRACE_LEVEL_ERROR,
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +05306764 "%s: Failed to disconnect, timed out", __func__);
6765 return -ETIMEDOUT;
6766 }
6767 else if (status == -ERESTARTSYS)
6768 {
6769 hddLog(VOS_TRACE_LEVEL_ERROR,
6770 "%s: Failed to disconnect, wait interrupted", __func__);
6771 return status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306772 }
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05306773 /*stop tx queues*/
6774 netif_tx_disable(pAdapter->dev);
6775 netif_carrier_off(pAdapter->dev);
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +05306776 return 0;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05306777}
6778
6779
6780/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +05306781 * FUNCTION: __wlan_hdd_cfg80211_disconnect
Jeff Johnson295189b2012-06-20 16:38:30 -07006782 * This function is used to issue a disconnect request to SME
6783 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +05306784static int __wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07006785 struct net_device *dev,
6786 u16 reason
6787 )
6788{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306789 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
6790 tCsrRoamProfile *pRoamProfile =
Jeff Johnson295189b2012-06-20 16:38:30 -07006791 &(WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter))->roamProfile;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306792 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07006793 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkala4327a152013-03-04 23:22:42 -08006794 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaaa353782013-05-17 20:36:22 +05306795#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08006796 tANI_U8 staIdx;
6797#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306798
Jeff Johnson295189b2012-06-20 16:38:30 -07006799 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306800
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05306801 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
6802 TRACE_CODE_HDD_CFG80211_DISCONNECT,
6803 pAdapter->sessionId, reason));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05306804 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s(%d)",
6805 __func__, hdd_device_modetoString(pAdapter->device_mode),
6806 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07006807
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306808 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Disconnect called with reason code %d",
6809 __func__, reason);
Jeff Johnson295189b2012-06-20 16:38:30 -07006810
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306811 status = wlan_hdd_validate_context(pHddCtx);
6812
6813 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -07006814 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306815 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6816 "%s: HDD context is not valid", __func__);
6817 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -07006818 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306819
Jeff Johnson295189b2012-06-20 16:38:30 -07006820 if (NULL != pRoamProfile)
6821 {
6822 /*issue disconnect request to SME, if station is in connected state*/
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +05306823 if ((pHddStaCtx->conn_info.connState == eConnectionState_Associated) ||
6824 (pHddStaCtx->conn_info.connState == eConnectionState_Connecting))
Jeff Johnson295189b2012-06-20 16:38:30 -07006825 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306826 eCsrRoamDisconnectReason reasonCode =
Jeff Johnson295189b2012-06-20 16:38:30 -07006827 eCSR_DISCONNECT_REASON_UNSPECIFIED;
Gopichand Nakkalaaa353782013-05-17 20:36:22 +05306828 hdd_scaninfo_t *pScanInfo;
Jeff Johnson295189b2012-06-20 16:38:30 -07006829 switch(reason)
6830 {
6831 case WLAN_REASON_MIC_FAILURE:
6832 reasonCode = eCSR_DISCONNECT_REASON_MIC_ERROR;
6833 break;
6834
6835 case WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY:
6836 case WLAN_REASON_DISASSOC_AP_BUSY:
6837 case WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA:
6838 reasonCode = eCSR_DISCONNECT_REASON_DISASSOC;
6839 break;
6840
6841 case WLAN_REASON_PREV_AUTH_NOT_VALID:
6842 case WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA:
Abhishek Singhc3269a52014-05-21 17:22:24 +05306843 case WLAN_REASON_DEAUTH_LEAVING:
Jeff Johnson295189b2012-06-20 16:38:30 -07006844 reasonCode = eCSR_DISCONNECT_REASON_DEAUTH;
6845 break;
6846
Jeff Johnson295189b2012-06-20 16:38:30 -07006847 default:
6848 reasonCode = eCSR_DISCONNECT_REASON_UNSPECIFIED;
6849 break;
6850 }
Gopichand Nakkalaaa353782013-05-17 20:36:22 +05306851 pScanInfo = &pHddCtx->scan_info;
6852 if (pScanInfo->mScanPending)
6853 {
Srinivas, Dasari138af4f2014-02-07 11:13:45 +05306854 hddLog(VOS_TRACE_LEVEL_INFO, "Disconnect is in progress, "
Gopichand Nakkalaaa353782013-05-17 20:36:22 +05306855 "Aborting Scan");
Srinivas, Dasari138af4f2014-02-07 11:13:45 +05306856 hdd_abort_mac_scan(pHddCtx, pAdapter->sessionId,
6857 eCSR_SCAN_ABORT_DEFAULT);
Gopichand Nakkalaaa353782013-05-17 20:36:22 +05306858 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006859
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08006860#ifdef FEATURE_WLAN_TDLS
6861 /* First clean up the tdls peers if any */
Gopichand Nakkala4327a152013-03-04 23:22:42 -08006862 for (staIdx = 0 ; staIdx < HDD_MAX_NUM_TDLS_STA; staIdx++)
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08006863 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -08006864 if ((pHddCtx->tdlsConnInfo[staIdx].sessionId == pAdapter->sessionId) &&
6865 (pHddCtx->tdlsConnInfo[staIdx].staId))
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08006866 {
Hoonki Lee11f7dda2013-02-14 16:55:44 -08006867 uint8 *mac;
Gopichand Nakkala4327a152013-03-04 23:22:42 -08006868 mac = pHddCtx->tdlsConnInfo[staIdx].peerMac.bytes;
Hoonki Lee11f7dda2013-02-14 16:55:44 -08006869 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07006870 "%s: call sme_DeleteTdlsPeerSta staId %d sessionId %d " MAC_ADDRESS_STR,
Gopichand Nakkala4327a152013-03-04 23:22:42 -08006871 __func__, pHddCtx->tdlsConnInfo[staIdx].staId, pAdapter->sessionId,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07006872 MAC_ADDR_ARRAY(mac));
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08006873 sme_DeleteTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala4327a152013-03-04 23:22:42 -08006874 pAdapter->sessionId,
6875 mac);
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08006876 }
6877 }
6878#endif
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +05306879 hddLog(LOG1, FL("Disconnecting with reasoncode:%u"), reasonCode);
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05306880 status = wlan_hdd_disconnect(pAdapter, reasonCode);
6881 if ( 0 != status )
Jeff Johnson295189b2012-06-20 16:38:30 -07006882 {
6883 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006884 "%s wlan_hdd_disconnect failure, returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07006885 __func__, (int)status );
6886 return -EINVAL;
6887 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006888 }
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +05306889 else
6890 {
6891 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unexpected cfg disconnect API"
6892 "called while in %d state", __func__,
6893 pHddStaCtx->conn_info.connState);
6894 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006895 }
6896 else
6897 {
6898 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid roam profile", __func__);
6899 }
6900
6901 return status;
6902}
6903
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +05306904static int wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
6905 struct net_device *dev,
6906 u16 reason
6907 )
6908{
6909 int ret;
6910 vos_ssr_protect(__func__);
6911 ret = __wlan_hdd_cfg80211_disconnect(wiphy, dev, reason);
6912 vos_ssr_unprotect(__func__);
6913
6914 return ret;
6915}
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05306916
Jeff Johnson295189b2012-06-20 16:38:30 -07006917/*
6918 * FUNCTION: wlan_hdd_cfg80211_set_privacy_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306919 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -07006920 * settings in IBSS mode.
6921 */
6922static int wlan_hdd_cfg80211_set_privacy_ibss(
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306923 hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07006924 struct cfg80211_ibss_params *params
6925 )
6926{
6927 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306928 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07006929 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
6930 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306931
Jeff Johnson295189b2012-06-20 16:38:30 -07006932 ENTER();
6933
6934 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
Ravi Joshib58ca0d2013-10-29 09:50:23 -07006935 vos_mem_zero(&pHddStaCtx->ibss_enc_key, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -07006936
6937 if (params->ie_len && ( NULL != params->ie) )
6938 {
Shailender Karmuchi67edd312013-06-18 16:30:48 -07006939 if (wlan_hdd_cfg80211_get_ie_ptr (params->ie,
6940 params->ie_len, WLAN_EID_RSN ))
Jeff Johnson295189b2012-06-20 16:38:30 -07006941 {
6942 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
6943 encryptionType = eCSR_ENCRYPT_TYPE_AES;
6944 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -07006945 else if ( hdd_isWPAIEPresent (params->ie, params->ie_len ))
Jeff Johnson295189b2012-06-20 16:38:30 -07006946 {
Shailender Karmuchi642e9812013-05-30 14:34:49 -07006947 tDot11fIEWPA dot11WPAIE;
6948 tHalHandle halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
Shailender Karmuchi67edd312013-06-18 16:30:48 -07006949 u8 *ie;
Shailender Karmuchi642e9812013-05-30 14:34:49 -07006950
Wilson Yang00256342013-10-10 23:13:38 -07006951 memset(&dot11WPAIE, 0, sizeof(dot11WPAIE));
Shailender Karmuchi67edd312013-06-18 16:30:48 -07006952 ie = wlan_hdd_cfg80211_get_ie_ptr (params->ie,
6953 params->ie_len, DOT11F_EID_WPA);
6954 if ( NULL != ie )
6955 {
6956 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
6957 // Unpack the WPA IE
6958 //Skip past the EID byte and length byte - and four byte WiFi OUI
6959 dot11fUnpackIeWPA((tpAniSirGlobal) halHandle,
6960 &ie[2+4],
6961 ie[1] - 4,
6962 &dot11WPAIE);
6963 /*Extract the multicast cipher, the encType for unicast
6964 cipher for wpa-none is none*/
6965 encryptionType =
6966 hdd_TranslateWPAToCsrEncryptionType(dot11WPAIE.multicast_cipher);
6967 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006968 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -07006969
Jeff Johnson295189b2012-06-20 16:38:30 -07006970 status = wlan_hdd_cfg80211_set_ie(pAdapter, params->ie, params->ie_len);
6971
6972 if (0 > status)
6973 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306974 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -07006975 __func__);
6976 return status;
6977 }
6978 }
6979
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306980 pWextState->roamProfile.AuthType.authType[0] =
6981 pHddStaCtx->conn_info.authType =
Jeff Johnson295189b2012-06-20 16:38:30 -07006982 eCSR_AUTH_TYPE_OPEN_SYSTEM;
6983
6984 if (params->privacy)
6985 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306986 /* Security enabled IBSS, At this time there is no information available
6987 * about the security paramters, so initialise the encryption type to
Jeff Johnson295189b2012-06-20 16:38:30 -07006988 * eCSR_ENCRYPT_TYPE_WEP40_STATICKEY.
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306989 * The correct security parameters will be updated later in
Jeff Johnson295189b2012-06-20 16:38:30 -07006990 * wlan_hdd_cfg80211_add_key */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306991 /* Hal expects encryption type to be set inorder
Jeff Johnson295189b2012-06-20 16:38:30 -07006992 *enable privacy bit in beacons */
6993
6994 encryptionType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
6995 }
Shailender Karmuchi642e9812013-05-30 14:34:49 -07006996 VOS_TRACE (VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
6997 "encryptionType=%d", encryptionType);
Jeff Johnson295189b2012-06-20 16:38:30 -07006998 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
6999 pWextState->roamProfile.EncryptionType.numEntries = 1;
7000 pWextState->roamProfile.EncryptionType.encryptionType[0] = encryptionType;
Jeff Johnson295189b2012-06-20 16:38:30 -07007001 return status;
7002}
7003
7004/*
7005 * FUNCTION: wlan_hdd_cfg80211_join_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307006 * This function is used to create/join an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -07007007 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307008static int wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07007009 struct net_device *dev,
7010 struct cfg80211_ibss_params *params
7011 )
7012{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307013 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Jeff Johnson295189b2012-06-20 16:38:30 -07007014 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
7015 tCsrRoamProfile *pRoamProfile;
7016 int status;
krunal sonie9002db2013-11-25 14:24:17 -08007017 bool alloc_bssid = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07007018 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307019 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07007020
7021 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307022
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307023 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7024 TRACE_CODE_HDD_CFG80211_JOIN_IBSS,
7025 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307026 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05307027 "%s: device_mode = %s (%d)", __func__,
7028 hdd_device_modetoString(pAdapter->device_mode),
7029 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07007030
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307031 status = wlan_hdd_validate_context(pHddCtx);
7032
7033 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -07007034 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307035 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7036 "%s: HDD context is not valid", __func__);
7037 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -07007038 }
7039
7040 if (NULL == pWextState)
7041 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08007042 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -07007043 __func__);
7044 return -EIO;
7045 }
7046
Vinay Krishna Eranna21042322014-01-08 19:21:39 +05307047 /*Try disconnecting if already in connected state*/
7048 status = wlan_hdd_try_disconnect(pAdapter);
7049 if ( 0 > status)
7050 {
7051 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
7052 " IBSS connection"));
7053 return -EALREADY;
7054 }
7055
Jeff Johnson295189b2012-06-20 16:38:30 -07007056 pRoamProfile = &pWextState->roamProfile;
7057
7058 if ( eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType )
7059 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307060 hddLog (VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007061 "%s Interface type is not set to IBSS", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007062 return -EINVAL;
7063 }
7064
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -07007065 /* BSSID is provided by upper layers hence no need to AUTO generate */
7066 if (NULL != params->bssid) {
7067 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
7068 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) {
7069 hddLog (VOS_TRACE_LEVEL_ERROR,
7070 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
7071 return -EIO;
7072 }
7073 }
krunal sonie9002db2013-11-25 14:24:17 -08007074 else if(pHddCtx->cfg_ini->isCoalesingInIBSSAllowed == 0)
7075 {
7076 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
7077 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
7078 {
7079 hddLog (VOS_TRACE_LEVEL_ERROR,
7080 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
7081 return -EIO;
7082 }
7083 params->bssid = vos_mem_malloc(sizeof(VOS_MAC_ADDR_SIZE));
7084 if (!params->bssid)
7085 {
7086 hddLog (VOS_TRACE_LEVEL_ERROR,
7087 "%s:Failed memory allocation", __func__);
7088 return -EIO;
7089 }
7090 vos_mem_copy((v_U8_t *)params->bssid,
7091 (v_U8_t *)&pHddCtx->cfg_ini->IbssBssid.bytes[0],
7092 VOS_MAC_ADDR_SIZE);
7093 alloc_bssid = VOS_TRUE;
7094 }
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -07007095
Jeff Johnson295189b2012-06-20 16:38:30 -07007096 /* Set Channel */
Yue Maf49ba872013-08-19 12:04:25 -07007097 if (NULL !=
7098#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
7099 params->chandef.chan)
7100#else
7101 params->channel)
7102#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007103 {
7104 u8 channelNum;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07007105 v_U32_t numChans = WNI_CFG_VALID_CHANNEL_LIST_LEN;
7106 v_U8_t validChan[WNI_CFG_VALID_CHANNEL_LIST_LEN];
7107 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
7108 int indx;
Jeff Johnson295189b2012-06-20 16:38:30 -07007109
7110 /* Get channel number */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307111 channelNum =
Yue Maf49ba872013-08-19 12:04:25 -07007112 ieee80211_frequency_to_channel(
7113#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
7114 params->chandef.chan->center_freq);
7115#else
7116 params->channel->center_freq);
7117#endif
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07007118
7119 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
7120 validChan, &numChans))
Jeff Johnson295189b2012-06-20 16:38:30 -07007121 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07007122 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid channel list",
7123 __func__);
7124 return -EOPNOTSUPP;
Jeff Johnson295189b2012-06-20 16:38:30 -07007125 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07007126
7127 for (indx = 0; indx < numChans; indx++)
Jeff Johnson295189b2012-06-20 16:38:30 -07007128 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07007129 if (channelNum == validChan[indx])
7130 {
7131 break;
7132 }
7133 }
7134 if (indx >= numChans)
7135 {
7136 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Not valid Channel %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07007137 __func__, channelNum);
7138 return -EINVAL;
7139 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07007140 /* Set the Operational Channel */
7141 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: set channel %d", __func__,
7142 channelNum);
7143 pRoamProfile->ChannelInfo.numOfChannels = 1;
7144 pHddStaCtx->conn_info.operationChannel = channelNum;
7145 pRoamProfile->ChannelInfo.ChannelList =
7146 &pHddStaCtx->conn_info.operationChannel;
Jeff Johnson295189b2012-06-20 16:38:30 -07007147 }
7148
7149 /* Initialize security parameters */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307150 status = wlan_hdd_cfg80211_set_privacy_ibss(pAdapter, params);
Jeff Johnson295189b2012-06-20 16:38:30 -07007151 if (status < 0)
7152 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307153 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security parameters",
Jeff Johnson295189b2012-06-20 16:38:30 -07007154 __func__);
7155 return status;
7156 }
7157
7158 /* Issue connect start */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307159 status = wlan_hdd_cfg80211_connect_start(pAdapter, params->ssid,
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07007160 params->ssid_len, params->bssid,
7161 pHddStaCtx->conn_info.operationChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -07007162
7163 if (0 > status)
7164 {
7165 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: connect failed", __func__);
7166 return status;
7167 }
7168
krunal sonie9002db2013-11-25 14:24:17 -08007169 if (NULL != params->bssid &&
7170 pHddCtx->cfg_ini->isCoalesingInIBSSAllowed == 0 &&
7171 alloc_bssid == VOS_TRUE)
7172 {
7173 vos_mem_free(params->bssid);
7174 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007175 return 0;
7176}
7177
7178/*
7179 * FUNCTION: wlan_hdd_cfg80211_leave_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307180 * This function is used to leave an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -07007181 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307182static int wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07007183 struct net_device *dev
7184 )
7185{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307186 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Jeff Johnson295189b2012-06-20 16:38:30 -07007187 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
7188 tCsrRoamProfile *pRoamProfile;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307189 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7190 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07007191
7192 ENTER();
7193
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307194 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7195 TRACE_CODE_HDD_CFG80211_LEAVE_IBSS,
7196 pAdapter->sessionId, eCSR_DISCONNECT_REASON_IBSS_LEAVE));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307197 status = wlan_hdd_validate_context(pHddCtx);
7198
7199 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007200 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307201 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7202 "%s: HDD context is not valid", __func__);
7203 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007204 }
7205
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05307206 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)", __func__,
7207 hdd_device_modetoString(pAdapter->device_mode),
7208 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07007209 if (NULL == pWextState)
7210 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08007211 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -07007212 __func__);
7213 return -EIO;
7214 }
7215
7216 pRoamProfile = &pWextState->roamProfile;
7217
7218 /* Issue disconnect only if interface type is set to IBSS */
7219 if (eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType)
7220 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307221 hddLog (VOS_TRACE_LEVEL_ERROR, "%s: BSS Type is not set to IBSS",
Jeff Johnson295189b2012-06-20 16:38:30 -07007222 __func__);
7223 return -EINVAL;
7224 }
7225
7226 /* Issue Disconnect request */
7227 INIT_COMPLETION(pAdapter->disconnect_comp_var);
7228 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
7229 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
7230
7231 return 0;
7232}
7233
7234/*
7235 * FUNCTION: wlan_hdd_cfg80211_set_wiphy_params
7236 * This function is used to set the phy parameters
7237 * (RTS Threshold/FRAG Threshold/Retry Count etc ...)
7238 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307239static int wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07007240 u32 changed)
7241{
7242 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
7243 tHalHandle hHal = pHddCtx->hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307244 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07007245
7246 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307247 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7248 TRACE_CODE_HDD_CFG80211_SET_WIPHY_PARAMS,
7249 NO_SESSION, wiphy->rts_threshold));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307250 status = wlan_hdd_validate_context(pHddCtx);
7251
7252 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007253 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307254 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7255 "%s: HDD context is not valid", __func__);
7256 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007257 }
7258
Jeff Johnson295189b2012-06-20 16:38:30 -07007259 if (changed & WIPHY_PARAM_RTS_THRESHOLD)
7260 {
7261 u16 rts_threshold = (wiphy->rts_threshold == -1) ?
7262 WNI_CFG_RTS_THRESHOLD_STAMAX :
7263 wiphy->rts_threshold;
7264
7265 if ((WNI_CFG_RTS_THRESHOLD_STAMIN > rts_threshold) ||
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307266 (WNI_CFG_RTS_THRESHOLD_STAMAX < rts_threshold))
Jeff Johnson295189b2012-06-20 16:38:30 -07007267 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307268 hddLog(VOS_TRACE_LEVEL_ERROR,
7269 "%s: Invalid RTS Threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07007270 __func__, rts_threshold);
7271 return -EINVAL;
7272 }
7273
7274 if (0 != ccmCfgSetInt(hHal, WNI_CFG_RTS_THRESHOLD,
7275 rts_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307276 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -07007277 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307278 hddLog(VOS_TRACE_LEVEL_ERROR,
7279 "%s: ccmCfgSetInt failed for rts_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07007280 __func__, rts_threshold);
7281 return -EIO;
7282 }
7283
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307284 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set rts threshold %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07007285 rts_threshold);
7286 }
7287
7288 if (changed & WIPHY_PARAM_FRAG_THRESHOLD)
7289 {
7290 u16 frag_threshold = (wiphy->frag_threshold == -1) ?
7291 WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX :
7292 wiphy->frag_threshold;
7293
7294 if ((WNI_CFG_FRAGMENTATION_THRESHOLD_STAMIN > frag_threshold)||
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307295 (WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX < frag_threshold) )
Jeff Johnson295189b2012-06-20 16:38:30 -07007296 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307297 hddLog(VOS_TRACE_LEVEL_ERROR,
7298 "%s: Invalid frag_threshold value %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07007299 frag_threshold);
7300 return -EINVAL;
7301 }
7302
7303 if (0 != ccmCfgSetInt(hHal, WNI_CFG_FRAGMENTATION_THRESHOLD,
7304 frag_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307305 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -07007306 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307307 hddLog(VOS_TRACE_LEVEL_ERROR,
7308 "%s: ccmCfgSetInt failed for frag_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07007309 __func__, frag_threshold);
7310 return -EIO;
7311 }
7312
7313 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set frag threshold %hu", __func__,
7314 frag_threshold);
7315 }
7316
7317 if ((changed & WIPHY_PARAM_RETRY_SHORT)
7318 || (changed & WIPHY_PARAM_RETRY_LONG))
7319 {
7320 u8 retry_value = (changed & WIPHY_PARAM_RETRY_SHORT) ?
7321 wiphy->retry_short :
7322 wiphy->retry_long;
7323
7324 if ((WNI_CFG_LONG_RETRY_LIMIT_STAMIN > retry_value) ||
7325 (WNI_CFG_LONG_RETRY_LIMIT_STAMAX < retry_value))
7326 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307327 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07007328 __func__, retry_value);
7329 return -EINVAL;
7330 }
7331
7332 if (changed & WIPHY_PARAM_RETRY_SHORT)
7333 {
7334 if (0 != ccmCfgSetInt(hHal, WNI_CFG_LONG_RETRY_LIMIT,
7335 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307336 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -07007337 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307338 hddLog(VOS_TRACE_LEVEL_ERROR,
7339 "%s: ccmCfgSetInt failed for long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07007340 __func__, retry_value);
7341 return -EIO;
7342 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307343 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07007344 __func__, retry_value);
7345 }
7346 else if (changed & WIPHY_PARAM_RETRY_SHORT)
7347 {
7348 if (0 != ccmCfgSetInt(hHal, WNI_CFG_SHORT_RETRY_LIMIT,
7349 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307350 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -07007351 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307352 hddLog(VOS_TRACE_LEVEL_ERROR,
7353 "%s: ccmCfgSetInt failed for short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07007354 __func__, retry_value);
7355 return -EIO;
7356 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307357 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07007358 __func__, retry_value);
7359 }
7360 }
7361
7362 return 0;
7363}
7364
7365/*
7366 * FUNCTION: wlan_hdd_cfg80211_set_txpower
7367 * This function is used to set the txpower
7368 */
7369static int wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
Yue Maf49ba872013-08-19 12:04:25 -07007370#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
7371 struct wireless_dev *wdev,
7372#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007373#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307374 enum tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -07007375#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307376 enum nl80211_tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -07007377#endif
7378 int dbm)
7379{
7380 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307381 tHalHandle hHal = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07007382 tSirMacAddr bssid = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
7383 tSirMacAddr selfMac = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307384 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07007385
7386 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307387 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7388 TRACE_CODE_HDD_CFG80211_SET_TXPOWER,
7389 NO_SESSION, type ));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307390 status = wlan_hdd_validate_context(pHddCtx);
7391
7392 if (0 != status)
7393 {
7394 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7395 "%s: HDD context is not valid", __func__);
7396 return status;
7397 }
7398
7399 hHal = pHddCtx->hHal;
7400
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307401 if (0 != ccmCfgSetInt(hHal, WNI_CFG_CURRENT_TX_POWER_LEVEL,
7402 dbm, ccmCfgSetCallback,
7403 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -07007404 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307405 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07007406 "%s: ccmCfgSetInt failed for tx power %hu", __func__, dbm);
7407 return -EIO;
7408 }
7409
7410 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set tx power level %d dbm", __func__,
7411 dbm);
7412
7413 switch(type)
7414 {
7415 case NL80211_TX_POWER_AUTOMATIC: /*automatically determine transmit power*/
7416 /* Fall through */
7417 case NL80211_TX_POWER_LIMITED: /*limit TX power by the mBm parameter*/
7418 if( sme_SetMaxTxPower(hHal, bssid, selfMac, dbm) != eHAL_STATUS_SUCCESS )
7419 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307420 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Setting maximum tx power failed",
7421 __func__);
7422 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -07007423 }
7424 break;
7425 case NL80211_TX_POWER_FIXED: /*fix TX power to the mBm parameter*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307426 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: NL80211_TX_POWER_FIXED not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -07007427 __func__);
7428 return -EOPNOTSUPP;
7429 break;
7430 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307431 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid power setting type %d",
7432 __func__, type);
Jeff Johnson295189b2012-06-20 16:38:30 -07007433 return -EIO;
7434 }
7435
7436 return 0;
7437}
7438
7439/*
7440 * FUNCTION: wlan_hdd_cfg80211_get_txpower
7441 * This function is used to read the txpower
7442 */
Yue Maf49ba872013-08-19 12:04:25 -07007443static int wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy,
7444#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
7445 struct wireless_dev *wdev,
7446#endif
7447 int *dbm)
Jeff Johnson295189b2012-06-20 16:38:30 -07007448{
7449
7450 hdd_adapter_t *pAdapter;
7451 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307452 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07007453
Jeff Johnsone7245742012-09-05 17:12:55 -07007454 ENTER();
7455
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307456 status = wlan_hdd_validate_context(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07007457
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307458 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007459 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307460 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7461 "%s: HDD context is not valid", __func__);
7462 *dbm = 0;
7463 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007464 }
7465
Jeff Johnson295189b2012-06-20 16:38:30 -07007466 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
7467 if (NULL == pAdapter)
7468 {
7469 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Not in station context " ,__func__);
7470 return -ENOENT;
7471 }
7472
7473 wlan_hdd_get_classAstats(pAdapter);
7474 *dbm = pAdapter->hdd_stats.ClassA_stat.max_pwr;
7475
Jeff Johnsone7245742012-09-05 17:12:55 -07007476 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07007477 return 0;
7478}
7479
7480static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
7481 u8* mac, struct station_info *sinfo)
7482{
7483 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
7484 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7485 int ssidlen = pHddStaCtx->conn_info.SSID.SSID.length;
c_hpothu44ff4e02014-05-08 00:13:57 +05307486 tANI_U32 rate_flags;
Jeff Johnson295189b2012-06-20 16:38:30 -07007487
7488 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
7489 hdd_config_t *pCfg = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -07007490
7491 tANI_U8 OperationalRates[CSR_DOT11_SUPPORTED_RATES_MAX];
7492 tANI_U32 ORLeng = CSR_DOT11_SUPPORTED_RATES_MAX;
7493 tANI_U8 ExtendedRates[CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX];
7494 tANI_U32 ERLeng = CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX;
7495 tANI_U8 MCSRates[SIZE_OF_BASIC_MCS_SET];
7496 tANI_U32 MCSLeng = SIZE_OF_BASIC_MCS_SET;
7497 tANI_U16 maxRate = 0;
7498 tANI_U16 myRate;
7499 tANI_U16 currentRate = 0;
7500 tANI_U8 maxSpeedMCS = 0;
7501 tANI_U8 maxMCSIdx = 0;
7502 tANI_U8 rateFlag = 1;
7503 tANI_U8 i, j, rssidx;
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07007504 tANI_U16 temp;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307505 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07007506
Leo Chang6f8870f2013-03-26 18:11:36 -07007507#ifdef WLAN_FEATURE_11AC
7508 tANI_U32 vht_mcs_map;
7509 eDataRate11ACMaxMcs vhtMaxMcs;
7510#endif /* WLAN_FEATURE_11AC */
7511
Jeff Johnsone7245742012-09-05 17:12:55 -07007512 ENTER();
7513
Jeff Johnson295189b2012-06-20 16:38:30 -07007514 if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) ||
7515 (0 == ssidlen))
7516 {
7517 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Not associated or"
7518 " Invalid ssidlen, %d", __func__, ssidlen);
7519 /*To keep GUI happy*/
7520 return 0;
7521 }
7522
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307523 status = wlan_hdd_validate_context(pHddCtx);
7524
7525 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007526 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307527 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7528 "%s: HDD context is not valid", __func__);
7529 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007530 }
7531
Jeff Johnson295189b2012-06-20 16:38:30 -07007532
Kiet Lam3b17fc82013-09-27 05:24:08 +05307533 wlan_hdd_get_rssi(pAdapter, &sinfo->signal);
7534 sinfo->filled |= STATION_INFO_SIGNAL;
7535
c_hpothu44ff4e02014-05-08 00:13:57 +05307536 if ((eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed) ||
7537 (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed &&
7538 sinfo->signal >= pCfg->linkSpeedRssiHigh))
7539 {
7540 rate_flags = pAdapter->maxRateFlags;
7541 }
7542 else
7543 {
7544 wlan_hdd_get_station_stats(pAdapter);
7545 rate_flags = pAdapter->hdd_stats.ClassA_stat.tx_rate_flags;
7546 }
7547
Jeff Johnson295189b2012-06-20 16:38:30 -07007548 //convert to the UI units of 100kbps
7549 myRate = pAdapter->hdd_stats.ClassA_stat.tx_rate * 5;
7550
7551#ifdef LINKSPEED_DEBUG_ENABLED
Leo Chang6f8870f2013-03-26 18:11:36 -07007552 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 -07007553 sinfo->signal,
7554 pCfg->reportMaxLinkSpeed,
7555 myRate,
7556 (int) pCfg->linkSpeedRssiHigh,
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07007557 (int) pCfg->linkSpeedRssiMid,
7558 (int) pCfg->linkSpeedRssiLow,
Leo Chang6f8870f2013-03-26 18:11:36 -07007559 (int) rate_flags,
7560 (int) pAdapter->hdd_stats.ClassA_stat.mcs_index);
Jeff Johnson295189b2012-06-20 16:38:30 -07007561#endif //LINKSPEED_DEBUG_ENABLED
7562
7563 if (eHDD_LINK_SPEED_REPORT_ACTUAL != pCfg->reportMaxLinkSpeed)
7564 {
7565 // we do not want to necessarily report the current speed
7566 if (eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed)
7567 {
7568 // report the max possible speed
7569 rssidx = 0;
7570 }
7571 else if (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed)
7572 {
7573 // report the max possible speed with RSSI scaling
7574 if (sinfo->signal >= pCfg->linkSpeedRssiHigh)
7575 {
7576 // report the max possible speed
7577 rssidx = 0;
7578 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07007579 else if (sinfo->signal >= pCfg->linkSpeedRssiMid)
Jeff Johnson295189b2012-06-20 16:38:30 -07007580 {
7581 // report middle speed
7582 rssidx = 1;
7583 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07007584 else if (sinfo->signal >= pCfg->linkSpeedRssiLow)
7585 {
7586 // report middle speed
7587 rssidx = 2;
7588 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007589 else
7590 {
7591 // report actual speed
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07007592 rssidx = 3;
Jeff Johnson295189b2012-06-20 16:38:30 -07007593 }
7594 }
7595 else
7596 {
7597 // unknown, treat as eHDD_LINK_SPEED_REPORT_MAX
7598 hddLog(VOS_TRACE_LEVEL_ERROR,
7599 "%s: Invalid value for reportMaxLinkSpeed: %u",
7600 __func__, pCfg->reportMaxLinkSpeed);
7601 rssidx = 0;
7602 }
7603
7604 maxRate = 0;
7605
7606 /* Get Basic Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +05307607 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_OPERATIONAL_RATE_SET,
7608 OperationalRates, &ORLeng))
7609 {
7610 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
7611 /*To keep GUI happy*/
7612 return 0;
7613 }
7614
Jeff Johnson295189b2012-06-20 16:38:30 -07007615 for (i = 0; i < ORLeng; i++)
7616 {
Jeff Johnsone7245742012-09-05 17:12:55 -07007617 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -07007618 {
7619 /* Validate Rate Set */
7620 if (supported_data_rate[j].beacon_rate_index == (OperationalRates[i] & 0x7F))
7621 {
7622 currentRate = supported_data_rate[j].supported_rate[rssidx];
7623 break;
7624 }
7625 }
7626 /* Update MAX rate */
7627 maxRate = (currentRate > maxRate)?currentRate:maxRate;
7628 }
7629
7630 /* Get Extended Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +05307631 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET,
7632 ExtendedRates, &ERLeng))
7633 {
7634 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
7635 /*To keep GUI happy*/
7636 return 0;
7637 }
7638
Jeff Johnson295189b2012-06-20 16:38:30 -07007639 for (i = 0; i < ERLeng; i++)
7640 {
Jeff Johnsone7245742012-09-05 17:12:55 -07007641 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -07007642 {
7643 if (supported_data_rate[j].beacon_rate_index == (ExtendedRates[i] & 0x7F))
7644 {
7645 currentRate = supported_data_rate[j].supported_rate[rssidx];
7646 break;
7647 }
7648 }
7649 /* Update MAX rate */
7650 maxRate = (currentRate > maxRate)?currentRate:maxRate;
7651 }
Kiet Lamb69f8dc2013-11-15 15:34:27 +05307652 /* Get MCS Rate Set --
Kaushik, Sushantdc304d82014-01-22 10:58:37 +05307653 Only if we are always reporting max speed (or)
Kiet Lamb69f8dc2013-11-15 15:34:27 +05307654 if we have good rssi */
Kaushik, Sushantdc304d82014-01-22 10:58:37 +05307655 if ((0 == rssidx) ||
Kiet Lamb69f8dc2013-11-15 15:34:27 +05307656 (eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed))
Jeff Johnson295189b2012-06-20 16:38:30 -07007657 {
Gopichand Nakkala05ab1322013-02-15 11:28:38 +05307658 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_CURRENT_MCS_SET,
7659 MCSRates, &MCSLeng))
7660 {
7661 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
7662 /*To keep GUI happy*/
7663 return 0;
7664 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007665 rateFlag = 0;
Leo Chang6f8870f2013-03-26 18:11:36 -07007666#ifdef WLAN_FEATURE_11AC
7667 /* VHT80 rate has seperate rate table */
Gopichand Nakkala4c705372013-04-24 13:20:33 +05307668 if (rate_flags & (eHAL_TX_RATE_VHT20|eHAL_TX_RATE_VHT40|eHAL_TX_RATE_VHT80))
Jeff Johnson295189b2012-06-20 16:38:30 -07007669 {
Leo Chang6f8870f2013-03-26 18:11:36 -07007670 ccmCfgGetInt(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_VHT_TX_MCS_MAP, &vht_mcs_map);
Gopichand Nakkala4c705372013-04-24 13:20:33 +05307671 vhtMaxMcs = (eDataRate11ACMaxMcs)(vht_mcs_map & DATA_RATE_11AC_MCS_MASK );
Leo Chang6f8870f2013-03-26 18:11:36 -07007672 if (rate_flags & eHAL_TX_RATE_SGI)
Jeff Johnson295189b2012-06-20 16:38:30 -07007673 {
Leo Chang6f8870f2013-03-26 18:11:36 -07007674 rateFlag |= 1;
Jeff Johnson295189b2012-06-20 16:38:30 -07007675 }
Leo Chang6f8870f2013-03-26 18:11:36 -07007676 if (DATA_RATE_11AC_MAX_MCS_7 == vhtMaxMcs)
Jeff Johnson295189b2012-06-20 16:38:30 -07007677 {
Leo Chang6f8870f2013-03-26 18:11:36 -07007678 maxMCSIdx = 7;
7679 }
7680 else if (DATA_RATE_11AC_MAX_MCS_8 == vhtMaxMcs)
7681 {
7682 maxMCSIdx = 8;
7683 }
7684 else if (DATA_RATE_11AC_MAX_MCS_9 == vhtMaxMcs)
7685 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +05307686 //VHT20 is supporting 0~8
7687 if (rate_flags & eHAL_TX_RATE_VHT20)
7688 maxMCSIdx = 8;
7689 else
7690 maxMCSIdx = 9;
Leo Chang6f8870f2013-03-26 18:11:36 -07007691 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +05307692
7693 if (rate_flags & eHAL_TX_RATE_VHT80)
7694 {
7695 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT80_rate[rateFlag];
7696 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT80_rate[rateFlag];
7697 }
7698 else if (rate_flags & eHAL_TX_RATE_VHT40)
7699 {
7700 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT40_rate[rateFlag];
7701 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT40_rate[rateFlag];
7702 }
7703 else if (rate_flags & eHAL_TX_RATE_VHT20)
7704 {
7705 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT20_rate[rateFlag];
7706 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT20_rate[rateFlag];
7707 }
7708
Leo Chang6f8870f2013-03-26 18:11:36 -07007709 maxSpeedMCS = 1;
7710 if (currentRate > maxRate)
7711 {
7712 maxRate = currentRate;
7713 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +05307714
Leo Chang6f8870f2013-03-26 18:11:36 -07007715 }
7716 else
7717#endif /* WLAN_FEATURE_11AC */
7718 {
7719 if (rate_flags & eHAL_TX_RATE_HT40)
7720 {
7721 rateFlag |= 1;
7722 }
7723 if (rate_flags & eHAL_TX_RATE_SGI)
7724 {
7725 rateFlag |= 2;
7726 }
7727
7728 for (i = 0; i < MCSLeng; i++)
7729 {
7730 temp = sizeof(supported_mcs_rate) / sizeof(supported_mcs_rate[0]);
7731 for (j = 0; j < temp; j++)
7732 {
7733 if (supported_mcs_rate[j].beacon_rate_index == MCSRates[i])
7734 {
7735 currentRate = supported_mcs_rate[j].supported_rate[rateFlag];
7736 break;
7737 }
7738 }
7739 if ((j < temp) && (currentRate > maxRate))
7740 {
7741 maxRate = currentRate;
7742 maxSpeedMCS = 1;
7743 maxMCSIdx = supported_mcs_rate[j].beacon_rate_index;
7744 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007745 }
7746 }
7747 }
7748
Gopichand Nakkala4c705372013-04-24 13:20:33 +05307749 else if (!(rate_flags & eHAL_TX_RATE_LEGACY))
7750 {
7751 maxRate = myRate;
7752 maxSpeedMCS = 1;
7753 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
7754 }
7755
Jeff Johnson295189b2012-06-20 16:38:30 -07007756 // make sure we report a value at least as big as our current rate
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07007757 if (((maxRate < myRate) && (0 == rssidx)) ||
7758 (0 == maxRate))
Jeff Johnson295189b2012-06-20 16:38:30 -07007759 {
7760 maxRate = myRate;
7761 if (rate_flags & eHAL_TX_RATE_LEGACY)
7762 {
7763 maxSpeedMCS = 0;
7764 }
7765 else
7766 {
7767 maxSpeedMCS = 1;
7768 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
7769 }
7770 }
7771
Gopichand Nakkala4c705372013-04-24 13:20:33 +05307772 if (rate_flags & eHAL_TX_RATE_LEGACY)
Jeff Johnson295189b2012-06-20 16:38:30 -07007773 {
7774 sinfo->txrate.legacy = maxRate;
7775#ifdef LINKSPEED_DEBUG_ENABLED
7776 pr_info("Reporting legacy rate %d\n", sinfo->txrate.legacy);
7777#endif //LINKSPEED_DEBUG_ENABLED
7778 }
7779 else
7780 {
7781 sinfo->txrate.mcs = maxMCSIdx;
Leo Chang6f8870f2013-03-26 18:11:36 -07007782#ifdef WLAN_FEATURE_11AC
7783 sinfo->txrate.nss = 1;
7784 if (rate_flags & eHAL_TX_RATE_VHT80)
7785 {
7786 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
Gopichand Nakkala4c705372013-04-24 13:20:33 +05307787 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
Leo Chang6f8870f2013-03-26 18:11:36 -07007788 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +05307789 else if (rate_flags & eHAL_TX_RATE_VHT40)
Leo Chang6f8870f2013-03-26 18:11:36 -07007790 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +05307791 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
7792 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
7793 }
7794 else if (rate_flags & eHAL_TX_RATE_VHT20)
7795 {
7796 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
7797 }
7798#endif /* WLAN_FEATURE_11AC */
7799 if (rate_flags & (eHAL_TX_RATE_HT20 | eHAL_TX_RATE_HT40))
7800 {
7801 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
7802 if (rate_flags & eHAL_TX_RATE_HT40)
7803 {
7804 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
7805 }
Leo Chang6f8870f2013-03-26 18:11:36 -07007806 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007807 if (rate_flags & eHAL_TX_RATE_SGI)
7808 {
7809 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
7810 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +05307811
Jeff Johnson295189b2012-06-20 16:38:30 -07007812#ifdef LINKSPEED_DEBUG_ENABLED
7813 pr_info("Reporting MCS rate %d flags %x\n",
7814 sinfo->txrate.mcs,
7815 sinfo->txrate.flags );
7816#endif //LINKSPEED_DEBUG_ENABLED
7817 }
7818 }
7819 else
7820 {
7821 // report current rate instead of max rate
7822
7823 if (rate_flags & eHAL_TX_RATE_LEGACY)
7824 {
7825 //provide to the UI in units of 100kbps
7826 sinfo->txrate.legacy = myRate;
7827#ifdef LINKSPEED_DEBUG_ENABLED
7828 pr_info("Reporting actual legacy rate %d\n", sinfo->txrate.legacy);
7829#endif //LINKSPEED_DEBUG_ENABLED
7830 }
7831 else
7832 {
7833 //must be MCS
7834 sinfo->txrate.mcs = pAdapter->hdd_stats.ClassA_stat.mcs_index;
Leo Chang6f8870f2013-03-26 18:11:36 -07007835#ifdef WLAN_FEATURE_11AC
7836 sinfo->txrate.nss = 1;
7837 if (rate_flags & eHAL_TX_RATE_VHT80)
7838 {
7839 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
7840 }
7841 else
7842#endif /* WLAN_FEATURE_11AC */
7843 {
7844 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
7845 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007846 if (rate_flags & eHAL_TX_RATE_SGI)
7847 {
7848 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
7849 }
7850 if (rate_flags & eHAL_TX_RATE_HT40)
7851 {
7852 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
7853 }
Leo Chang6f8870f2013-03-26 18:11:36 -07007854#ifdef WLAN_FEATURE_11AC
7855 else if (rate_flags & eHAL_TX_RATE_VHT80)
7856 {
7857 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
7858 }
7859#endif /* WLAN_FEATURE_11AC */
Jeff Johnson295189b2012-06-20 16:38:30 -07007860#ifdef LINKSPEED_DEBUG_ENABLED
7861 pr_info("Reporting actual MCS rate %d flags %x\n",
7862 sinfo->txrate.mcs,
7863 sinfo->txrate.flags );
7864#endif //LINKSPEED_DEBUG_ENABLED
7865 }
7866 }
7867 sinfo->filled |= STATION_INFO_TX_BITRATE;
7868
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -07007869 sinfo->tx_packets =
7870 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[0] +
7871 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[1] +
7872 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[2] +
7873 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[3];
7874
7875 sinfo->tx_retries =
7876 pAdapter->hdd_stats.summary_stat.retry_cnt[0] +
7877 pAdapter->hdd_stats.summary_stat.retry_cnt[1] +
7878 pAdapter->hdd_stats.summary_stat.retry_cnt[2] +
7879 pAdapter->hdd_stats.summary_stat.retry_cnt[3];
7880
7881 sinfo->tx_failed =
7882 pAdapter->hdd_stats.summary_stat.fail_cnt[0] +
7883 pAdapter->hdd_stats.summary_stat.fail_cnt[1] +
7884 pAdapter->hdd_stats.summary_stat.fail_cnt[2] +
7885 pAdapter->hdd_stats.summary_stat.fail_cnt[3];
7886
7887 sinfo->filled |=
7888 STATION_INFO_TX_PACKETS |
7889 STATION_INFO_TX_RETRIES |
7890 STATION_INFO_TX_FAILED;
7891
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307892 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7893 TRACE_CODE_HDD_CFG80211_GET_STA,
7894 pAdapter->sessionId, maxRate));
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -07007895 EXIT();
7896 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07007897}
7898
7899static int wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
Sameer Thalappilc9f26e92013-06-07 10:11:06 -07007900 struct net_device *dev, bool mode, int timeout)
Jeff Johnson295189b2012-06-20 16:38:30 -07007901{
7902 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +05307903 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07007904 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307905 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07007906
Jeff Johnsone7245742012-09-05 17:12:55 -07007907 ENTER();
7908
Jeff Johnson295189b2012-06-20 16:38:30 -07007909 if (NULL == pAdapter)
7910 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08007911 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007912 return -ENODEV;
7913 }
7914
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307915 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7916 TRACE_CODE_HDD_CFG80211_SET_POWER_MGMT,
7917 pAdapter->sessionId, timeout));
7918
Gopichand Nakkala20c4c042013-04-19 22:08:55 +05307919 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307920 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +05307921
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307922 if (0 != status)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307923 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307924 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7925 "%s: HDD context is not valid", __func__);
7926 return status;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307927 }
7928
Gopichand Nakkala20c4c042013-04-19 22:08:55 +05307929 if ((DRIVER_POWER_MODE_AUTO == !mode) &&
7930 (TRUE == pHddCtx->hdd_wlan_suspended) &&
7931 (pHddCtx->cfg_ini->fhostArpOffload) &&
7932 (eConnectionState_Associated ==
7933 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
7934 {
Amar Singhald53568e2013-09-26 11:03:45 -07007935
7936 hddLog(VOS_TRACE_LEVEL_INFO,
7937 "offload: in cfg80211_set_power_mgmt, calling arp offload");
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05307938 vos_status = hdd_conf_arp_offload(pAdapter, TRUE);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +05307939 if (!VOS_IS_STATUS_SUCCESS(vos_status))
7940 {
7941 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007942 "%s:Failed to enable ARPOFFLOAD Feature %d",
Gopichand Nakkala20c4c042013-04-19 22:08:55 +05307943 __func__, vos_status);
7944 }
7945 }
7946
Jeff Johnson295189b2012-06-20 16:38:30 -07007947 /**The get power cmd from the supplicant gets updated by the nl only
7948 *on successful execution of the function call
7949 *we are oppositely mapped w.r.t mode in the driver
7950 **/
7951 vos_status = wlan_hdd_enter_bmps(pAdapter, !mode);
7952
Jeff Johnsone7245742012-09-05 17:12:55 -07007953 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07007954 if (VOS_STATUS_E_FAILURE == vos_status)
7955 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307956 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7957 "%s: failed to enter bmps mode", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007958 return -EINVAL;
7959 }
7960 return 0;
7961}
7962
7963
7964#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
7965static int wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
7966 struct net_device *netdev,
7967 u8 key_index)
7968{
Jeff Johnsone7245742012-09-05 17:12:55 -07007969 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07007970 return 0;
7971}
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307972#endif //LINUX_VERSION_CODE
Jeff Johnson295189b2012-06-20 16:38:30 -07007973
7974#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
7975static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
7976 struct net_device *dev,
7977 struct ieee80211_txq_params *params)
7978{
Jeff Johnsone7245742012-09-05 17:12:55 -07007979 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07007980 return 0;
7981}
7982#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
7983static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
7984 struct ieee80211_txq_params *params)
7985{
Jeff Johnsone7245742012-09-05 17:12:55 -07007986 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07007987 return 0;
7988}
7989#endif //LINUX_VERSION_CODE
7990
7991static int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
7992 struct net_device *dev, u8 *mac)
7993{
7994 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307995 hdd_context_t *pHddCtx;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08007996 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307997 int status;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08007998 v_U8_t staId;
Jeff Johnson295189b2012-06-20 16:38:30 -07007999
Jeff Johnsone7245742012-09-05 17:12:55 -07008000 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308001
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308002 if ( NULL == pAdapter )
Jeff Johnson295189b2012-06-20 16:38:30 -07008003 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308004 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008005 return -EINVAL;
8006 }
8007
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308008 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
8009 TRACE_CODE_HDD_CFG80211_DEL_STA,
8010 pAdapter->sessionId, pAdapter->device_mode));
8011
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308012 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8013 status = wlan_hdd_validate_context(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07008014
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308015 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008016 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308017 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8018 "%s: HDD context is not valid", __func__);
8019 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008020 }
8021
Jeff Johnson295189b2012-06-20 16:38:30 -07008022 if ( (WLAN_HDD_SOFTAP == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -07008023 || (WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -07008024 )
8025 {
8026 if( NULL == mac )
8027 {
8028 v_U16_t i;
8029 for(i = 0; i < WLAN_MAX_STA_COUNT; i++)
8030 {
Rajesh Chauhan18488fc2013-08-22 10:15:03 -07008031 if ((pAdapter->aStaInfo[i].isUsed) &&
8032 (!pAdapter->aStaInfo[i].isDeauthInProgress))
Jeff Johnson295189b2012-06-20 16:38:30 -07008033 {
8034 u8 *macAddr = pAdapter->aStaInfo[i].macAddrSTA.bytes;
8035 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -08008036 "%s: Delete STA with MAC::"
8037 MAC_ADDRESS_STR,
8038 __func__, MAC_ADDR_ARRAY(macAddr));
Rajesh Chauhan18488fc2013-08-22 10:15:03 -07008039 vos_status = hdd_softap_sta_deauth(pAdapter, macAddr);
8040 if (VOS_IS_STATUS_SUCCESS(vos_status))
8041 pAdapter->aStaInfo[i].isDeauthInProgress = TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -07008042 }
8043 }
8044 }
8045 else
8046 {
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08008047
8048 vos_status = hdd_softap_GetStaId(pAdapter,(v_MACADDR_t *)mac, &staId);
8049 if (!VOS_IS_STATUS_SUCCESS(vos_status))
8050 {
8051 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -08008052 "%s: Skip this DEL STA as this is not used::"
8053 MAC_ADDRESS_STR,
8054 __func__, MAC_ADDR_ARRAY(mac));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08008055 return -ENOENT;
8056 }
8057
8058 if( pAdapter->aStaInfo[staId].isDeauthInProgress == TRUE)
8059 {
8060 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -08008061 "%s: Skip this DEL STA as deauth is in progress::"
8062 MAC_ADDRESS_STR,
8063 __func__, MAC_ADDR_ARRAY(mac));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08008064 return -ENOENT;
8065 }
8066
8067 pAdapter->aStaInfo[staId].isDeauthInProgress = TRUE;
8068
Jeff Johnson295189b2012-06-20 16:38:30 -07008069 hddLog(VOS_TRACE_LEVEL_INFO,
8070 "%s: Delete STA with MAC::"
Arif Hussain24bafea2013-11-15 15:10:03 -08008071 MAC_ADDRESS_STR,
Jeff Johnson295189b2012-06-20 16:38:30 -07008072 __func__,
Arif Hussain24bafea2013-11-15 15:10:03 -08008073 MAC_ADDR_ARRAY(mac));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08008074
8075 vos_status = hdd_softap_sta_deauth(pAdapter, mac);
8076 if (!VOS_IS_STATUS_SUCCESS(vos_status))
8077 {
8078 pAdapter->aStaInfo[staId].isDeauthInProgress = FALSE;
8079 hddLog(VOS_TRACE_LEVEL_INFO,
8080 "%s: STA removal failed for ::"
Arif Hussain24bafea2013-11-15 15:10:03 -08008081 MAC_ADDRESS_STR,
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08008082 __func__,
Arif Hussain24bafea2013-11-15 15:10:03 -08008083 MAC_ADDR_ARRAY(mac));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08008084 return -ENOENT;
8085 }
8086
Jeff Johnson295189b2012-06-20 16:38:30 -07008087 }
8088 }
8089
8090 EXIT();
8091
8092 return 0;
8093}
8094
Hoonki Lee11f7dda2013-02-14 16:55:44 -08008095static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
8096 struct net_device *dev, u8 *mac, struct station_parameters *params)
8097{
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308098 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkalab977a972013-02-18 19:15:09 -08008099 int status = -EPERM;
Hoonki Lee11f7dda2013-02-14 16:55:44 -08008100#ifdef FEATURE_WLAN_TDLS
8101 u32 mask, set;
Hoonki Lee11f7dda2013-02-14 16:55:44 -08008102 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308103
8104 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
8105 TRACE_CODE_HDD_CFG80211_ADD_STA,
8106 pAdapter->sessionId, params->listen_interval));
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008107 mask = params->sta_flags_mask;
8108
8109 set = params->sta_flags_set;
8110
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07008111#ifdef WLAN_FEATURE_TDLS_DEBUG
8112 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8113 "%s: mask 0x%x set 0x%x " MAC_ADDRESS_STR,
8114 __func__, mask, set, MAC_ADDR_ARRAY(mac));
8115#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008116
8117 if (mask & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
8118 if (set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008119 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 0, NULL);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008120 }
8121 }
8122#endif
Gopichand Nakkalab977a972013-02-18 19:15:09 -08008123 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -07008124}
8125
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008126
8127#ifdef FEATURE_WLAN_LFR
Wilson Yang6507c4e2013-10-01 20:11:19 -07008128
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008129static int wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
Jeff Johnsond13512a2012-07-17 11:42:19 -07008130 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008131{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308132 tANI_U32 j=0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008133 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Agarwal Ashish3da95242014-05-21 14:57:17 +05308134 hdd_station_ctx_t *pHddStaCtx;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008135 tHalHandle halHandle;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308136 eHalStatus result;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308137 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008138 tANI_U8 BSSIDMatched = 0;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308139 hdd_context_t *pHddCtx;
Jeff Johnson0299d0a2013-10-30 12:37:43 -07008140 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: set PMKSA for " MAC_ADDRESS_STR,
8141 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
Jeff Johnsone7245742012-09-05 17:12:55 -07008142
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308143 // Validate pAdapter
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308144 if ( NULL == pAdapter )
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008145 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308146 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008147 return -EINVAL;
8148 }
8149
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308150 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8151 status = wlan_hdd_validate_context(pHddCtx);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008152
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308153 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008154 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308155 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8156 "%s: HDD context is not valid", __func__);
8157 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008158 }
8159
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308160 // Retrieve halHandle
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008161 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
Agarwal Ashish3da95242014-05-21 14:57:17 +05308162 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008163
Agarwal Ashish3da95242014-05-21 14:57:17 +05308164 for (j = 0; j < pHddStaCtx->PMKIDCacheIndex; j++)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008165 {
Agarwal Ashish3da95242014-05-21 14:57:17 +05308166 if (vos_mem_compare(pHddStaCtx->PMKIDCache[j].BSSID,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008167 pmksa->bssid, WNI_CFG_BSSID_LEN))
8168 {
8169 /* BSSID matched previous entry. Overwrite it. */
8170 BSSIDMatched = 1;
Agarwal Ashish3da95242014-05-21 14:57:17 +05308171 vos_mem_copy(pHddStaCtx->PMKIDCache[j].BSSID,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008172 pmksa->bssid, WNI_CFG_BSSID_LEN);
Agarwal Ashish3da95242014-05-21 14:57:17 +05308173 vos_mem_copy(pHddStaCtx->PMKIDCache[j].PMKID,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308174 pmksa->pmkid,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008175 CSR_RSN_PMKID_SIZE);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308176 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Reusing cache entry %d.",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008177 __func__, j );
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008178 dump_bssid(pmksa->bssid);
8179 dump_pmkid(halHandle, pmksa->pmkid);
8180 break;
8181 }
8182 }
8183
Madan Mohan Koyyalamudic4b317d2012-10-18 19:43:08 -07008184 /* Check we compared all entries,if then take the first slot now */
Agarwal Ashish3da95242014-05-21 14:57:17 +05308185 if (j == MAX_PMKSAIDS_IN_CACHE) pHddStaCtx->PMKIDCacheIndex=0;
Madan Mohan Koyyalamudic4b317d2012-10-18 19:43:08 -07008186
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008187 if (!BSSIDMatched)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308188 {
8189 // Now, we DON'T have a BSSID match, so take a new entry in the cache.
Agarwal Ashish3da95242014-05-21 14:57:17 +05308190 vos_mem_copy(pHddStaCtx->PMKIDCache[pHddStaCtx->PMKIDCacheIndex].BSSID,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308191 pmksa->bssid, ETHER_ADDR_LEN);
Agarwal Ashish3da95242014-05-21 14:57:17 +05308192 vos_mem_copy(pHddStaCtx->PMKIDCache[pHddStaCtx->PMKIDCacheIndex].PMKID,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308193 pmksa->pmkid,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008194 CSR_RSN_PMKID_SIZE);
Agarwal Ashish3da95242014-05-21 14:57:17 +05308195 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: Adding a new cache entry %d.",
8196 __func__, pHddStaCtx->PMKIDCacheIndex );
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008197 dump_bssid(pmksa->bssid);
8198 dump_pmkid(halHandle, pmksa->pmkid);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308199 // Increment the HDD Local Cache index
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008200 // The "i=0" doesn't work for the call to sme_RoamSetPMKIDCache() - LFR FIXME
Agarwal Ashish3da95242014-05-21 14:57:17 +05308201 if (pHddStaCtx->PMKIDCacheIndex <= (MAX_PMKSAIDS_IN_CACHE-1))
8202 pHddStaCtx->PMKIDCacheIndex++;
8203 else
8204 pHddStaCtx->PMKIDCacheIndex = 0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008205 }
8206
8207
8208 // Calling csrRoamSetPMKIDCache to configure the PMKIDs into the cache
Agarwal Ashish3da95242014-05-21 14:57:17 +05308209 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: Calling csrRoamSetPMKIDCache with %d cache entries.",
8210 __func__, pHddStaCtx->PMKIDCacheIndex );
8211
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008212 // Finally set the PMKSA ID Cache in CSR
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308213 result = sme_RoamSetPMKIDCache(halHandle,pAdapter->sessionId,
Agarwal Ashish3da95242014-05-21 14:57:17 +05308214 pHddStaCtx->PMKIDCache,
8215 pHddStaCtx->PMKIDCacheIndex);
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308216 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
8217 TRACE_CODE_HDD_CFG80211_SET_PMKSA,
8218 pAdapter->sessionId, result));
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008219 return 0;
8220}
8221
8222
Wilson Yang6507c4e2013-10-01 20:11:19 -07008223
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008224static int wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
Wilson Yang6507c4e2013-10-01 20:11:19 -07008225 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008226{
Wilson Yang6507c4e2013-10-01 20:11:19 -07008227 tANI_U32 j=0;
8228 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Agarwal Ashish3da95242014-05-21 14:57:17 +05308229 hdd_station_ctx_t *pHddStaCtx;
Wilson Yang6507c4e2013-10-01 20:11:19 -07008230 tHalHandle halHandle;
Wilson Yang6507c4e2013-10-01 20:11:19 -07008231 tANI_U8 BSSIDMatched = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -07008232 hdd_context_t *pHddCtx;
Wilson Yangef657d32014-01-15 19:19:23 -08008233 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -07008234
Jeff Johnson0299d0a2013-10-30 12:37:43 -07008235 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: deleting PMKSA for " MAC_ADDRESS_STR,
8236 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
Wilson Yang6507c4e2013-10-01 20:11:19 -07008237
8238 /* Validate pAdapter */
8239 if (NULL == pAdapter)
8240 {
8241 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
8242 return -EINVAL;
8243 }
8244
8245 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8246 status = wlan_hdd_validate_context(pHddCtx);
8247
8248 if (0 != status)
8249 {
8250 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8251 "%s: HDD context is not valid", __func__);
8252 return status;
8253 }
8254
8255 /*Retrieve halHandle*/
8256 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
Agarwal Ashish3da95242014-05-21 14:57:17 +05308257 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Wilson Yang6507c4e2013-10-01 20:11:19 -07008258
8259 /*in case index is 0,no entry to delete*/
Agarwal Ashish3da95242014-05-21 14:57:17 +05308260 if (0 == pHddStaCtx->PMKIDCacheIndex)
Wilson Yang6507c4e2013-10-01 20:11:19 -07008261 {
Agarwal Ashish3da95242014-05-21 14:57:17 +05308262 hddLog(VOS_TRACE_LEVEL_INFO, FL("No entries to flush"));
8263 return 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -07008264 }
8265
8266 /*find the matching PMKSA entry from j=0 to (index-1),
8267 * and delete the matched one
8268 */
Agarwal Ashish3da95242014-05-21 14:57:17 +05308269 for (j = 0; j < pHddStaCtx->PMKIDCacheIndex; j++)
Wilson Yang6507c4e2013-10-01 20:11:19 -07008270 {
Agarwal Ashish3da95242014-05-21 14:57:17 +05308271 if (vos_mem_compare(pHddStaCtx->PMKIDCache[j].BSSID,
Wilson Yang6507c4e2013-10-01 20:11:19 -07008272 pmksa->bssid,
8273 WNI_CFG_BSSID_LEN))
8274 {
8275 /* BSSID matched entry */
8276 BSSIDMatched = 1;
Agarwal Ashish3da95242014-05-21 14:57:17 +05308277 if (j < pHddStaCtx->PMKIDCacheIndex-1)
Wilson Yang6507c4e2013-10-01 20:11:19 -07008278 {
8279 /*replace the matching entry with the last entry in HDD local cache*/
Agarwal Ashish3da95242014-05-21 14:57:17 +05308280 vos_mem_copy(pHddStaCtx->PMKIDCache[j].BSSID,
8281 pHddStaCtx->PMKIDCache[pHddStaCtx->PMKIDCacheIndex-1].BSSID,
8282 VOS_MAC_ADDR_SIZE);
8283 vos_mem_copy(pHddStaCtx->PMKIDCache[j].PMKID,
8284 pHddStaCtx->PMKIDCache[pHddStaCtx->PMKIDCacheIndex-1].PMKID,
8285 CSR_RSN_PMKID_SIZE);
8286 }
Wilson Yang6507c4e2013-10-01 20:11:19 -07008287
8288 /*clear the last entry in HDD cache ---[index-1]*/
Agarwal Ashish3da95242014-05-21 14:57:17 +05308289 vos_mem_zero(pHddStaCtx->PMKIDCache[pHddStaCtx->PMKIDCacheIndex-1].BSSID,
8290 VOS_MAC_ADDR_SIZE);
8291 vos_mem_zero(pHddStaCtx->PMKIDCache[pHddStaCtx->PMKIDCacheIndex-1].PMKID,
8292 CSR_RSN_PMKID_SIZE);
Wilson Yang6507c4e2013-10-01 20:11:19 -07008293 /*reduce the PMKID array index*/
Agarwal Ashish3da95242014-05-21 14:57:17 +05308294 pHddStaCtx->PMKIDCacheIndex--;
Wilson Yang6507c4e2013-10-01 20:11:19 -07008295 /*delete the last PMKID cache in CSR*/
Wilson Yangef657d32014-01-15 19:19:23 -08008296 if (eHAL_STATUS_SUCCESS !=
8297 sme_RoamDelPMKIDfromCache(halHandle, pAdapter->sessionId, pmksa->bssid))
Wilson Yang6507c4e2013-10-01 20:11:19 -07008298 {
8299 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: cannot delete PMKSA %d CONTENT.",
Agarwal Ashish3da95242014-05-21 14:57:17 +05308300 __func__, pHddStaCtx->PMKIDCacheIndex);
Wilson Yangef657d32014-01-15 19:19:23 -08008301 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -07008302 }
8303
8304 dump_bssid(pmksa->bssid);
8305 dump_pmkid(halHandle,pmksa->pmkid);
8306
8307 break;
8308 }
8309 }
8310
8311 /* we compare all entries,but cannot find matching entry */
8312 if (j == MAX_PMKSAIDS_IN_CACHE && !BSSIDMatched)
8313 {
Jeff Johnson0299d0a2013-10-30 12:37:43 -07008314 hddLog(VOS_TRACE_LEVEL_FATAL,
8315 "%s: No such PMKSA entry existed " MAC_ADDRESS_STR,
8316 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
Wilson Yang6507c4e2013-10-01 20:11:19 -07008317 dump_bssid(pmksa->bssid);
8318 dump_pmkid(halHandle, pmksa->pmkid);
8319 return -EINVAL;
8320 }
Wilson Yangef657d32014-01-15 19:19:23 -08008321 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008322}
8323
Wilson Yang6507c4e2013-10-01 20:11:19 -07008324
8325
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008326static int wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
8327{
Wilson Yang6507c4e2013-10-01 20:11:19 -07008328 tANI_U32 j=0;
8329 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Agarwal Ashish3da95242014-05-21 14:57:17 +05308330 hdd_station_ctx_t *pHddStaCtx;
Wilson Yang6507c4e2013-10-01 20:11:19 -07008331 tHalHandle halHandle;
8332 hdd_context_t *pHddCtx;
8333 tANI_U8 *pBSSId;
Wilson Yangef657d32014-01-15 19:19:23 -08008334 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -07008335
8336 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: flushing PMKSA ",__func__);
8337
8338 /* Validate pAdapter */
8339 if (NULL == pAdapter)
8340 {
8341 hddLog(VOS_TRACE_LEVEL_ERROR,
8342 "%s: Invalid Adapter" ,__func__);
8343 return -EINVAL;
8344 }
8345
8346 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8347 status = wlan_hdd_validate_context(pHddCtx);
8348
8349 if (0 != status)
8350 {
8351 hddLog(VOS_TRACE_LEVEL_ERROR,
8352 "%s: HDD context is not valid", __func__);
8353 return status;
8354 }
8355
8356 /*Retrieve halHandle*/
8357 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
Agarwal Ashish3da95242014-05-21 14:57:17 +05308358 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Wilson Yang6507c4e2013-10-01 20:11:19 -07008359
8360 /*in case index is 0,no entry to delete*/
Agarwal Ashish3da95242014-05-21 14:57:17 +05308361 if (0 == pHddStaCtx->PMKIDCacheIndex)
Wilson Yang6507c4e2013-10-01 20:11:19 -07008362 {
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +05308363 hddLog(VOS_TRACE_LEVEL_ERROR, FL("No entries to flush"));
Agarwal Ashish3da95242014-05-21 14:57:17 +05308364 return 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -07008365 }
8366
8367 /*delete all the PMKSA one by one */
Agarwal Ashish3da95242014-05-21 14:57:17 +05308368 for (j = 0; j < pHddStaCtx->PMKIDCacheIndex; j++)
Wilson Yang6507c4e2013-10-01 20:11:19 -07008369 {
Agarwal Ashish3da95242014-05-21 14:57:17 +05308370 pBSSId =(tANI_U8 *)(pHddStaCtx->PMKIDCache[j].BSSID);
Wilson Yang6507c4e2013-10-01 20:11:19 -07008371 /*delete the PMKID in CSR*/
Wilson Yangef657d32014-01-15 19:19:23 -08008372 if (eHAL_STATUS_SUCCESS !=
8373 sme_RoamDelPMKIDfromCache(halHandle, pAdapter->sessionId, pBSSId))
Wilson Yang6507c4e2013-10-01 20:11:19 -07008374 {
8375 hddLog(VOS_TRACE_LEVEL_ERROR ,"%s cannot flush PMKIDCache %d.",
8376 __func__,j);
Wilson Yangef657d32014-01-15 19:19:23 -08008377 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -07008378 }
Kiet Lam8d21d5b2013-10-31 17:18:29 +05308379 /*clear the entry in HDD cache 0--index-1 */
Agarwal Ashish3da95242014-05-21 14:57:17 +05308380 vos_mem_zero(pHddStaCtx->PMKIDCache[j].BSSID, VOS_MAC_ADDR_SIZE);
8381 vos_mem_zero(pHddStaCtx->PMKIDCache[j].PMKID, CSR_RSN_PMKID_SIZE);
8382 }
Wilson Yang6507c4e2013-10-01 20:11:19 -07008383
Agarwal Ashish3da95242014-05-21 14:57:17 +05308384 pHddStaCtx->PMKIDCacheIndex = 0;
Wilson Yangef657d32014-01-15 19:19:23 -08008385 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008386}
8387#endif
8388
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07008389#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308390static int wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07008391 struct net_device *dev, struct cfg80211_update_ft_ies_params *ftie)
8392{
8393 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
8394 hdd_station_ctx_t *pHddStaCtx;
8395
8396 if (NULL == pAdapter)
8397 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08008398 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07008399 return -ENODEV;
8400 }
8401
8402 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
8403
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308404 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
8405 TRACE_CODE_HDD_CFG80211_UPDATE_FT_IES,
8406 pAdapter->sessionId, pHddStaCtx->conn_info.connState));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07008407 // Added for debug on reception of Re-assoc Req.
8408 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
8409 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08008410 hddLog(LOGE, FL("Called with Ie of length = %zu when not associated"),
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07008411 ftie->ie_len);
Arif Hussain6d2a3322013-11-17 19:50:10 -08008412 hddLog(LOGE, FL("Should be Re-assoc Req IEs"));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07008413 }
8414
8415#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG
Arif Hussain6d2a3322013-11-17 19:50:10 -08008416 hddLog(LOGE, FL("%s called with Ie of length = %zu"), __func__,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07008417 ftie->ie_len);
8418#endif
8419
8420 // Pass the received FT IEs to SME
Gopichand Nakkala356fb102013-03-06 12:34:04 +05308421 sme_SetFTIEs( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
8422 (const u8 *)ftie->ie,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07008423 ftie->ie_len);
8424 return 0;
8425}
8426#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008427
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308428#ifdef FEATURE_WLAN_SCAN_PNO
8429
8430void hdd_cfg80211_sched_scan_done_callback(void *callbackContext,
8431 tSirPrefNetworkFoundInd *pPrefNetworkFoundInd)
8432{
8433 int ret;
8434 hdd_adapter_t* pAdapter = (hdd_adapter_t*)callbackContext;
8435 hdd_context_t *pHddCtx;
8436
Nirav Shah80830bf2013-12-31 16:35:12 +05308437 ENTER();
8438
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308439 if (NULL == pAdapter)
8440 {
Agarwal Ashish971c2882013-10-30 20:11:12 +05308441 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308442 "%s: HDD adapter is Null", __func__);
8443 return ;
8444 }
8445
8446 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8447 if (NULL == pHddCtx)
8448 {
8449 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8450 "%s: HDD context is Null!!!", __func__);
8451 return ;
8452 }
8453
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05308454 spin_lock(&pHddCtx->schedScan_lock);
8455 if (TRUE == pHddCtx->isWiphySuspended)
8456 {
8457 pHddCtx->isSchedScanUpdatePending = TRUE;
8458 spin_unlock(&pHddCtx->schedScan_lock);
8459 hddLog(VOS_TRACE_LEVEL_INFO,
8460 "%s: Update cfg80211 scan database after it resume", __func__);
8461 return ;
8462 }
8463 spin_unlock(&pHddCtx->schedScan_lock);
8464
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308465 ret = wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter);
8466
8467 if (0 > ret)
8468 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
8469
8470 cfg80211_sched_scan_results(pHddCtx->wiphy);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05308471 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8472 "%s: cfg80211 scan result database updated", __func__);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308473}
8474
8475/*
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +05308476 * FUNCTION: wlan_hdd_is_pno_allowed
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +05308477 * Disallow pno if any session is active
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +05308478 */
8479static eHalStatus wlan_hdd_is_pno_allowed(hdd_adapter_t *pAdapter)
8480{
8481 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
8482 hdd_adapter_t *pTempAdapter = NULL;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +05308483 hdd_station_ctx_t *pStaCtx;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +05308484 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8485 int status = 0;
8486 status = hdd_get_front_adapter(pHddCtx, &pAdapterNode);
8487
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +05308488 /* The current firmware design does not allow PNO during any
8489 * active sessions. Hence, determine the active sessions
8490 * and return a failure.
8491 */
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +05308492 while ((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status))
8493 {
8494 pTempAdapter = pAdapterNode->pAdapter;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +05308495 pStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pTempAdapter);
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +05308496
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +05308497 if (((WLAN_HDD_INFRA_STATION == pTempAdapter->device_mode)
8498 && (eConnectionState_NotConnected != pStaCtx->conn_info.connState))
8499 || (WLAN_HDD_P2P_CLIENT == pTempAdapter->device_mode)
8500 || (WLAN_HDD_P2P_GO == pTempAdapter->device_mode)
8501 || (WLAN_HDD_SOFTAP == pTempAdapter->device_mode)
8502 )
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +05308503 {
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +05308504 return eHAL_STATUS_FAILURE;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +05308505 }
8506 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
8507 pAdapterNode = pNext;
8508 }
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +05308509 return eHAL_STATUS_SUCCESS;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +05308510}
8511
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +05308512void hdd_cfg80211_sched_scan_start_status_cb(void *callbackContext, VOS_STATUS status)
8513{
8514 hdd_adapter_t *pAdapter = callbackContext;
8515 hdd_context_t *pHddCtx;
8516
8517 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
8518 {
8519 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8520 FL("Invalid adapter or adapter has invalid magic"));
8521 return;
8522 }
8523
8524 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8525 if (0 != wlan_hdd_validate_context(pHddCtx))
8526 {
8527 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8528 FL("HDD context is not valid"));
8529 return;
8530 }
8531
8532 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8533 FL("PNO enable response status = %d"), status);
8534
8535 pAdapter->pno_req_status = (status == VOS_STATUS_SUCCESS) ? 0 : -EBUSY;
8536 complete(&pAdapter->pno_comp_var);
8537}
8538
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +05308539/*
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308540 * FUNCTION: wlan_hdd_cfg80211_sched_scan_start
8541 * NL interface to enable PNO
8542 */
8543static int wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
8544 struct net_device *dev, struct cfg80211_sched_scan_request *request)
8545{
8546 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
8547 tpSirPNOScanReq pPnoRequest = NULL;
8548 hdd_context_t *pHddCtx;
8549 tHalHandle hHal;
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +05308550 v_U32_t i, indx, num_ch, tempInterval;
Sushant Kaushikd62d9782014-02-19 15:39:40 +05308551 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
8552 u8 channels_allowed[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308553 v_U32_t num_channels_allowed = WNI_CFG_VALID_CHANNEL_LIST_LEN;
8554 eHalStatus status = eHAL_STATUS_FAILURE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308555 int ret = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308556
8557 if (NULL == pAdapter)
8558 {
8559 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
8560 "%s: HDD adapter is Null", __func__);
8561 return -ENODEV;
8562 }
8563
8564 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05308565 ret = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308566
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05308567 if (0 != ret)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308568 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05308569 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8570 "%s: HDD context is not valid", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308571 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308572 }
8573
8574 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
8575 if (NULL == hHal)
8576 {
8577 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8578 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05308579 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308580 }
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +05308581
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +05308582 if (eHAL_STATUS_SUCCESS != wlan_hdd_is_pno_allowed(pAdapter))
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +05308583 {
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +05308584 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +05308585 FL("Cannot handle sched_scan"));
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +05308586 return -EBUSY;
8587 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308588
c_hpothu37f21312014-04-09 21:49:54 +05308589 if (TRUE == pHddCtx->isPnoEnable)
8590 {
8591 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
8592 FL("already PNO is enabled"));
8593 return -EBUSY;
8594 }
8595 pHddCtx->isPnoEnable = TRUE;
8596
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308597 pPnoRequest = (tpSirPNOScanReq) vos_mem_malloc(sizeof (tSirPNOScanReq));
8598 if (NULL == pPnoRequest)
8599 {
8600 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
8601 "%s: vos_mem_malloc failed", __func__);
c_hpothu37f21312014-04-09 21:49:54 +05308602 pHddCtx->isPnoEnable = FALSE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308603 return -ENOMEM;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308604 }
8605
Madan Mohan Koyyalamudic3f04352013-09-26 19:21:48 +05308606 memset(pPnoRequest, 0, sizeof (tSirPNOScanReq));
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308607 pPnoRequest->enable = 1; /*Enable PNO */
8608 pPnoRequest->ucNetworksCount = request->n_match_sets;
8609
8610 if (( !pPnoRequest->ucNetworksCount ) ||
8611 ( pPnoRequest->ucNetworksCount > SIR_PNO_MAX_SUPP_NETWORKS ))
8612 {
8613 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik1e406c32014-05-09 15:57:52 +05308614 "%s: Network input is not correct %d Max Network supported is %d",
8615 __func__, pPnoRequest->ucNetworksCount,
8616 SIR_PNO_MAX_SUPP_NETWORKS);
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308617 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308618 goto error;
8619 }
8620
8621 if ( SIR_PNO_MAX_NETW_CHANNELS_EX < request->n_channels )
8622 {
8623 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +05308624 "%s: Incorrect number of channels %d",
8625 __func__, request->n_channels);
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308626 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308627 goto error;
8628 }
8629
8630 /* Framework provides one set of channels(all)
8631 * common for all saved profile */
8632 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
8633 channels_allowed, &num_channels_allowed))
8634 {
8635 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8636 "%s: failed to get valid channel list", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308637 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308638 goto error;
8639 }
8640 /* Checking each channel against allowed channel list */
8641 num_ch = 0;
Nirav Shah80830bf2013-12-31 16:35:12 +05308642 if (request->n_channels)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308643 {
Nirav Shah80830bf2013-12-31 16:35:12 +05308644 char chList [(request->n_channels*5)+1];
8645 int len;
8646 for (i = 0, len = 0; i < request->n_channels; i++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308647 {
Nirav Shah80830bf2013-12-31 16:35:12 +05308648 for (indx = 0; indx < num_channels_allowed; indx++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308649 {
Nirav Shah80830bf2013-12-31 16:35:12 +05308650 if (request->channels[i]->hw_value == channels_allowed[indx])
8651 {
8652 valid_ch[num_ch++] = request->channels[i]->hw_value;
8653 len += snprintf(chList+len, 5, "%d ",
8654 request->channels[i]->hw_value);
8655 break ;
8656 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308657 }
8658 }
Nirav Shah80830bf2013-12-31 16:35:12 +05308659 hddLog(VOS_TRACE_LEVEL_INFO,"Channel-List: %s ", chList);
8660 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308661
8662 /* Filling per profile params */
8663 for (i = 0; i < pPnoRequest->ucNetworksCount; i++)
8664 {
8665 pPnoRequest->aNetworks[i].ssId.length =
8666 request->match_sets[i].ssid.ssid_len;
8667
8668 if (( 0 == pPnoRequest->aNetworks[i].ssId.length ) ||
8669 ( pPnoRequest->aNetworks[i].ssId.length > 32 ) )
8670 {
8671 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +05308672 "%s: SSID Len %d is not correct for network %d",
8673 __func__, pPnoRequest->aNetworks[i].ssId.length, i);
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308674 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308675 goto error;
8676 }
8677
8678 memcpy(pPnoRequest->aNetworks[i].ssId.ssId,
8679 request->match_sets[i].ssid.ssid,
8680 request->match_sets[i].ssid.ssid_len);
Sushant Kaushik1e406c32014-05-09 15:57:52 +05308681 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8682 "%s: SSID of network %d is %s ", __func__,
8683 i, pPnoRequest->aNetworks[i].ssId.ssId);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308684 pPnoRequest->aNetworks[i].authentication = 0; /*eAUTH_TYPE_ANY*/
8685 pPnoRequest->aNetworks[i].encryption = 0; /*eED_ANY*/
8686 pPnoRequest->aNetworks[i].bcastNetwType = 0; /*eBCAST_UNKNOWN*/
8687
8688 /*Copying list of valid channel into request */
8689 memcpy(pPnoRequest->aNetworks[i].aChannels, valid_ch, num_ch);
8690 pPnoRequest->aNetworks[i].ucChannelCount = num_ch;
8691
8692 pPnoRequest->aNetworks[i].rssiThreshold = 0; //Default value
8693 }
8694
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +05308695 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnson59a121e2013-11-30 09:46:08 -08008696 "request->ie_len = %zu", request->ie_len);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +05308697 if ((0 < request->ie_len) && (NULL != request->ie))
8698 {
8699 pPnoRequest->us24GProbeTemplateLen = request->ie_len;
8700 memcpy(&pPnoRequest->p24GProbeTemplate, request->ie,
8701 pPnoRequest->us24GProbeTemplateLen);
8702
8703 pPnoRequest->us5GProbeTemplateLen = request->ie_len;
8704 memcpy(&pPnoRequest->p5GProbeTemplate, request->ie,
8705 pPnoRequest->us5GProbeTemplateLen);
8706 }
8707
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +05308708 /* Driver gets only one time interval which is hardcoded in
8709 * supplicant for 10000ms. Taking power consumption into account 6 timers
8710 * will be used, Timervalue is increased exponentially i.e 10,20,40,
8711 * 80,160,320 secs. And number of scan cycle for each timer
8712 * is configurable through INI param gPNOScanTimerRepeatValue.
8713 * If it is set to 0 only one timer will be used and PNO scan cycle
8714 * will be repeated after each interval specified by supplicant
8715 * till PNO is disabled.
8716 */
8717 if (0 == pHddCtx->cfg_ini->configPNOScanTimerRepeatValue)
8718 pPnoRequest->scanTimers.ucScanTimersCount = HDD_PNO_SCAN_TIMERS_SET_ONE;
8719 else
8720 pPnoRequest->scanTimers.ucScanTimersCount =
8721 HDD_PNO_SCAN_TIMERS_SET_MULTIPLE;
8722
8723 tempInterval = (request->interval)/1000;
8724 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8725 "Base scan interval = %d PNOScanTimerRepeatValue = %d",
8726 tempInterval, pHddCtx->cfg_ini->configPNOScanTimerRepeatValue);
8727 for ( i = 0; i < pPnoRequest->scanTimers.ucScanTimersCount; i++)
8728 {
8729 pPnoRequest->scanTimers.aTimerValues[i].uTimerRepeat =
8730 pHddCtx->cfg_ini->configPNOScanTimerRepeatValue;
8731 pPnoRequest->scanTimers.aTimerValues[i].uTimerValue = tempInterval;
8732 tempInterval *= 2;
8733 }
8734 //Repeat last timer until pno disabled.
8735 pPnoRequest->scanTimers.aTimerValues[i-1].uTimerRepeat = 0;
8736
Madan Mohan Koyyalamudid206c7b2013-09-26 22:54:51 +05308737 pPnoRequest->modePNO = SIR_PNO_MODE_IMMEDIATE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308738
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +05308739 INIT_COMPLETION(pAdapter->pno_comp_var);
8740 pPnoRequest->statusCallback = hdd_cfg80211_sched_scan_start_status_cb;
8741 pPnoRequest->callbackContext = pAdapter;
8742 pAdapter->pno_req_status = 0;
8743
Nirav Shah80830bf2013-12-31 16:35:12 +05308744 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8745 "SessionId %d, enable %d, modePNO %d, ucScanTimersCount %d",
8746 pAdapter->sessionId, pPnoRequest->enable, pPnoRequest->modePNO,
8747 pPnoRequest->scanTimers.ucScanTimersCount);
8748
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308749 status = sme_SetPreferredNetworkList(WLAN_HDD_GET_HAL_CTX(pAdapter),
8750 pPnoRequest, pAdapter->sessionId,
8751 hdd_cfg80211_sched_scan_done_callback, pAdapter);
8752 if (eHAL_STATUS_SUCCESS != status)
8753 {
8754 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +05308755 "%s: Failed to enable PNO", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308756 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308757 goto error;
8758 }
8759
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +05308760 ret = wait_for_completion_timeout(
8761 &pAdapter->pno_comp_var,
8762 msecs_to_jiffies(WLAN_WAIT_TIME_PNO));
8763 if (0 >= ret)
8764 {
8765 // Did not receive the response for PNO enable in time.
8766 // Assuming the PNO enable was success.
8767 // Returning error from here, because we timeout, results
8768 // in side effect of Wifi (Wifi Setting) not to work.
8769 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8770 FL("Timed out waiting for PNO to be Enabled"));
8771 ret = 0;
8772 goto error;
8773 }
8774
8775 ret = pAdapter->pno_req_status;
c_hpothu37f21312014-04-09 21:49:54 +05308776 return ret;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05308777
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308778error:
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +05308779 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8780 FL("PNO scanRequest offloaded ret = %d"), ret);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308781 vos_mem_free(pPnoRequest);
c_hpothu37f21312014-04-09 21:49:54 +05308782 pHddCtx->isPnoEnable = FALSE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308783 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308784}
8785
8786/*
8787 * FUNCTION: wlan_hdd_cfg80211_sched_scan_stop
8788 * NL interface to disable PNO
8789 */
8790static int wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
8791 struct net_device *dev)
8792{
8793 eHalStatus status = eHAL_STATUS_FAILURE;
8794 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
8795 hdd_context_t *pHddCtx;
8796 tHalHandle hHal;
8797 tpSirPNOScanReq pPnoRequest = NULL;
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308798 int ret = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308799
8800 ENTER();
8801
8802 if (NULL == pAdapter)
8803 {
8804 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
8805 "%s: HDD adapter is Null", __func__);
8806 return -ENODEV;
8807 }
8808
8809 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308810
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308811 if (NULL == pHddCtx)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308812 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05308813 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308814 "%s: HDD context is Null", __func__);
8815 return -ENODEV;
8816 }
8817
8818 /* The return 0 is intentional when isLogpInProgress and
8819 * isLoadUnloadInProgress. We did observe a crash due to a return of
8820 * failure in sched_scan_stop , especially for a case where the unload
8821 * of the happens at the same time. The function __cfg80211_stop_sched_scan
8822 * was clearing rdev->sched_scan_req only when the sched_scan_stop returns
8823 * success. If it returns a failure , then its next invocation due to the
8824 * clean up of the second interface will have the dev pointer corresponding
8825 * to the first one leading to a crash.
8826 */
8827 if (pHddCtx->isLogpInProgress)
8828 {
8829 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8830 "%s: LOGP in Progress. Ignore!!!", __func__);
8831 return ret;
8832 }
8833
Mihir Shete18156292014-03-11 15:38:30 +05308834 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308835 {
8836 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8837 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
8838 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308839 }
8840
8841 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
8842 if (NULL == hHal)
8843 {
8844 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8845 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05308846 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308847 }
8848
8849 pPnoRequest = (tpSirPNOScanReq) vos_mem_malloc(sizeof (tSirPNOScanReq));
8850 if (NULL == pPnoRequest)
8851 {
8852 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
8853 "%s: vos_mem_malloc failed", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308854 return -ENOMEM;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308855 }
8856
8857 memset(pPnoRequest, 0, sizeof (tSirPNOScanReq));
8858 pPnoRequest->enable = 0; /* Disable PNO */
8859 pPnoRequest->ucNetworksCount = 0;
8860
8861 status = sme_SetPreferredNetworkList(hHal, pPnoRequest,
8862 pAdapter->sessionId,
8863 NULL, pAdapter);
8864 if (eHAL_STATUS_SUCCESS != status)
8865 {
8866 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8867 "Failed to disabled PNO");
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308868 ret = -EINVAL;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +05308869 goto error;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308870 }
c_hpothu37f21312014-04-09 21:49:54 +05308871 pHddCtx->isPnoEnable = FALSE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308872
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +05308873error:
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05308874 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +05308875 FL("PNO scan disabled ret = %d"), ret);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308876 vos_mem_free(pPnoRequest);
8877
8878 EXIT();
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308879 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308880}
8881
8882#endif /*FEATURE_WLAN_SCAN_PNO*/
8883
8884
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008885#ifdef FEATURE_WLAN_TDLS
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +05308886#if TDLS_MGMT_VERSION2
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008887static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
8888 u8 *peer, u8 action_code, u8 dialog_token,
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +05308889 u16 status_code, u32 peer_capability, const u8 *buf, size_t len)
8890#else
8891static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
8892 u8 *peer, u8 action_code, u8 dialog_token,
8893 u16 status_code, const u8 *buf, size_t len)
8894#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008895{
8896
8897 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
8898 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008899 u8 peerMac[6];
8900 VOS_STATUS status;
Gopichand Nakkala05922802013-03-14 12:23:19 -07008901 int max_sta_failed = 0;
Hoonki Leea34dd892013-02-05 22:56:02 -08008902 int responder;
Hoonki Leed37cbb32013-04-20 00:31:14 -07008903 long rc;
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +05308904#if !(TDLS_MGMT_VERSION2)
8905 u32 peer_capability = 0;
8906#endif
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05308907 tANI_U16 numCurrTdlsPeers;
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008908
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308909 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
8910 TRACE_CODE_HDD_CFG80211_TDLS_MGMT,
8911 pAdapter->sessionId, action_code));
Hoonki Lee11f7dda2013-02-14 16:55:44 -08008912 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008913 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308914 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008915 "Invalid arguments");
8916 return -EINVAL;
8917 }
8918
Sameer Thalappil75ea31a2013-02-21 19:38:16 -08008919 if (pHddCtx->isLogpInProgress)
8920 {
8921 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8922 "%s:LOGP in Progress. Ignore!!!", __func__);
Gopichand Nakkala05922802013-03-14 12:23:19 -07008923 wlan_hdd_tdls_set_link_status(pAdapter, peer, eTDLS_LINK_IDLE);
Sameer Thalappil75ea31a2013-02-21 19:38:16 -08008924 return -EBUSY;
8925 }
8926
Hoonki Lee27511902013-03-14 18:19:06 -07008927 if (eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode)
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008928 {
Hoonki Lee27511902013-03-14 18:19:06 -07008929 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
8930 "%s: TDLS mode is disabled OR not enabled in FW."
8931 MAC_ADDRESS_STR " action %d declined.",
8932 __func__, MAC_ADDR_ARRAY(peer), action_code);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008933 return -ENOTSUPP;
8934 }
Lee Hoonkic1262f22013-01-24 21:59:00 -08008935
Hoonki Lee27511902013-03-14 18:19:06 -07008936 /* other than teardown frame, other mgmt frames are not sent if disabled */
8937 if (SIR_MAC_TDLS_TEARDOWN != action_code)
8938 {
8939 /* if tdls_mode is disabled to respond to peer's request */
8940 if (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode)
8941 {
8942 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
8943 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07008944 " TDLS mode is disabled. action %d declined.",
8945 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee27511902013-03-14 18:19:06 -07008946
8947 return -ENOTSUPP;
8948 }
8949 }
8950
Gopichand Nakkalab977a972013-02-18 19:15:09 -08008951 if (WLAN_IS_TDLS_SETUP_ACTION(action_code))
8952 {
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308953 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, peer, TRUE))
Gopichand Nakkalab977a972013-02-18 19:15:09 -08008954 {
8955 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07008956 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07008957 " TDLS setup is ongoing. action %d declined.",
8958 __func__, MAC_ADDR_ARRAY(peer), action_code);
8959 return -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -08008960 }
8961 }
8962
Hoonki Lee11f7dda2013-02-14 16:55:44 -08008963 if (SIR_MAC_TDLS_SETUP_REQ == action_code ||
8964 SIR_MAC_TDLS_SETUP_RSP == action_code )
Lee Hoonkic1262f22013-01-24 21:59:00 -08008965 {
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05308966 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
8967 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Lee Hoonkic1262f22013-01-24 21:59:00 -08008968 {
8969 /* supplicant still sends tdls_mgmt(SETUP_REQ) even after
8970 we return error code at 'add_station()'. Hence we have this
8971 check again in addtion to add_station().
8972 Anyway, there is no hard to double-check. */
Hoonki Lee11f7dda2013-02-14 16:55:44 -08008973 if (SIR_MAC_TDLS_SETUP_REQ == action_code)
Lee Hoonkic1262f22013-01-24 21:59:00 -08008974 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07008975 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8976 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05308977 " TDLS Max peer already connected. action (%d) declined. Num of peers (%d), Max allowed (%d).",
8978 __func__, MAC_ADDR_ARRAY(peer), action_code,
8979 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Sunil Dutt388ac8f2013-11-28 18:06:52 +05308980 return -EINVAL;
Lee Hoonkic1262f22013-01-24 21:59:00 -08008981 }
8982 else
8983 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -08008984 /* maximum reached. tweak to send error code to peer and return
8985 error code to supplicant */
Lee Hoonkic1262f22013-01-24 21:59:00 -08008986 status_code = eSIR_MAC_UNSPEC_FAILURE_STATUS;
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07008987 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8988 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05308989 " TDLS Max peer already connected, send response status (%d). Num of peers (%d), Max allowed (%d).",
8990 __func__, MAC_ADDR_ARRAY(peer), status_code,
8991 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -07008992 max_sta_failed = -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -08008993 /* fall through to send setup resp with failure status
8994 code */
Lee Hoonkic1262f22013-01-24 21:59:00 -08008995 }
8996 }
Hoonki Lee11f7dda2013-02-14 16:55:44 -08008997 else
8998 {
8999 hddTdlsPeer_t *pTdlsPeer;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05309000 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009001 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Hoonki Lee11f7dda2013-02-14 16:55:44 -08009002 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07009003 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07009004 "%s:" MAC_ADDRESS_STR " already connected. action %d declined.",
9005 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee11f7dda2013-02-14 16:55:44 -08009006 return -EPERM;
9007 }
9008 }
Lee Hoonkic1262f22013-01-24 21:59:00 -08009009 }
Hoonki Lee11f7dda2013-02-14 16:55:44 -08009010 vos_mem_copy(peerMac, peer, 6);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009011
Hoonki Lee1090c6a2013-01-16 17:40:54 -08009012#ifdef WLAN_FEATURE_TDLS_DEBUG
9013 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +05309014 "%s: " MAC_ADDRESS_STR " action %d, dialog_token %d status %d, len = %zu",
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07009015 "tdls_mgmt", MAC_ADDR_ARRAY(peer),
9016 action_code, dialog_token, status_code, len);
Hoonki Lee1090c6a2013-01-16 17:40:54 -08009017#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009018
Hoonki Leea34dd892013-02-05 22:56:02 -08009019 /*Except teardown responder will not be used so just make 0*/
9020 responder = 0;
Hoonki Lee11f7dda2013-02-14 16:55:44 -08009021 if (SIR_MAC_TDLS_TEARDOWN == action_code)
Hoonki Leea34dd892013-02-05 22:56:02 -08009022 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -07009023
9024 hddTdlsPeer_t *pTdlsPeer;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05309025 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peerMac, TRUE);
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -07009026
9027 if(pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
9028 responder = pTdlsPeer->is_responder;
9029 else
Hoonki Leea34dd892013-02-05 22:56:02 -08009030 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -07009031 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +05309032 "%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 -07009033 __func__, MAC_ADDR_ARRAY(peer), (NULL == pTdlsPeer) ? -1 : pTdlsPeer->link_status,
9034 dialog_token, status_code, len);
9035 return -EPERM;
Hoonki Leea34dd892013-02-05 22:56:02 -08009036 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009037 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009038
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +05309039 /* For explicit trigger of DIS_REQ come out of BMPS for
9040 successfully receiving DIS_RSP from peer. */
Hoonki Lee14621352013-04-16 17:51:19 -07009041 if ((SIR_MAC_TDLS_SETUP_RSP == action_code) ||
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +05309042 (SIR_MAC_TDLS_DIS_RSP == action_code) ||
9043 (SIR_MAC_TDLS_DIS_REQ == action_code))
Hoonki Lee14621352013-04-16 17:51:19 -07009044 {
9045 if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter)))
9046 {
9047 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +05309048 "%s: Sending frame action_code %u.Disable BMPS", __func__, action_code);
Hoonki Lee14621352013-04-16 17:51:19 -07009049 hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
9050 }
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +05309051 if (SIR_MAC_TDLS_DIS_REQ != action_code)
9052 wlan_hdd_tdls_set_cap(pAdapter, peerMac, eTDLS_CAP_SUPPORTED);
Hoonki Lee14621352013-04-16 17:51:19 -07009053 }
9054
Hoonki Lee5305c3a2013-04-29 23:28:59 -07009055 /* make sure doesn't call send_mgmt() while it is pending */
9056 if (TDLS_CTX_MAGIC == pAdapter->mgmtTxCompletionStatus)
9057 {
9058 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009059 "%s: " MAC_ADDRESS_STR " action %d couldn't sent, as one is pending. return EBUSY",
Hoonki Lee5305c3a2013-04-29 23:28:59 -07009060 __func__, MAC_ADDR_ARRAY(peer), action_code);
9061 return -EBUSY;
9062 }
9063
9064 pAdapter->mgmtTxCompletionStatus = TDLS_CTX_MAGIC;
Gopichand Nakkalab977a972013-02-18 19:15:09 -08009065 INIT_COMPLETION(pAdapter->tdls_mgmt_comp);
9066
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009067 status = sme_SendTdlsMgmtFrame(WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
Pradeep Reddy POTTETIca171f82014-03-21 14:17:35 +05309068 peerMac, action_code, dialog_token, status_code, peer_capability, (tANI_U8 *)buf, len, responder);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009069
Gopichand Nakkalab977a972013-02-18 19:15:09 -08009070 if (VOS_STATUS_SUCCESS != status)
9071 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009072 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9073 "%s: sme_SendTdlsMgmtFrame failed!", __func__);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07009074 pAdapter->mgmtTxCompletionStatus = FALSE;
Hoonki Lee14621352013-04-16 17:51:19 -07009075 wlan_hdd_tdls_check_bmps(pAdapter);
Sunil Dutt388ac8f2013-11-28 18:06:52 +05309076 return -EINVAL;
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009077 }
9078
Hoonki Leed37cbb32013-04-20 00:31:14 -07009079 rc = wait_for_completion_interruptible_timeout(&pAdapter->tdls_mgmt_comp,
9080 msecs_to_jiffies(WAIT_TIME_TDLS_MGMT));
9081
9082 if ((rc <= 0) || (TRUE != pAdapter->mgmtTxCompletionStatus))
Gopichand Nakkalab977a972013-02-18 19:15:09 -08009083 {
Hoonki Leed37cbb32013-04-20 00:31:14 -07009084 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07009085 "%s: Mgmt Tx Completion failed status %ld TxCompletion %u",
Hoonki Leed37cbb32013-04-20 00:31:14 -07009086 __func__, rc, pAdapter->mgmtTxCompletionStatus);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07009087 pAdapter->mgmtTxCompletionStatus = FALSE;
Yue Ma4f55ef32014-01-23 16:45:33 -08009088
9089 if (pHddCtx->isLogpInProgress)
9090 {
9091 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9092 "%s: LOGP in Progress. Ignore!!!", __func__);
9093 return -EAGAIN;
9094 }
9095
Hoonki Leed37cbb32013-04-20 00:31:14 -07009096 wlan_hdd_tdls_check_bmps(pAdapter);
Sunil Dutt388ac8f2013-11-28 18:06:52 +05309097 return -EINVAL;
Gopichand Nakkalab977a972013-02-18 19:15:09 -08009098 }
9099
Gopichand Nakkala05922802013-03-14 12:23:19 -07009100 if (max_sta_failed)
Hoonki Lee14621352013-04-16 17:51:19 -07009101 {
9102 wlan_hdd_tdls_check_bmps(pAdapter);
Gopichand Nakkala05922802013-03-14 12:23:19 -07009103 return max_sta_failed;
Hoonki Lee14621352013-04-16 17:51:19 -07009104 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -08009105
Hoonki Leea34dd892013-02-05 22:56:02 -08009106 if (SIR_MAC_TDLS_SETUP_RSP == action_code)
9107 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -08009108 wlan_hdd_tdls_set_responder(pAdapter, peerMac, TRUE);
Hoonki Leea34dd892013-02-05 22:56:02 -08009109 }
9110 else if (SIR_MAC_TDLS_SETUP_CNF == action_code)
9111 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -08009112 wlan_hdd_tdls_set_responder(pAdapter, peerMac, FALSE);
Hoonki Leea34dd892013-02-05 22:56:02 -08009113 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009114
9115 return 0;
9116}
9117
9118static int wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
9119 u8 *peer, enum nl80211_tdls_operation oper)
9120{
9121 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
9122 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309123 int status;
Hoonki Lee5305c3a2013-04-29 23:28:59 -07009124 hddTdlsPeer_t *pTdlsPeer;
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009125
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309126 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
9127 TRACE_CODE_HDD_CFG80211_TDLS_OPER,
9128 pAdapter->sessionId, oper));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309129 if ( NULL == peer )
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009130 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -08009131 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chilam Ngc4244af2013-04-01 15:37:32 -07009132 "%s: Invalid arguments", __func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009133 return -EINVAL;
9134 }
Hoonki Lee1090c6a2013-01-16 17:40:54 -08009135
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309136 status = wlan_hdd_validate_context(pHddCtx);
9137
9138 if (0 != status)
Sameer Thalappil75ea31a2013-02-21 19:38:16 -08009139 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309140 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9141 "%s: HDD context is not valid", __func__);
9142 return status;
Sameer Thalappil75ea31a2013-02-21 19:38:16 -08009143 }
9144
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009145
9146 if( FALSE == pHddCtx->cfg_ini->fEnableTDLSSupport ||
Hoonki Lee1090c6a2013-01-16 17:40:54 -08009147 FALSE == sme_IsFeatureSupportedByFW(TDLS))
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009148 {
Hoonki Lee1090c6a2013-01-16 17:40:54 -08009149 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chilam Ngc4244af2013-04-01 15:37:32 -07009150 "TDLS Disabled in INI OR not enabled in FW. "
9151 "Cannot process TDLS commands");
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009152 return -ENOTSUPP;
9153 }
9154
9155 switch (oper) {
9156 case NL80211_TDLS_ENABLE_LINK:
9157 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009158 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309159 long ret;
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05309160 tCsrTdlsLinkEstablishParams tdlsLinkEstablishParams;
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009161
Sunil Dutt41de4e22013-11-14 18:09:02 +05309162 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
9163
9164 if ( NULL == pTdlsPeer ) {
9165 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
9166 " (oper %d) not exsting. ignored",
9167 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
9168 return -EINVAL;
9169 }
9170
9171 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9172 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
9173 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
9174 "NL80211_TDLS_ENABLE_LINK");
9175
Gopichand Nakkala2f4a2822013-04-17 11:22:01 -07009176 if (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
9177 {
9178 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Staion Index %u "
9179 MAC_ADDRESS_STR " failed",
9180 __func__, pTdlsPeer->staId, MAC_ADDR_ARRAY(peer));
9181 return -EINVAL;
9182 }
9183
Hoonki Lee5305c3a2013-04-29 23:28:59 -07009184 if (eTDLS_LINK_CONNECTED != pTdlsPeer->link_status)
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07009185 {
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +05309186 if (IS_ADVANCE_TDLS_ENABLE) {
Gopichand Nakkala24be5312013-07-02 16:47:12 +05309187
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +05309188 if (0 != wlan_hdd_tdls_get_link_establish_params(
9189 pAdapter, peer,&tdlsLinkEstablishParams)) {
9190 return -EINVAL;
9191 }
9192 INIT_COMPLETION(pAdapter->tdls_link_establish_req_comp);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05309193
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +05309194 sme_SendTdlsLinkEstablishParams(WLAN_HDD_GET_HAL_CTX(pAdapter),
9195 pAdapter->sessionId, peer, &tdlsLinkEstablishParams);
9196 /* Send TDLS peer UAPSD capabilities to the firmware and
9197 * register with the TL on after the response for this operation
9198 * is received .
9199 */
9200 ret = wait_for_completion_interruptible_timeout(
9201 &pAdapter->tdls_link_establish_req_comp,
9202 msecs_to_jiffies(WAIT_TIME_TDLS_LINK_ESTABLISH_REQ));
9203 if (ret <= 0)
9204 {
9205 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9206 "%s: Link Establish Request Faled Status %ld",
9207 __func__, ret);
9208 return -EINVAL;
9209 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05309210 }
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -07009211 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer, eTDLS_LINK_CONNECTED);
Gopichand Nakkala471708b2013-06-04 20:03:01 +05309212 /* Mark TDLS client Authenticated .*/
9213 status = WLANTL_ChangeSTAState( pHddCtx->pvosContext,
9214 pTdlsPeer->staId,
9215 WLANTL_STA_AUTHENTICATED);
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -07009216 if (VOS_STATUS_SUCCESS == status)
9217 {
Hoonki Lee14621352013-04-16 17:51:19 -07009218 if (pTdlsPeer->is_responder == 0)
9219 {
9220 v_U8_t staId = (v_U8_t)pTdlsPeer->staId;
9221
9222 wlan_hdd_tdls_timer_restart(pAdapter,
9223 &pTdlsPeer->initiatorWaitTimeoutTimer,
9224 WAIT_TIME_TDLS_INITIATOR);
9225 /* suspend initiator TX until it receives direct packet from the
9226 reponder or WAIT_TIME_TDLS_INITIATOR timer expires */
9227 WLANTL_SuspendDataTx( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
9228 &staId, NULL);
9229 }
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -07009230 wlan_hdd_tdls_increment_peer_count(pAdapter);
9231 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07009232 wlan_hdd_tdls_check_bmps(pAdapter);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05309233
9234 /* Update TL about the UAPSD masks , to route the packets to firmware */
Gopichand Nakkala574f6d12013-06-27 19:38:43 +05309235 if ((TRUE == pHddCtx->cfg_ini->fEnableTDLSBufferSta)
9236 || pHddCtx->cfg_ini->fTDLSUapsdMask )
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05309237 {
Gopichand Nakkala574f6d12013-06-27 19:38:43 +05309238 int ac;
9239 uint8 ucAc[4] = { WLANTL_AC_VO,
9240 WLANTL_AC_VI,
9241 WLANTL_AC_BK,
9242 WLANTL_AC_BE };
9243 uint8 tlTid[4] = { 7, 5, 2, 3 } ;
9244 for(ac=0; ac < 4; ac++)
9245 {
9246 status = WLANTL_EnableUAPSDForAC( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
9247 pTdlsPeer->staId, ucAc[ac],
9248 tlTid[ac], tlTid[ac], 0, 0,
9249 WLANTL_BI_DIR );
9250 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05309251 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07009252 }
9253
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009254 }
9255 break;
9256 case NL80211_TDLS_DISABLE_LINK:
Lee Hoonkic1262f22013-01-24 21:59:00 -08009257 {
Sunil Dutt41de4e22013-11-14 18:09:02 +05309258 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
9259
9260 if ( NULL == pTdlsPeer ) {
9261 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
9262 " (oper %d) not exsting. ignored",
9263 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
9264 return -EINVAL;
9265 }
9266
9267 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9268 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
9269 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
9270 "NL80211_TDLS_DISABLE_LINK");
9271
Hoonki Lee5305c3a2013-04-29 23:28:59 -07009272 if(TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
Lee Hoonkic1262f22013-01-24 21:59:00 -08009273 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009274 long status;
9275
9276 INIT_COMPLETION(pAdapter->tdls_del_station_comp);
9277
Lee Hoonkic1262f22013-01-24 21:59:00 -08009278 sme_DeleteTdlsPeerSta( WLAN_HDD_GET_HAL_CTX(pAdapter),
9279 pAdapter->sessionId, peer );
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009280
9281 status = wait_for_completion_interruptible_timeout(&pAdapter->tdls_del_station_comp,
9282 msecs_to_jiffies(WAIT_TIME_TDLS_DEL_STA));
9283 if (status <= 0)
9284 {
Hoonki Lee5305c3a2013-04-29 23:28:59 -07009285 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer, eTDLS_LINK_IDLE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009286 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9287 "%s: Del station failed status %ld",
9288 __func__, status);
9289 return -EPERM;
9290 }
Hoonki Lee5305c3a2013-04-29 23:28:59 -07009291 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer, eTDLS_LINK_IDLE);
Lee Hoonkic1262f22013-01-24 21:59:00 -08009292 }
9293 else
9294 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07009295 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9296 "%s: TDLS Peer Station doesn't exist.", __func__);
Lee Hoonkic1262f22013-01-24 21:59:00 -08009297 }
Lee Hoonkic1262f22013-01-24 21:59:00 -08009298 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07009299 break;
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009300 case NL80211_TDLS_TEARDOWN:
Sunil Dutt41de4e22013-11-14 18:09:02 +05309301 {
9302 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9303 " %s : NL80211_TDLS_TEARDOWN for " MAC_ADDRESS_STR,
9304 __func__, MAC_ADDR_ARRAY(peer));
9305
9306 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
9307 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
9308
9309 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9310 " %s TDLS External control and Implicit Trigger not enabled ",
9311 __func__);
9312 return -ENOTSUPP;
9313 }
9314
Sunil Dutt41de4e22013-11-14 18:09:02 +05309315
9316 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
9317
9318 if ( NULL == pTdlsPeer ) {
9319 hddLog(VOS_TRACE_LEVEL_INFO, "%s: " MAC_ADDRESS_STR
9320 " peer not exsting",
9321 __func__, MAC_ADDR_ARRAY(peer));
Naresh Jayaram937abdf2013-11-26 19:50:25 +05309322 return -EINVAL;
Sunil Dutt41de4e22013-11-14 18:09:02 +05309323 }
9324 else {
9325 wlan_hdd_tdls_indicate_teardown(pAdapter, pTdlsPeer,
9326 eSIR_MAC_TDLS_TEARDOWN_UNSPEC_REASON);
9327 }
Naresh Jayaram937abdf2013-11-26 19:50:25 +05309328
9329 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, FALSE) )
9330 return -EINVAL;
Sunil Dutt41de4e22013-11-14 18:09:02 +05309331 break;
9332 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009333 case NL80211_TDLS_SETUP:
Sunil Dutt41de4e22013-11-14 18:09:02 +05309334 {
Naresh Jayaramdb4514b2013-11-25 18:08:10 +05309335 hddTdlsPeer_t *pTdlsPeer;
Sunil Dutt41de4e22013-11-14 18:09:02 +05309336 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9337 " %s : NL80211_TDLS_SETUP for " MAC_ADDRESS_STR,
9338 __func__, MAC_ADDR_ARRAY(peer));
9339
9340 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
9341 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
9342
9343 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9344 " %s TDLS External control and Implicit Trigger not enabled ",
9345 __func__);
9346 return -ENOTSUPP;
9347 }
9348
Naresh Jayaramdb4514b2013-11-25 18:08:10 +05309349 /* To cater the requirement of establishing the TDLS link
9350 * irrespective of the data traffic , get an entry of TDLS peer.
9351 */
9352 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, peer);
9353 if (pTdlsPeer == NULL) {
9354 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9355 "%s: peer " MAC_ADDRESS_STR " not existing",
9356 __func__, MAC_ADDR_ARRAY(peer));
9357 return -EINVAL;
9358 }
Naresh Jayaram937abdf2013-11-26 19:50:25 +05309359
9360 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, TRUE) ) {
9361
9362 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9363 " %s TDLS Add Force Peer Failed",
9364 __func__);
9365 return -EINVAL;
9366 }
Naresh Jayaramdb4514b2013-11-25 18:08:10 +05309367 break;
Sunil Dutt41de4e22013-11-14 18:09:02 +05309368 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009369 case NL80211_TDLS_DISCOVERY_REQ:
9370 /* We don't support in-driver setup/teardown/discovery */
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309371 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
9372 "%s: We don't support in-driver setup/teardown/discovery "
9373 ,__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009374 return -ENOTSUPP;
9375 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309376 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9377 "%s: unsupported event",__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009378 return -ENOTSUPP;
9379 }
9380 return 0;
9381}
Chilam NG571c65a2013-01-19 12:27:36 +05309382
9383int wlan_hdd_cfg80211_send_tdls_discover_req(struct wiphy *wiphy,
9384 struct net_device *dev, u8 *peer)
9385{
Arif Hussaina7c8e412013-11-20 11:06:42 -08009386 hddLog(VOS_TRACE_LEVEL_INFO,
9387 "tdls send discover req: "MAC_ADDRESS_STR,
9388 MAC_ADDR_ARRAY(peer));
Chilam NG571c65a2013-01-19 12:27:36 +05309389
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +05309390#if TDLS_MGMT_VERSION2
9391 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
9392 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
9393#else
Chilam NG571c65a2013-01-19 12:27:36 +05309394 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
9395 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, NULL, 0);
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +05309396#endif
Chilam NG571c65a2013-01-19 12:27:36 +05309397}
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009398#endif
9399
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309400#ifdef WLAN_FEATURE_GTK_OFFLOAD
9401/*
9402 * FUNCTION: wlan_hdd_cfg80211_update_replayCounterCallback
9403 * Callback rountine called upon receiving response for
9404 * get offload info
9405 */
9406void wlan_hdd_cfg80211_update_replayCounterCallback(void *callbackContext,
9407 tpSirGtkOffloadGetInfoRspParams pGtkOffloadGetInfoRsp)
9408{
9409
9410 hdd_adapter_t *pAdapter = (hdd_adapter_t *)callbackContext;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05309411 tANI_U8 tempReplayCounter[8];
9412 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309413
9414 ENTER();
9415
9416 if (NULL == pAdapter)
9417 {
Agarwal Ashish971c2882013-10-30 20:11:12 +05309418 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309419 "%s: HDD adapter is Null", __func__);
9420 return ;
9421 }
9422
9423 if (NULL == pGtkOffloadGetInfoRsp)
9424 {
9425 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9426 "%s: pGtkOffloadGetInfoRsp is Null", __func__);
9427 return ;
9428 }
9429
9430 if (VOS_STATUS_SUCCESS != pGtkOffloadGetInfoRsp->ulStatus)
9431 {
9432 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9433 "%s: wlan Failed to get replay counter value",
9434 __func__);
9435 return ;
9436 }
9437
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05309438 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9439 /* Update replay counter */
9440 pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter =
9441 pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
9442
9443 {
9444 /* changing from little to big endian since supplicant
9445 * works on big endian format
9446 */
9447 int i;
9448 tANI_U8 *p = (tANI_U8 *)&pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
9449
9450 for (i = 0; i < 8; i++)
9451 {
9452 tempReplayCounter[7-i] = (tANI_U8)p[i];
9453 }
9454 }
9455
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309456 /* Update replay counter to NL */
9457 cfg80211_gtk_rekey_notify(pAdapter->dev, pGtkOffloadGetInfoRsp->bssId,
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05309458 tempReplayCounter, GFP_KERNEL);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309459}
9460
9461/*
9462 * FUNCTION: wlan_hdd_cfg80211_set_rekey_data
9463 * This function is used to offload GTK rekeying job to the firmware.
9464 */
9465int wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
9466 struct cfg80211_gtk_rekey_data *data)
9467{
9468 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
9469 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
9470 hdd_station_ctx_t *pHddStaCtx;
9471 tHalHandle hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309472 int result;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05309473 tSirGtkOffloadParams hddGtkOffloadReqParams;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309474 eHalStatus status = eHAL_STATUS_FAILURE;
9475
9476 ENTER();
9477
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309478
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309479 if (NULL == pAdapter)
9480 {
9481 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
9482 "%s: HDD adapter is Null", __func__);
9483 return -ENODEV;
9484 }
9485
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309486 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
9487 TRACE_CODE_HDD_CFG80211_SET_REKEY_DATA,
9488 pAdapter->sessionId, pAdapter->device_mode));
9489
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309490 result = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309491
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309492 if (0 != result)
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309493 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309494 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9495 "%s: HDD context is not valid", __func__);
9496 return result;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309497 }
9498
9499 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9500 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
9501 if (NULL == hHal)
9502 {
9503 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9504 "%s: HAL context is Null!!!", __func__);
9505 return -EAGAIN;
9506 }
9507
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05309508 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_ENABLE;
9509 memcpy(pHddStaCtx->gtkOffloadReqParams.aKCK, data->kck, NL80211_KCK_LEN);
9510 memcpy(pHddStaCtx->gtkOffloadReqParams.aKEK, data->kek, NL80211_KEK_LEN);
9511 memcpy(pHddStaCtx->gtkOffloadReqParams.bssId, &pHddStaCtx->conn_info.bssId,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309512 WNI_CFG_BSSID_LEN);
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05309513 {
9514 /* changing from big to little endian since driver
9515 * works on little endian format
9516 */
9517 tANI_U8 *p =
9518 (tANI_U8 *)&pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter;
9519 int i;
9520
9521 for (i = 0; i < 8; i++)
9522 {
9523 p[7-i] = data->replay_ctr[i];
9524 }
9525 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309526
9527 if (TRUE == pHddCtx->hdd_wlan_suspended)
9528 {
9529 /* if wlan is suspended, enable GTK offload directly from here */
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05309530 memcpy(&hddGtkOffloadReqParams, &pHddStaCtx->gtkOffloadReqParams,
9531 sizeof (tSirGtkOffloadParams));
9532 status = sme_SetGTKOffload(hHal, &hddGtkOffloadReqParams,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309533 pAdapter->sessionId);
9534
9535 if (eHAL_STATUS_SUCCESS != status)
9536 {
9537 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9538 "%s: sme_SetGTKOffload failed, returned %d",
9539 __func__, status);
9540 return status;
9541 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309542 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9543 "%s: sme_SetGTKOffload successfull", __func__);
9544 }
9545 else
9546 {
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309547 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9548 "%s: wlan not suspended GTKOffload request is stored",
9549 __func__);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309550 }
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05309551
9552 return eHAL_STATUS_SUCCESS;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309553}
9554#endif /*WLAN_FEATURE_GTK_OFFLOAD*/
9555
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05309556/*
9557 * FUNCTION: wlan_hdd_cfg80211_set_mac_acl
9558 * This function is used to set access control policy
9559 */
9560static int wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy,
9561 struct net_device *dev, const struct cfg80211_acl_data *params)
9562{
9563 int i;
9564 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
9565 hdd_hostapd_state_t *pHostapdState;
9566 tsap_Config_t *pConfig;
9567 v_CONTEXT_t pVosContext = NULL;
9568 hdd_context_t *pHddCtx;
9569 int status;
9570
9571 ENTER();
9572
9573 if (NULL == pAdapter)
9574 {
9575 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
9576 "%s: HDD adapter is Null", __func__);
9577 return -ENODEV;
9578 }
9579
9580 if (NULL == params)
9581 {
9582 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
9583 "%s: params is Null", __func__);
9584 return -EINVAL;
9585 }
9586
9587 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9588 status = wlan_hdd_validate_context(pHddCtx);
9589
9590 if (0 != status)
9591 {
9592 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9593 "%s: HDD context is not valid", __func__);
9594 return status;
9595 }
9596
9597 pVosContext = pHddCtx->pvosContext;
9598 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
9599
9600 if (NULL == pHostapdState)
9601 {
9602 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
9603 "%s: pHostapdState is Null", __func__);
9604 return -EINVAL;
9605 }
9606
9607 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"acl policy: = %d"
9608 "no acl entries = %d", params->acl_policy, params->n_acl_entries);
9609
9610 if (WLAN_HDD_SOFTAP == pAdapter->device_mode)
9611 {
9612 pConfig = &pAdapter->sessionCtx.ap.sapConfig;
9613
9614 /* default value */
9615 pConfig->num_accept_mac = 0;
9616 pConfig->num_deny_mac = 0;
9617
9618 /**
9619 * access control policy
9620 * @NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED: Deny stations which are
9621 * listed in hostapd.deny file.
9622 * @NL80211_ACL_POLICY_DENY_UNLESS_LISTED: Allow stations which are
9623 * listed in hostapd.accept file.
9624 */
9625 if (NL80211_ACL_POLICY_DENY_UNLESS_LISTED == params->acl_policy)
9626 {
9627 pConfig->SapMacaddr_acl = eSAP_DENY_UNLESS_ACCEPTED;
9628 }
9629 else if (NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED == params->acl_policy)
9630 {
9631 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
9632 }
9633 else
9634 {
9635 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9636 "%s:Acl Policy : %d is not supported",
9637 __func__, params->acl_policy);
9638 return -ENOTSUPP;
9639 }
9640
9641 if (eSAP_DENY_UNLESS_ACCEPTED == pConfig->SapMacaddr_acl)
9642 {
9643 pConfig->num_accept_mac = params->n_acl_entries;
9644 for (i = 0; i < params->n_acl_entries; i++)
9645 {
9646 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9647 "** Add ACL MAC entry %i in WhiletList :"
9648 MAC_ADDRESS_STR, i,
9649 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
9650
9651 vos_mem_copy(&pConfig->accept_mac[i], params->mac_addrs[i].addr,
9652 sizeof(qcmacaddr));
9653 }
9654 }
9655 else if (eSAP_ACCEPT_UNLESS_DENIED == pConfig->SapMacaddr_acl)
9656 {
9657 pConfig->num_deny_mac = params->n_acl_entries;
9658 for (i = 0; i < params->n_acl_entries; i++)
9659 {
9660 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9661 "** Add ACL MAC entry %i in BlackList :"
9662 MAC_ADDRESS_STR, i,
9663 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
9664
9665 vos_mem_copy(&pConfig->deny_mac[i], params->mac_addrs[i].addr,
9666 sizeof(qcmacaddr));
9667 }
9668 }
9669
9670 if (VOS_STATUS_SUCCESS != WLANSAP_SetMacACL(pVosContext, pConfig))
9671 {
9672 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9673 "%s: SAP Set Mac Acl fail", __func__);
9674 return -EINVAL;
9675 }
9676 }
9677 else
9678 {
9679 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309680 "%s: Invalid device_mode = %s (%d)",
9681 __func__, hdd_device_modetoString(pAdapter->device_mode),
9682 pAdapter->device_mode);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05309683 return -EINVAL;
9684 }
9685
9686 return 0;
9687}
9688
Leo Chang9056f462013-08-01 19:21:11 -07009689#ifdef WLAN_NL80211_TESTMODE
9690#ifdef FEATURE_WLAN_LPHB
Leo Changd9df8aa2013-09-26 13:32:26 -07009691void wlan_hdd_cfg80211_lphb_ind_handler
Leo Chang9056f462013-08-01 19:21:11 -07009692(
9693 void *pAdapter,
9694 void *indCont
9695)
9696{
Leo Changd9df8aa2013-09-26 13:32:26 -07009697 tSirLPHBInd *lphbInd;
9698 struct sk_buff *skb;
c_hpothu73f35e62014-04-18 13:40:08 +05309699 hdd_context_t *pHddCtxt;
Leo Chang9056f462013-08-01 19:21:11 -07009700
9701 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -07009702 "LPHB indication arrived");
Leo Chang9056f462013-08-01 19:21:11 -07009703
c_hpothu73f35e62014-04-18 13:40:08 +05309704 if (pAdapter == NULL)
9705 {
9706 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9707 "%s: pAdapter is NULL\n",__func__);
9708 return;
9709 }
9710
Leo Chang9056f462013-08-01 19:21:11 -07009711 if (NULL == indCont)
9712 {
9713 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -07009714 "LPHB IND, invalid argument");
Leo Chang9056f462013-08-01 19:21:11 -07009715 return;
9716 }
9717
c_hpothu73f35e62014-04-18 13:40:08 +05309718 pHddCtxt = (hdd_context_t *)pAdapter;
Leo Changd9df8aa2013-09-26 13:32:26 -07009719 lphbInd = (tSirLPHBInd *)indCont;
Leo Chang9056f462013-08-01 19:21:11 -07009720 skb = cfg80211_testmode_alloc_event_skb(
c_hpothu73f35e62014-04-18 13:40:08 +05309721 pHddCtxt->wiphy,
Leo Changd9df8aa2013-09-26 13:32:26 -07009722 sizeof(tSirLPHBInd),
Leo Chang9056f462013-08-01 19:21:11 -07009723 GFP_ATOMIC);
9724 if (!skb)
9725 {
9726 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9727 "LPHB timeout, NL buffer alloc fail");
9728 return;
9729 }
9730
Leo Changac3ba772013-10-07 09:47:04 -07009731 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_CMD, WLAN_HDD_TM_CMD_WLAN_HB))
Leo Changd9df8aa2013-09-26 13:32:26 -07009732 {
9733 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9734 "WLAN_HDD_TM_ATTR_CMD put fail");
9735 goto nla_put_failure;
9736 }
Leo Changac3ba772013-10-07 09:47:04 -07009737 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_TYPE, lphbInd->protocolType))
Leo Changd9df8aa2013-09-26 13:32:26 -07009738 {
9739 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9740 "WLAN_HDD_TM_ATTR_TYPE put fail");
9741 goto nla_put_failure;
9742 }
Leo Changac3ba772013-10-07 09:47:04 -07009743 if(nla_put(skb, WLAN_HDD_TM_ATTR_DATA,
Leo Changd9df8aa2013-09-26 13:32:26 -07009744 sizeof(tSirLPHBInd), lphbInd))
9745 {
9746 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9747 "WLAN_HDD_TM_ATTR_DATA put fail");
9748 goto nla_put_failure;
9749 }
Leo Chang9056f462013-08-01 19:21:11 -07009750 cfg80211_testmode_event(skb, GFP_ATOMIC);
9751 return;
9752
9753nla_put_failure:
9754 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9755 "NLA Put fail");
9756 kfree_skb(skb);
9757
9758 return;
9759}
9760#endif /* FEATURE_WLAN_LPHB */
9761
9762static int wlan_hdd_cfg80211_testmode(struct wiphy *wiphy, void *data, int len)
9763{
9764 struct nlattr *tb[WLAN_HDD_TM_ATTR_MAX + 1];
9765 int err = 0;
9766#ifdef FEATURE_WLAN_LPHB
9767 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Leo Changd9df8aa2013-09-26 13:32:26 -07009768 eHalStatus smeStatus;
Leo Chang9056f462013-08-01 19:21:11 -07009769#endif /* FEATURE_WLAN_LPHB */
9770
9771 err = nla_parse(tb, WLAN_HDD_TM_ATTR_MAX, data, len, wlan_hdd_tm_policy);
9772 if (err)
9773 {
9774 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9775 "%s Testmode INV ATTR", __func__);
9776 return err;
9777 }
9778
9779 if (!tb[WLAN_HDD_TM_ATTR_CMD])
9780 {
9781 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9782 "%s Testmode INV CMD", __func__);
9783 return -EINVAL;
9784 }
9785
9786 switch (nla_get_u32(tb[WLAN_HDD_TM_ATTR_CMD]))
9787 {
9788#ifdef FEATURE_WLAN_LPHB
9789 /* Low Power Heartbeat configuration request */
9790 case WLAN_HDD_TM_CMD_WLAN_HB:
9791 {
9792 int buf_len;
9793 void *buf;
9794 tSirLPHBReq *hb_params = NULL;
Amar Singhal05852702014-02-04 14:40:00 -08009795 tSirLPHBReq *hb_params_temp = NULL;
Leo Chang9056f462013-08-01 19:21:11 -07009796
9797 if (!tb[WLAN_HDD_TM_ATTR_DATA])
9798 {
9799 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9800 "%s Testmode INV DATA", __func__);
9801 return -EINVAL;
9802 }
9803
9804 buf = nla_data(tb[WLAN_HDD_TM_ATTR_DATA]);
9805 buf_len = nla_len(tb[WLAN_HDD_TM_ATTR_DATA]);
Amar Singhal05852702014-02-04 14:40:00 -08009806
9807 hb_params_temp =(tSirLPHBReq *)buf;
9808 if ((hb_params_temp->cmd == LPHB_SET_TCP_PARAMS_INDID) &&
9809 (hb_params_temp->params.lphbTcpParamReq.timePeriodSec == 0))
9810 return -EINVAL;
9811
Leo Chang9056f462013-08-01 19:21:11 -07009812 hb_params = (tSirLPHBReq *)vos_mem_malloc(sizeof(tSirLPHBReq));
9813 if (NULL == hb_params)
9814 {
9815 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9816 "%s Request Buffer Alloc Fail", __func__);
9817 return -EINVAL;
9818 }
9819
9820 vos_mem_copy(hb_params, buf, buf_len);
Leo Changd9df8aa2013-09-26 13:32:26 -07009821 smeStatus = sme_LPHBConfigReq((tHalHandle)(pHddCtx->hHal),
9822 hb_params,
9823 wlan_hdd_cfg80211_lphb_ind_handler);
9824 if (eHAL_STATUS_SUCCESS != smeStatus)
Leo Chang9056f462013-08-01 19:21:11 -07009825 {
Leo Changd9df8aa2013-09-26 13:32:26 -07009826 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9827 "LPHB Config Fail, disable");
Leo Chang9056f462013-08-01 19:21:11 -07009828 vos_mem_free(hb_params);
9829 }
Leo Chang9056f462013-08-01 19:21:11 -07009830 return 0;
9831 }
9832#endif /* FEATURE_WLAN_LPHB */
9833 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309834 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9835 "%s: unsupported event",__func__);
Leo Chang9056f462013-08-01 19:21:11 -07009836 return -EOPNOTSUPP;
9837 }
9838
9839 return err;
9840}
9841#endif /* CONFIG_NL80211_TESTMODE */
9842
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +05309843static int wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
9844 struct net_device *dev,
9845 int idx, struct survey_info *survey)
9846{
9847 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
9848 hdd_context_t *pHddCtx;
Mihir Sheted9072e02013-08-21 17:02:29 +05309849 hdd_station_ctx_t *pHddStaCtx;
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +05309850 tHalHandle halHandle;
Mihir Sheted9072e02013-08-21 17:02:29 +05309851 v_U32_t channel = 0, freq = 0; /* Initialization Required */
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +05309852 v_S7_t snr,rssi;
9853 int status, i, j, filled = 0;
9854
9855 ENTER();
9856
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +05309857 if (NULL == pAdapter)
9858 {
9859 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
9860 "%s: HDD adapter is Null", __func__);
9861 return -ENODEV;
9862 }
9863
9864 if (NULL == wiphy)
9865 {
9866 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
9867 "%s: wiphy is Null", __func__);
9868 return -ENODEV;
9869 }
9870
9871 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9872 status = wlan_hdd_validate_context(pHddCtx);
9873
9874 if (0 != status)
9875 {
9876 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9877 "%s: HDD context is not valid", __func__);
9878 return status;
9879 }
9880
Mihir Sheted9072e02013-08-21 17:02:29 +05309881 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9882
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +05309883 if (0 == pHddCtx->cfg_ini->fEnableSNRMonitoring ||
Mihir Sheted9072e02013-08-21 17:02:29 +05309884 0 != pAdapter->survey_idx ||
9885 eConnectionState_Associated != pHddStaCtx->conn_info.connState)
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +05309886 {
9887 /* The survey dump ops when implemented completely is expected to
9888 * return a survey of all channels and the ops is called by the
9889 * kernel with incremental values of the argument 'idx' till it
9890 * returns -ENONET. But we can only support the survey for the
9891 * operating channel for now. survey_idx is used to track
9892 * that the ops is called only once and then return -ENONET for
9893 * the next iteration
9894 */
9895 pAdapter->survey_idx = 0;
9896 return -ENONET;
9897 }
9898
9899 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
9900
9901 wlan_hdd_get_snr(pAdapter, &snr);
9902 wlan_hdd_get_rssi(pAdapter, &rssi);
9903
9904 sme_GetOperationChannel(halHandle, &channel, pAdapter->sessionId);
9905 hdd_wlan_get_freq(channel, &freq);
9906
9907
9908 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
9909 {
9910 if (NULL == wiphy->bands[i])
9911 {
9912 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
9913 "%s: wiphy->bands[i] is NULL, i = %d", __func__, i);
9914 continue;
9915 }
9916
9917 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
9918 {
9919 struct ieee80211_supported_band *band = wiphy->bands[i];
9920
9921 if (band->channels[j].center_freq == (v_U16_t)freq)
9922 {
9923 survey->channel = &band->channels[j];
9924 /* The Rx BDs contain SNR values in dB for the received frames
9925 * while the supplicant expects noise. So we calculate and
9926 * return the value of noise (dBm)
9927 * SNR (dB) = RSSI (dBm) - NOISE (dBm)
9928 */
9929 survey->noise = rssi - snr;
9930 survey->filled = SURVEY_INFO_NOISE_DBM;
9931 filled = 1;
9932 }
9933 }
9934 }
9935
9936 if (filled)
9937 pAdapter->survey_idx = 1;
9938 else
9939 {
9940 pAdapter->survey_idx = 0;
9941 return -ENONET;
9942 }
9943
9944 return 0;
9945}
9946
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05309947/*
9948 * FUNCTION: wlan_hdd_cfg80211_resume_wlan
9949 * this is called when cfg80211 driver resume
9950 * driver updates latest sched_scan scan result(if any) to cfg80211 database
9951 */
9952int wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
9953{
9954 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
9955 hdd_adapter_t *pAdapter;
9956 hdd_adapter_list_node_t *pAdapterNode, *pNext;
9957 VOS_STATUS status = VOS_STATUS_SUCCESS;
9958
9959 ENTER();
9960
9961 if ( NULL == pHddCtx )
9962 {
9963 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
9964 "%s: HddCtx validation failed", __func__);
9965 return 0;
9966 }
9967
9968 if (pHddCtx->isLogpInProgress)
9969 {
9970 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9971 "%s: LOGP in Progress. Ignore!!!", __func__);
9972 return 0;
9973 }
9974
Mihir Shete18156292014-03-11 15:38:30 +05309975 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05309976 {
9977 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9978 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
9979 return 0;
9980 }
9981
9982 spin_lock(&pHddCtx->schedScan_lock);
9983 pHddCtx->isWiphySuspended = FALSE;
9984 if (TRUE != pHddCtx->isSchedScanUpdatePending)
9985 {
9986 spin_unlock(&pHddCtx->schedScan_lock);
9987 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9988 "%s: Return resume is not due to PNO indication", __func__);
9989 return 0;
9990 }
9991 // Reset flag to avoid updatating cfg80211 data old results again
9992 pHddCtx->isSchedScanUpdatePending = FALSE;
9993 spin_unlock(&pHddCtx->schedScan_lock);
9994
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +05309995
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05309996 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
9997
9998 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
9999 {
10000 pAdapter = pAdapterNode->pAdapter;
10001 if ( (NULL != pAdapter) &&
10002 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) )
10003 {
10004 if (0 != wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter))
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053010005 {
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053010006 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
10007 "%s: NO SCAN result", __func__);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053010008 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053010009 else
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053010010 {
10011 /* Acquire wakelock to handle the case where APP's tries to
10012 * suspend immediately after updating the scan results. Whis
10013 * results in app's is in suspended state and not able to
10014 * process the connect request to AP
10015 */
10016 hdd_prevent_suspend_timeout(2000);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053010017 cfg80211_sched_scan_results(pHddCtx->wiphy);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053010018 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053010019
10020 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
10021 "%s : cfg80211 scan result database updated", __func__);
10022
10023 return 0;
10024
10025 }
10026 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
10027 pAdapterNode = pNext;
10028 }
10029
10030 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
10031 "%s: Failed to find Adapter", __func__);
10032 return 0;
10033}
10034
10035/*
10036 * FUNCTION: wlan_hdd_cfg80211_suspend_wlan
10037 * this is called when cfg80211 driver suspends
10038 */
10039int wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
10040 struct cfg80211_wowlan *wow)
10041{
10042 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
10043
10044 ENTER();
10045 if (NULL == pHddCtx)
10046 {
10047 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
10048 "%s: HddCtx validation failed", __func__);
10049 return 0;
10050 }
10051
10052 pHddCtx->isWiphySuspended = TRUE;
10053
10054 EXIT();
10055
10056 return 0;
10057}
10058
Jeff Johnson295189b2012-06-20 16:38:30 -070010059/* cfg80211_ops */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010060static struct cfg80211_ops wlan_hdd_cfg80211_ops =
Jeff Johnson295189b2012-06-20 16:38:30 -070010061{
10062 .add_virtual_intf = wlan_hdd_add_virtual_intf,
10063 .del_virtual_intf = wlan_hdd_del_virtual_intf,
10064 .change_virtual_intf = wlan_hdd_cfg80211_change_iface,
10065 .change_station = wlan_hdd_change_station,
10066#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
10067 .add_beacon = wlan_hdd_cfg80211_add_beacon,
10068 .del_beacon = wlan_hdd_cfg80211_del_beacon,
10069 .set_beacon = wlan_hdd_cfg80211_set_beacon,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010070#else
10071 .start_ap = wlan_hdd_cfg80211_start_ap,
10072 .change_beacon = wlan_hdd_cfg80211_change_beacon,
10073 .stop_ap = wlan_hdd_cfg80211_stop_ap,
Jeff Johnson295189b2012-06-20 16:38:30 -070010074#endif
10075 .change_bss = wlan_hdd_cfg80211_change_bss,
10076 .add_key = wlan_hdd_cfg80211_add_key,
10077 .get_key = wlan_hdd_cfg80211_get_key,
10078 .del_key = wlan_hdd_cfg80211_del_key,
10079 .set_default_key = wlan_hdd_cfg80211_set_default_key,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080010080#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
Jeff Johnson295189b2012-06-20 16:38:30 -070010081 .set_channel = wlan_hdd_cfg80211_set_channel,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080010082#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010083 .scan = wlan_hdd_cfg80211_scan,
10084 .connect = wlan_hdd_cfg80211_connect,
10085 .disconnect = wlan_hdd_cfg80211_disconnect,
10086 .join_ibss = wlan_hdd_cfg80211_join_ibss,
10087 .leave_ibss = wlan_hdd_cfg80211_leave_ibss,
10088 .set_wiphy_params = wlan_hdd_cfg80211_set_wiphy_params,
10089 .set_tx_power = wlan_hdd_cfg80211_set_txpower,
10090 .get_tx_power = wlan_hdd_cfg80211_get_txpower,
Jeff Johnson295189b2012-06-20 16:38:30 -070010091 .remain_on_channel = wlan_hdd_cfg80211_remain_on_channel,
10092 .cancel_remain_on_channel = wlan_hdd_cfg80211_cancel_remain_on_channel,
DARAM SUDHA39eede62014-02-12 11:16:40 +053010093 .mgmt_tx = wlan_hdd_mgmt_tx,
Jeff Johnson295189b2012-06-20 16:38:30 -070010094#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
10095 .mgmt_tx_cancel_wait = wlan_hdd_cfg80211_mgmt_tx_cancel_wait,
10096 .set_default_mgmt_key = wlan_hdd_set_default_mgmt_key,
10097 .set_txq_params = wlan_hdd_set_txq_params,
10098#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010099 .get_station = wlan_hdd_cfg80211_get_station,
10100 .set_power_mgmt = wlan_hdd_cfg80211_set_power_mgmt,
10101 .del_station = wlan_hdd_cfg80211_del_station,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010102 .add_station = wlan_hdd_cfg80211_add_station,
10103#ifdef FEATURE_WLAN_LFR
10104 .set_pmksa = wlan_hdd_cfg80211_set_pmksa,
10105 .del_pmksa = wlan_hdd_cfg80211_del_pmksa,
10106 .flush_pmksa = wlan_hdd_cfg80211_flush_pmksa,
10107#endif
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070010108#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
10109 .update_ft_ies = wlan_hdd_cfg80211_update_ft_ies,
10110#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080010111#ifdef FEATURE_WLAN_TDLS
10112 .tdls_mgmt = wlan_hdd_cfg80211_tdls_mgmt,
10113 .tdls_oper = wlan_hdd_cfg80211_tdls_oper,
10114#endif
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053010115#ifdef WLAN_FEATURE_GTK_OFFLOAD
10116 .set_rekey_data = wlan_hdd_cfg80211_set_rekey_data,
10117#endif /* WLAN_FEATURE_GTK_OFFLOAD */
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053010118#ifdef FEATURE_WLAN_SCAN_PNO
10119 .sched_scan_start = wlan_hdd_cfg80211_sched_scan_start,
10120 .sched_scan_stop = wlan_hdd_cfg80211_sched_scan_stop,
10121#endif /*FEATURE_WLAN_SCAN_PNO */
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053010122 .resume = wlan_hdd_cfg80211_resume_wlan,
10123 .suspend = wlan_hdd_cfg80211_suspend_wlan,
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053010124 .set_mac_acl = wlan_hdd_cfg80211_set_mac_acl,
Leo Chang9056f462013-08-01 19:21:11 -070010125#ifdef WLAN_NL80211_TESTMODE
10126 .testmode_cmd = wlan_hdd_cfg80211_testmode,
10127#endif
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053010128 .dump_survey = wlan_hdd_cfg80211_dump_survey,
Jeff Johnson295189b2012-06-20 16:38:30 -070010129};
10130