blob: 95696ec5a5324c32693b6caea55f3a9c59fb43c2 [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 );
Jeff Johnson295189b2012-06-20 16:38:30 -0700973}
974
975void wlan_hdd_cfg80211_pre_voss_stop(hdd_adapter_t* pAdapter)
976{
Jeff Johnson295189b2012-06-20 16:38:30 -0700977 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
978 /* Register for all P2P action, public action etc frames */
979 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
980
Jeff Johnsone7245742012-09-05 17:12:55 -0700981 ENTER();
982
Jeff Johnson295189b2012-06-20 16:38:30 -0700983 /* Right now we are registering these frame when driver is getting
984 initialized. Once we will move to 2.6.37 kernel, in which we have
985 frame register ops, we will move this code as a part of that */
986 /* GAS Initial Request */
987
988 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
989 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
990
991 /* GAS Initial Response */
992 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
993 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530994
Jeff Johnson295189b2012-06-20 16:38:30 -0700995 /* GAS Comeback Request */
996 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
997 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
998
999 /* GAS Comeback Response */
1000 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
1001 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
1002
1003 /* P2P Public Action */
1004 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301005 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -07001006 P2P_PUBLIC_ACTION_FRAME_SIZE );
1007
1008 /* P2P Action */
1009 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
1010 (v_U8_t*)P2P_ACTION_FRAME,
1011 P2P_ACTION_FRAME_SIZE );
Chet Lanctot186b5732013-03-18 10:26:30 -07001012
1013#ifdef WLAN_FEATURE_11W
1014 /* SA Query Response Action Frame */
1015 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
1016 (v_U8_t*)SA_QUERY_FRAME_RSP,
1017 SA_QUERY_FRAME_RSP_SIZE );
1018#endif /* WLAN_FEATURE_11W */
Jeff Johnson295189b2012-06-20 16:38:30 -07001019}
1020
1021#ifdef FEATURE_WLAN_WAPI
1022void wlan_hdd_cfg80211_set_key_wapi(hdd_adapter_t* pAdapter, u8 key_index,
1023 const u8 *mac_addr, u8 *key , int key_Len)
1024{
1025 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
1026 tCsrRoamSetKey setKey;
1027 v_BOOL_t isConnected = TRUE;
1028 int status = 0;
1029 v_U32_t roamId= 0xFF;
1030 tANI_U8 *pKeyPtr = NULL;
1031 int n = 0;
1032
Arif Hussain6d2a3322013-11-17 19:50:10 -08001033 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07001034 __func__,pAdapter->device_mode);
1035
Gopichand Nakkalae7480202013-02-11 15:24:22 +05301036 vos_mem_zero(&setKey, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -07001037 setKey.keyId = key_index; // Store Key ID
1038 setKey.encType = eCSR_ENCRYPT_TYPE_WPI; // SET WAPI Encryption
1039 setKey.keyDirection = eSIR_TX_RX; // Key Directionn both TX and RX
1040 setKey.paeRole = 0 ; // the PAE role
1041 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
1042 {
1043 vos_set_macaddr_broadcast( (v_MACADDR_t *)setKey.peerMac );
1044 }
1045 else
1046 {
1047 isConnected = hdd_connIsConnected(pHddStaCtx);
1048 vos_mem_copy(setKey.peerMac,&pHddStaCtx->conn_info.bssId,WNI_CFG_BSSID_LEN);
1049 }
1050 setKey.keyLength = key_Len;
1051 pKeyPtr = setKey.Key;
1052 memcpy( pKeyPtr, key, key_Len);
1053
Arif Hussain6d2a3322013-11-17 19:50:10 -08001054 hddLog(VOS_TRACE_LEVEL_INFO,"%s: WAPI KEY LENGTH:0x%04x",
Jeff Johnson295189b2012-06-20 16:38:30 -07001055 __func__, key_Len);
1056 for (n = 0 ; n < key_Len; n++)
1057 hddLog(VOS_TRACE_LEVEL_INFO, "%s WAPI KEY Data[%d]:%02x ",
1058 __func__,n,setKey.Key[n]);
1059
1060 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
1061 if ( isConnected )
1062 {
1063 status= sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
1064 pAdapter->sessionId, &setKey, &roamId );
1065 }
1066 if ( status != 0 )
1067 {
1068 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1069 "[%4d] sme_RoamSetKey returned ERROR status= %d",
1070 __LINE__, status );
1071 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
1072 }
1073}
1074#endif /* FEATURE_WLAN_WAPI*/
1075
1076#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301077int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07001078 beacon_data_t **ppBeacon,
1079 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001080#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301081int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001082 beacon_data_t **ppBeacon,
1083 struct cfg80211_beacon_data *params,
1084 int dtim_period)
1085#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301086{
Jeff Johnson295189b2012-06-20 16:38:30 -07001087 int size;
1088 beacon_data_t *beacon = NULL;
1089 beacon_data_t *old = NULL;
1090 int head_len,tail_len;
1091
Jeff Johnsone7245742012-09-05 17:12:55 -07001092 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07001093 if (params->head && !params->head_len)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05301094 {
1095 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1096 FL("head_len is NULL"));
Jeff Johnson295189b2012-06-20 16:38:30 -07001097 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05301098 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001099
1100 old = pAdapter->sessionCtx.ap.beacon;
1101
1102 if (!params->head && !old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05301103 {
1104 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1105 FL("session(%d) old and new heads points to NULL"),
1106 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07001107 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05301108 }
1109
1110 if (params->tail && !params->tail_len)
1111 {
1112 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1113 FL("tail_len is zero but tail is not NULL"));
1114 return -EINVAL;
1115 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001116
Jeff Johnson295189b2012-06-20 16:38:30 -07001117#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,38))
1118 /* Kernel 3.0 is not updating dtim_period for set beacon */
1119 if (!params->dtim_period)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05301120 {
1121 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1122 FL("dtim period is 0"));
Jeff Johnson295189b2012-06-20 16:38:30 -07001123 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05301124 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001125#endif
1126
1127 if(params->head)
1128 head_len = params->head_len;
1129 else
1130 head_len = old->head_len;
1131
1132 if(params->tail || !old)
1133 tail_len = params->tail_len;
1134 else
1135 tail_len = old->tail_len;
1136
1137 size = sizeof(beacon_data_t) + head_len + tail_len;
1138
1139 beacon = kzalloc(size, GFP_KERNEL);
1140
1141 if( beacon == NULL )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05301142 {
1143 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1144 FL("Mem allocation for beacon failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -07001145 return -ENOMEM;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05301146 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001147
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001148#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07001149 if(params->dtim_period || !old )
1150 beacon->dtim_period = params->dtim_period;
1151 else
1152 beacon->dtim_period = old->dtim_period;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001153#else
1154 if(dtim_period || !old )
1155 beacon->dtim_period = dtim_period;
1156 else
1157 beacon->dtim_period = old->dtim_period;
1158#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301159
Jeff Johnson295189b2012-06-20 16:38:30 -07001160 beacon->head = ((u8 *) beacon) + sizeof(beacon_data_t);
1161 beacon->tail = beacon->head + head_len;
1162 beacon->head_len = head_len;
1163 beacon->tail_len = tail_len;
1164
1165 if(params->head) {
1166 memcpy (beacon->head,params->head,beacon->head_len);
1167 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301168 else {
Jeff Johnson295189b2012-06-20 16:38:30 -07001169 if(old)
1170 memcpy (beacon->head,old->head,beacon->head_len);
1171 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301172
Jeff Johnson295189b2012-06-20 16:38:30 -07001173 if(params->tail) {
1174 memcpy (beacon->tail,params->tail,beacon->tail_len);
1175 }
1176 else {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301177 if(old)
Jeff Johnson295189b2012-06-20 16:38:30 -07001178 memcpy (beacon->tail,old->tail,beacon->tail_len);
1179 }
1180
1181 *ppBeacon = beacon;
1182
1183 kfree(old);
1184
1185 return 0;
1186
1187}
Jeff Johnson295189b2012-06-20 16:38:30 -07001188
1189v_U8_t* wlan_hdd_cfg80211_get_ie_ptr(v_U8_t *pIes, int length, v_U8_t eid)
1190{
1191 int left = length;
1192 v_U8_t *ptr = pIes;
1193 v_U8_t elem_id,elem_len;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301194
Jeff Johnson295189b2012-06-20 16:38:30 -07001195 while(left >= 2)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301196 {
Jeff Johnson295189b2012-06-20 16:38:30 -07001197 elem_id = ptr[0];
1198 elem_len = ptr[1];
1199 left -= 2;
1200 if(elem_len > left)
1201 {
1202 hddLog(VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07001203 FL("****Invalid IEs eid = %d elem_len=%d left=%d*****"),
Jeff Johnson295189b2012-06-20 16:38:30 -07001204 eid,elem_len,left);
1205 return NULL;
1206 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301207 if (elem_id == eid)
Jeff Johnson295189b2012-06-20 16:38:30 -07001208 {
1209 return ptr;
1210 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301211
Jeff Johnson295189b2012-06-20 16:38:30 -07001212 left -= elem_len;
1213 ptr += (elem_len + 2);
1214 }
1215 return NULL;
1216}
1217
Jeff Johnson295189b2012-06-20 16:38:30 -07001218/* Check if rate is 11g rate or not */
1219static int wlan_hdd_rate_is_11g(u8 rate)
1220{
Sanjay Devnani28322e22013-06-21 16:13:40 -07001221 static const u8 gRateArray[8] = {12, 18, 24, 36, 48, 72, 96, 108}; /* actual rate * 2 */
Jeff Johnson295189b2012-06-20 16:38:30 -07001222 u8 i;
1223 for (i = 0; i < 8; i++)
1224 {
1225 if(rate == gRateArray[i])
1226 return TRUE;
1227 }
1228 return FALSE;
1229}
1230
1231/* Check for 11g rate and set proper 11g only mode */
1232static void wlan_hdd_check_11gmode(u8 *pIe, u8* require_ht,
1233 u8* pCheckRatesfor11g, eSapPhyMode* pSapHw_mode)
1234{
1235 u8 i, num_rates = pIe[0];
1236
1237 pIe += 1;
1238 for ( i = 0; i < num_rates; i++)
1239 {
1240 if( *pCheckRatesfor11g && (TRUE == wlan_hdd_rate_is_11g(pIe[i] & RATE_MASK)))
1241 {
1242 /* If rate set have 11g rate than change the mode to 11G */
1243 *pSapHw_mode = eSAP_DOT11_MODE_11g;
1244 if (pIe[i] & BASIC_RATE_MASK)
1245 {
1246 /* If we have 11g rate as basic rate, it means mode
1247 is 11g only mode.
1248 */
1249 *pSapHw_mode = eSAP_DOT11_MODE_11g_ONLY;
1250 *pCheckRatesfor11g = FALSE;
1251 }
1252 }
1253 else if((BASIC_RATE_MASK | WLAN_BSS_MEMBERSHIP_SELECTOR_HT_PHY) == pIe[i])
1254 {
1255 *require_ht = TRUE;
1256 }
1257 }
1258 return;
1259}
1260
1261static void wlan_hdd_set_sapHwmode(hdd_adapter_t *pHostapdAdapter)
1262{
1263 tsap_Config_t *pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
1264 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
1265 struct ieee80211_mgmt *pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
1266 u8 checkRatesfor11g = TRUE;
1267 u8 require_ht = FALSE;
1268 u8 *pIe=NULL;
1269
1270 pConfig->SapHw_mode= eSAP_DOT11_MODE_11b;
1271
1272 pIe = wlan_hdd_cfg80211_get_ie_ptr(&pMgmt_frame->u.beacon.variable[0],
1273 pBeacon->head_len, WLAN_EID_SUPP_RATES);
1274 if (pIe != NULL)
1275 {
1276 pIe += 1;
1277 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
1278 &pConfig->SapHw_mode);
1279 }
1280
1281 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
1282 WLAN_EID_EXT_SUPP_RATES);
1283 if (pIe != NULL)
1284 {
1285
1286 pIe += 1;
1287 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
1288 &pConfig->SapHw_mode);
1289 }
1290
1291 if( pConfig->channel > 14 )
1292 {
1293 pConfig->SapHw_mode= eSAP_DOT11_MODE_11a;
1294 }
1295
1296 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
1297 WLAN_EID_HT_CAPABILITY);
1298
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301299 if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07001300 {
1301 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n;
1302 if(require_ht)
1303 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n_ONLY;
1304 }
1305}
1306
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05301307static int wlan_hdd_add_ie(hdd_adapter_t* pHostapdAdapter, v_U8_t *genie,
1308 v_U8_t *total_ielen, v_U8_t *oui, v_U8_t oui_size)
1309{
Arif Hussaine7f3ea52013-09-12 21:56:36 -07001310 v_U16_t ielen = 0;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05301311 v_U8_t *pIe = NULL;
1312 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
1313
1314 pIe = wlan_hdd_get_vendor_oui_ie_ptr(oui, oui_size,
1315 pBeacon->tail, pBeacon->tail_len);
1316
1317 if (pIe)
1318 {
1319 ielen = pIe[1] + 2;
1320 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
1321 {
1322 vos_mem_copy(&genie[*total_ielen], pIe, ielen);
1323 }
1324 else
1325 {
1326 hddLog( VOS_TRACE_LEVEL_ERROR, "**Ie Length is too big***");
1327 return -EINVAL;
1328 }
1329 *total_ielen += ielen;
1330 }
1331 return 0;
1332}
1333
Arif Hussaine7f3ea52013-09-12 21:56:36 -07001334static void wlan_hdd_add_hostapd_conf_vsie(hdd_adapter_t* pHostapdAdapter,
1335 v_U8_t *genie, v_U8_t *total_ielen)
1336{
1337 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
1338 int left = pBeacon->tail_len;
1339 v_U8_t *ptr = pBeacon->tail;
1340 v_U8_t elem_id, elem_len;
1341 v_U16_t ielen = 0;
1342
1343 if ( NULL == ptr || 0 == left )
1344 return;
1345
1346 while (left >= 2)
1347 {
1348 elem_id = ptr[0];
1349 elem_len = ptr[1];
1350 left -= 2;
1351 if (elem_len > left)
1352 {
1353 hddLog( VOS_TRACE_LEVEL_ERROR,
1354 "****Invalid IEs eid = %d elem_len=%d left=%d*****",
1355 elem_id, elem_len, left);
1356 return;
1357 }
1358 if (IE_EID_VENDOR == elem_id)
1359 {
1360 /* skipping the VSIE's which we don't want to include or
1361 * it will be included by existing code
1362 */
1363 if ((memcmp( &ptr[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) != 0 ) &&
1364#ifdef WLAN_FEATURE_WFD
1365 (memcmp( &ptr[2], WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE) != 0) &&
1366#endif
1367 (memcmp( &ptr[2], WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
1368 (memcmp( &ptr[2], BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
1369 (memcmp( &ptr[2], "\x00\x50\xf2\x02", WPA_OUI_TYPE_SIZE) != 0) &&
1370 (memcmp( &ptr[2], WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
1371 (memcmp( &ptr[2], P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE) != 0))
1372 {
1373 ielen = ptr[1] + 2;
1374 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
1375 {
1376 vos_mem_copy(&genie[*total_ielen], ptr, ielen);
1377 *total_ielen += ielen;
1378 }
1379 else
1380 {
1381 hddLog( VOS_TRACE_LEVEL_ERROR,
1382 "IE Length is too big "
1383 "IEs eid=%d elem_len=%d total_ie_lent=%d",
1384 elem_id, elem_len, *total_ielen);
1385 }
1386 }
1387 }
1388
1389 left -= elem_len;
1390 ptr += (elem_len + 2);
1391 }
1392 return;
1393}
1394
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001395#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07001396static int wlan_hdd_cfg80211_update_apies(hdd_adapter_t* pHostapdAdapter,
1397 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001398#else
1399static int wlan_hdd_cfg80211_update_apies(hdd_adapter_t* pHostapdAdapter,
1400 struct cfg80211_beacon_data *params)
1401#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07001402{
1403 v_U8_t *genie;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05301404 v_U8_t total_ielen = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07001405 v_U8_t addIE[1] = {0};
Jeff Johnsone7245742012-09-05 17:12:55 -07001406 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07001407
1408 genie = vos_mem_malloc(MAX_GENIE_LEN);
1409
1410 if(genie == NULL) {
1411
1412 return -ENOMEM;
1413 }
1414
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05301415 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
1416 &total_ielen, WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07001417 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05301418 hddLog(LOGE,
1419 FL("Adding WPS IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05301420 ret = -EINVAL;
1421 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001422 }
1423
1424#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05301425 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
1426 &total_ielen, WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE))
1427 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05301428 hddLog(LOGE,
1429 FL("Adding WFD IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05301430 ret = -EINVAL;
1431 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001432 }
1433#endif
1434
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05301435 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
1436 &total_ielen, P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07001437 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05301438 hddLog(LOGE,
1439 FL("Adding P2P IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05301440 ret = -EINVAL;
1441 goto done;
1442 }
1443
1444 if (WLAN_HDD_SOFTAP == pHostapdAdapter->device_mode)
1445 {
Arif Hussaine7f3ea52013-09-12 21:56:36 -07001446 wlan_hdd_add_hostapd_conf_vsie(pHostapdAdapter, genie, &total_ielen);
Jeff Johnson295189b2012-06-20 16:38:30 -07001447 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001448
1449 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1450 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, genie, total_ielen, NULL,
1451 eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
1452 {
1453 hddLog(LOGE,
1454 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001455 ret = -EINVAL;
1456 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001457 }
1458
1459 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1460 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
1461 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
1462 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
1463 ==eHAL_STATUS_FAILURE)
1464 {
1465 hddLog(LOGE,
1466 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001467 ret = -EINVAL;
1468 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001469 }
1470
1471 // Added for ProResp IE
1472 if ( (params->proberesp_ies != NULL) && (params->proberesp_ies_len != 0) )
1473 {
1474 u16 rem_probe_resp_ie_len = params->proberesp_ies_len;
1475 u8 probe_rsp_ie_len[3] = {0};
1476 u8 counter = 0;
1477 /* Check Probe Resp Length if it is greater then 255 then Store
1478 Probe Resp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1 &
1479 WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are not able
1480 Store More then 255 bytes into One Variable.
1481 */
1482 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
1483 {
1484 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
1485 {
1486 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
1487 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
1488 }
1489 else
1490 {
1491 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
1492 rem_probe_resp_ie_len = 0;
1493 }
1494 }
1495
1496 rem_probe_resp_ie_len = 0;
1497
1498 if (probe_rsp_ie_len[0] > 0)
1499 {
1500 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1501 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
1502 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
1503 probe_rsp_ie_len[0], NULL,
1504 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
1505 {
1506 hddLog(LOGE,
1507 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001508 ret = -EINVAL;
1509 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001510 }
1511 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
1512 }
1513
1514 if (probe_rsp_ie_len[1] > 0)
1515 {
1516 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1517 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
1518 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
1519 probe_rsp_ie_len[1], NULL,
1520 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
1521 {
1522 hddLog(LOGE,
1523 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001524 ret = -EINVAL;
1525 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001526 }
1527 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
1528 }
1529
1530 if (probe_rsp_ie_len[2] > 0)
1531 {
1532 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1533 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
1534 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
1535 probe_rsp_ie_len[2], NULL,
1536 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
1537 {
1538 hddLog(LOGE,
1539 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001540 ret = -EINVAL;
1541 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001542 }
1543 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
1544 }
1545
1546 if (probe_rsp_ie_len[1] == 0 )
1547 {
1548 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1549 WNI_CFG_PROBE_RSP_ADDNIE_DATA2, (tANI_U8*)addIE, 0, NULL,
1550 eANI_BOOLEAN_FALSE) )
1551 {
1552 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08001553 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07001554 }
1555 }
1556
1557 if (probe_rsp_ie_len[2] == 0 )
1558 {
1559 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1560 WNI_CFG_PROBE_RSP_ADDNIE_DATA3, (tANI_U8*)addIE, 0, NULL,
1561 eANI_BOOLEAN_FALSE) )
1562 {
1563 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08001564 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07001565 }
1566 }
1567
1568 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1569 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
1570 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
1571 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
1572 == eHAL_STATUS_FAILURE)
1573 {
1574 hddLog(LOGE,
1575 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001576 ret = -EINVAL;
1577 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001578 }
1579 }
1580 else
1581 {
1582 // Reset WNI_CFG_PROBE_RSP Flags
1583 wlan_hdd_reset_prob_rspies(pHostapdAdapter);
1584
1585 hddLog(VOS_TRACE_LEVEL_INFO,
1586 "%s: No Probe Response IE received in set beacon",
1587 __func__);
1588 }
1589
1590 // Added for AssocResp IE
1591 if ( (params->assocresp_ies != NULL) && (params->assocresp_ies_len != 0) )
1592 {
1593 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1594 WNI_CFG_ASSOC_RSP_ADDNIE_DATA, (tANI_U8*)params->assocresp_ies,
1595 params->assocresp_ies_len, NULL,
1596 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
1597 {
1598 hddLog(LOGE,
1599 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001600 ret = -EINVAL;
1601 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001602 }
1603
1604 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1605 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 1, NULL,
1606 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
1607 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
1608 == eHAL_STATUS_FAILURE)
1609 {
1610 hddLog(LOGE,
1611 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001612 ret = -EINVAL;
1613 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001614 }
1615 }
1616 else
1617 {
1618 hddLog(VOS_TRACE_LEVEL_INFO,
1619 "%s: No Assoc Response IE received in set beacon",
1620 __func__);
1621
1622 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1623 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
1624 eANI_BOOLEAN_FALSE) )
1625 {
1626 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08001627 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07001628 }
1629 }
1630
Jeff Johnsone7245742012-09-05 17:12:55 -07001631done:
Jeff Johnson295189b2012-06-20 16:38:30 -07001632 vos_mem_free(genie);
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05301633 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07001634}
Jeff Johnson295189b2012-06-20 16:38:30 -07001635
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301636/*
Jeff Johnson295189b2012-06-20 16:38:30 -07001637 * FUNCTION: wlan_hdd_validate_operation_channel
1638 * called by wlan_hdd_cfg80211_start_bss() and
1639 * wlan_hdd_cfg80211_set_channel()
1640 * This function validates whether given channel is part of valid
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301641 * channel list.
1642 */
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07001643VOS_STATUS wlan_hdd_validate_operation_channel(hdd_adapter_t *pAdapter,int channel)
Jeff Johnson295189b2012-06-20 16:38:30 -07001644{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301645
Jeff Johnson295189b2012-06-20 16:38:30 -07001646 v_U32_t num_ch = 0;
1647 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN];
1648 u32 indx = 0;
1649 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05301650 v_U8_t fValidChannel = FALSE, count = 0;
1651 hdd_config_t *hdd_pConfig_ini= (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301652
Jeff Johnson295189b2012-06-20 16:38:30 -07001653 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
1654
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05301655 if ( hdd_pConfig_ini->sapAllowAllChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -07001656 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05301657 /* Validate the channel */
1658 for (count = RF_CHAN_1 ; count <= RF_CHAN_165 ; count++)
Jeff Johnson295189b2012-06-20 16:38:30 -07001659 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05301660 if ( channel == rfChannels[count].channelNum )
1661 {
1662 fValidChannel = TRUE;
1663 break;
1664 }
1665 }
1666 if (fValidChannel != TRUE)
1667 {
1668 hddLog(VOS_TRACE_LEVEL_ERROR,
1669 "%s: Invalid Channel [%d]", __func__, channel);
1670 return VOS_STATUS_E_FAILURE;
Jeff Johnson295189b2012-06-20 16:38:30 -07001671 }
1672 }
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05301673 else
Jeff Johnson295189b2012-06-20 16:38:30 -07001674 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05301675 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
1676 valid_ch, &num_ch))
1677 {
1678 hddLog(VOS_TRACE_LEVEL_ERROR,
1679 "%s: failed to get valid channel list", __func__);
1680 return VOS_STATUS_E_FAILURE;
1681 }
1682 for (indx = 0; indx < num_ch; indx++)
1683 {
1684 if (channel == valid_ch[indx])
1685 {
1686 break;
1687 }
1688 }
1689
1690 if (indx >= num_ch)
1691 {
1692 hddLog(VOS_TRACE_LEVEL_ERROR,
1693 "%s: Invalid Channel [%d]", __func__, channel);
1694 return VOS_STATUS_E_FAILURE;
1695 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001696 }
1697 return VOS_STATUS_SUCCESS;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301698
Jeff Johnson295189b2012-06-20 16:38:30 -07001699}
1700
Viral Modi3a32cc52013-02-08 11:14:52 -08001701/**
1702 * FUNCTION: wlan_hdd_cfg80211_set_channel
1703 * This function is used to set the channel number
1704 */
1705static int wlan_hdd_cfg80211_set_channel( struct wiphy *wiphy, struct net_device *dev,
1706 struct ieee80211_channel *chan,
1707 enum nl80211_channel_type channel_type
1708 )
1709{
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05301710 hdd_adapter_t *pAdapter = NULL;
Viral Modi3a32cc52013-02-08 11:14:52 -08001711 v_U32_t num_ch = 0;
Jeff Johnson4416a782013-03-25 14:17:50 -07001712 int channel = 0;
Viral Modi3a32cc52013-02-08 11:14:52 -08001713 int freq = chan->center_freq; /* freq is in MHZ */
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05301714 hdd_context_t *pHddCtx;
1715 int status;
Viral Modi3a32cc52013-02-08 11:14:52 -08001716
1717 ENTER();
1718
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05301719
Viral Modi3a32cc52013-02-08 11:14:52 -08001720 if( NULL == dev )
1721 {
1722 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08001723 "%s: Called with dev = NULL.", __func__);
Viral Modi3a32cc52013-02-08 11:14:52 -08001724 return -ENODEV;
1725 }
1726 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
1727
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05301728 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
1729 TRACE_CODE_HDD_CFG80211_SET_CHANNEL, pAdapter->sessionId,
1730 channel_type ));
Viral Modi3a32cc52013-02-08 11:14:52 -08001731 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -08001732 "%s: device_mode = %d freq = %d", __func__,
Viral Modi3a32cc52013-02-08 11:14:52 -08001733 pAdapter->device_mode, chan->center_freq);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05301734
1735 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1736 status = wlan_hdd_validate_context(pHddCtx);
1737
1738 if (0 != status)
Viral Modi3a32cc52013-02-08 11:14:52 -08001739 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05301740 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1741 "%s: HDD context is not valid", __func__);
1742 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -08001743 }
1744
1745 /*
1746 * Do freq to chan conversion
1747 * TODO: for 11a
1748 */
1749
1750 channel = ieee80211_frequency_to_channel(freq);
1751
1752 /* Check freq range */
1753 if ((WNI_CFG_CURRENT_CHANNEL_STAMIN > channel) ||
1754 (WNI_CFG_CURRENT_CHANNEL_STAMAX < channel))
1755 {
1756 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08001757 "%s: Channel [%d] is outside valid range from %d to %d",
Viral Modi3a32cc52013-02-08 11:14:52 -08001758 __func__, channel, WNI_CFG_CURRENT_CHANNEL_STAMIN,
1759 WNI_CFG_CURRENT_CHANNEL_STAMAX);
1760 return -EINVAL;
1761 }
1762
1763 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
1764
Gopichand Nakkala6ab19562013-03-07 13:59:42 +05301765 if ((WLAN_HDD_SOFTAP != pAdapter->device_mode) &&
1766 (WLAN_HDD_P2P_GO != pAdapter->device_mode))
Viral Modi3a32cc52013-02-08 11:14:52 -08001767 {
1768 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pAdapter,channel))
1769 {
1770 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08001771 "%s: Invalid Channel [%d]", __func__, channel);
Viral Modi3a32cc52013-02-08 11:14:52 -08001772 return -EINVAL;
1773 }
1774 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
1775 "%s: set channel to [%d] for device mode =%d",
1776 __func__, channel,pAdapter->device_mode);
1777 }
1778 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Viral Modi3a32cc52013-02-08 11:14:52 -08001779 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Viral Modi3a32cc52013-02-08 11:14:52 -08001780 )
1781 {
1782 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
1783 tCsrRoamProfile * pRoamProfile = &pWextState->roamProfile;
1784 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
1785
1786 if (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState)
1787 {
1788 /* Link is up then return cant set channel*/
1789 hddLog( VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08001790 "%s: IBSS Associated, can't set the channel", __func__);
Viral Modi3a32cc52013-02-08 11:14:52 -08001791 return -EINVAL;
1792 }
1793
1794 num_ch = pRoamProfile->ChannelInfo.numOfChannels = 1;
1795 pHddStaCtx->conn_info.operationChannel = channel;
1796 pRoamProfile->ChannelInfo.ChannelList =
1797 &pHddStaCtx->conn_info.operationChannel;
1798 }
1799 else if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Viral Modi3a32cc52013-02-08 11:14:52 -08001800 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Viral Modi3a32cc52013-02-08 11:14:52 -08001801 )
1802 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05301803 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
1804 {
1805 if(VOS_STATUS_SUCCESS !=
1806 wlan_hdd_validate_operation_channel(pAdapter,channel))
1807 {
1808 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08001809 "%s: Invalid Channel [%d]", __func__, channel);
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05301810 return -EINVAL;
1811 }
1812 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
1813 }
1814 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
Viral Modi3a32cc52013-02-08 11:14:52 -08001815 {
1816 hdd_config_t *cfg_param = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
1817
1818 /* If auto channel selection is configured as enable/ 1 then ignore
1819 channel set by supplicant
1820 */
1821 if ( cfg_param->apAutoChannelSelection )
1822 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05301823 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel =
1824 AUTO_CHANNEL_SELECT;
Viral Modi3a32cc52013-02-08 11:14:52 -08001825 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
1826 "%s: set channel to auto channel (0) for device mode =%d",
1827 __func__, pAdapter->device_mode);
1828 }
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05301829 else
1830 {
1831 if(VOS_STATUS_SUCCESS !=
1832 wlan_hdd_validate_operation_channel(pAdapter,channel))
1833 {
1834 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08001835 "%s: Invalid Channel [%d]", __func__, channel);
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05301836 return -EINVAL;
1837 }
1838 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
1839 }
Viral Modi3a32cc52013-02-08 11:14:52 -08001840 }
1841 }
1842 else
1843 {
1844 hddLog(VOS_TRACE_LEVEL_FATAL,
1845 "%s: Invalid device mode failed to set valid channel", __func__);
1846 return -EINVAL;
1847 }
1848 EXIT();
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05301849 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -08001850}
1851
Jeff Johnson295189b2012-06-20 16:38:30 -07001852#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
1853static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
1854 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001855#else
1856static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
1857 struct cfg80211_beacon_data *params,
1858 const u8 *ssid, size_t ssid_len,
1859 enum nl80211_hidden_ssid hidden_ssid)
1860#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07001861{
1862 tsap_Config_t *pConfig;
1863 beacon_data_t *pBeacon = NULL;
1864 struct ieee80211_mgmt *pMgmt_frame;
1865 v_U8_t *pIe=NULL;
1866 v_U16_t capab_info;
1867 eCsrAuthType RSNAuthType;
1868 eCsrEncryptionType RSNEncryptType;
1869 eCsrEncryptionType mcRSNEncryptType;
1870 int status = VOS_STATUS_SUCCESS;
1871 tpWLAN_SAPEventCB pSapEventCallback;
1872 hdd_hostapd_state_t *pHostapdState;
1873 v_U8_t wpaRsnIEdata[(SIR_MAC_MAX_IE_LENGTH * 2)+4]; //Max ie length 255 * 2(WPA+RSN) + 2 bytes (vendor specific ID) * 2
1874 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05301875 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07001876 struct qc_mac_acl_entry *acl_entry = NULL;
1877 v_SINT_t i;
Madan Mohan Koyyalamudi543172b2012-12-05 16:40:18 -08001878 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
Chet Lanctot8cecea22014-02-11 19:09:36 -08001879 v_BOOL_t MFPCapable;
1880 v_BOOL_t MFPRequired;
Abhishek Singhf0ac1752014-03-05 17:47:09 +05301881 eHddDot11Mode sapDot11Mode =
1882 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->sapDot11Mode;
Jeff Johnson295189b2012-06-20 16:38:30 -07001883
1884 ENTER();
1885
1886 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter);
1887
1888 pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
1889
1890 pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
1891
1892 pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
1893
1894 pConfig->beacon_int = pMgmt_frame->u.beacon.beacon_int;
1895
1896 //channel is already set in the set_channel Call back
1897 //pConfig->channel = pCommitConfig->channel;
1898
1899 /*Protection parameter to enable or disable*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301900 pConfig->protEnabled =
Jeff Johnson295189b2012-06-20 16:38:30 -07001901 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtEnabled;
1902
1903 pConfig->dtim_period = pBeacon->dtim_period;
1904
Arif Hussain6d2a3322013-11-17 19:50:10 -08001905 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"****pConfig->dtim_period=%d***",
Jeff Johnson295189b2012-06-20 16:38:30 -07001906 pConfig->dtim_period);
1907
1908
Madan Mohan Koyyalamudie0ca11f2012-11-27 15:57:52 -08001909 if (pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson32d95a32012-09-10 13:15:23 -07001910 {
1911 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -07001912 WLAN_EID_COUNTRY);
Kiet Lam083504c2013-11-25 14:17:45 +05301913 if(memcmp(pHddCtx->cfg_ini->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0)
1914 {
1915 tANI_BOOLEAN restartNeeded;
1916 pConfig->ieee80211d = 1;
1917 vos_mem_copy(pConfig->countryCode, pHddCtx->cfg_ini->apCntryCode, 3);
1918 sme_setRegInfo(hHal, pConfig->countryCode);
1919 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
1920 }
1921 else if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07001922 {
Jeff Johnson32d95a32012-09-10 13:15:23 -07001923 tANI_BOOLEAN restartNeeded;
Jeff Johnson32d95a32012-09-10 13:15:23 -07001924 pConfig->ieee80211d = 1;
1925 vos_mem_copy(pConfig->countryCode, &pIe[2], 3);
1926 sme_setRegInfo(hHal, pConfig->countryCode);
1927 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
Jeff Johnson295189b2012-06-20 16:38:30 -07001928 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07001929 else
1930 {
1931 pConfig->ieee80211d = 0;
1932 }
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05301933 /*
1934 * If auto channel is configured i.e. channel is 0,
1935 * so skip channel validation.
1936 */
1937 if( AUTO_CHANNEL_SELECT != pConfig->channel )
1938 {
1939 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pHostapdAdapter,pConfig->channel))
1940 {
1941 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08001942 "%s: Invalid Channel [%d]", __func__, pConfig->channel);
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05301943 return -EINVAL;
1944 }
1945 }
1946 else
1947 {
1948 if(1 != pHddCtx->is_dynamic_channel_range_set)
1949 {
1950 hdd_config_t *hdd_pConfig= (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini;
1951 WLANSAP_SetChannelRange(hHal, hdd_pConfig->apStartChannelNum,
1952 hdd_pConfig->apEndChannelNum,hdd_pConfig->apOperatingBand);
1953 }
1954 pHddCtx->is_dynamic_channel_range_set = 0;
1955 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001956 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07001957 else
Jeff Johnson295189b2012-06-20 16:38:30 -07001958 {
1959 pConfig->ieee80211d = 0;
1960 }
1961 pConfig->authType = eSAP_AUTO_SWITCH;
1962
1963 capab_info = pMgmt_frame->u.beacon.capab_info;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301964
1965 pConfig->privacy = (pMgmt_frame->u.beacon.capab_info &
Jeff Johnson295189b2012-06-20 16:38:30 -07001966 WLAN_CAPABILITY_PRIVACY) ? VOS_TRUE : VOS_FALSE;
1967
1968 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uPrivacy = pConfig->privacy;
1969
1970 /*Set wps station to configured*/
1971 pIe = wlan_hdd_get_wps_ie_ptr(pBeacon->tail, pBeacon->tail_len);
1972
1973 if(pIe)
1974 {
1975 if(pIe[1] < (2 + WPS_OUI_TYPE_SIZE))
1976 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08001977 hddLog( VOS_TRACE_LEVEL_ERROR, "**Wps Ie Length is too small***");
Jeff Johnson295189b2012-06-20 16:38:30 -07001978 return -EINVAL;
1979 }
1980 else if(memcmp(&pIe[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) == 0)
1981 {
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07001982 hddLog( VOS_TRACE_LEVEL_INFO, "** WPS IE(len %d) ***", (pIe[1]+2));
Jeff Johnson295189b2012-06-20 16:38:30 -07001983 /* Check 15 bit of WPS IE as it contain information for wps state
1984 * WPS state
1985 */
1986 if(SAP_WPS_ENABLED_UNCONFIGURED == pIe[15])
1987 {
1988 pConfig->wps_state = SAP_WPS_ENABLED_UNCONFIGURED;
1989 } else if(SAP_WPS_ENABLED_CONFIGURED == pIe[15])
1990 {
1991 pConfig->wps_state = SAP_WPS_ENABLED_CONFIGURED;
1992 }
1993 }
1994 }
1995 else
1996 {
1997 pConfig->wps_state = SAP_WPS_DISABLED;
1998 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301999 pConfig->fwdWPSPBCProbeReq = 1; // Forward WPS PBC probe request frame up
Jeff Johnson295189b2012-06-20 16:38:30 -07002000
2001 pConfig->RSNWPAReqIELength = 0;
2002 pConfig->pRSNWPAReqIE = NULL;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302003 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -07002004 WLAN_EID_RSN);
2005 if(pIe && pIe[1])
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302006 {
Jeff Johnson295189b2012-06-20 16:38:30 -07002007 pConfig->RSNWPAReqIELength = pIe[1] + 2;
2008 memcpy(&wpaRsnIEdata[0], pIe, pConfig->RSNWPAReqIELength);
2009 pConfig->pRSNWPAReqIE = &wpaRsnIEdata[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302010 /* The actual processing may eventually be more extensive than
2011 * this. Right now, just consume any PMKIDs that are sent in
Jeff Johnson295189b2012-06-20 16:38:30 -07002012 * by the app.
2013 * */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302014 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -07002015 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
2016 &RSNEncryptType,
2017 &mcRSNEncryptType,
2018 &RSNAuthType,
Chet Lanctot8cecea22014-02-11 19:09:36 -08002019 &MFPCapable,
2020 &MFPRequired,
Jeff Johnson295189b2012-06-20 16:38:30 -07002021 pConfig->pRSNWPAReqIE[1]+2,
2022 pConfig->pRSNWPAReqIE );
2023
2024 if( VOS_STATUS_SUCCESS == status )
2025 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302026 /* Now copy over all the security attributes you have
2027 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -07002028 * */
2029 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
2030 pConfig->mcRSNEncryptType = mcRSNEncryptType;
2031 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
2032 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05302033 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -08002034 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -07002035 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
2036 }
2037 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302038
Jeff Johnson295189b2012-06-20 16:38:30 -07002039 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE,
2040 pBeacon->tail, pBeacon->tail_len);
2041
2042 if(pIe && pIe[1] && (pIe[0] == DOT11F_EID_WPA))
2043 {
2044 if (pConfig->pRSNWPAReqIE)
2045 {
2046 /*Mixed mode WPA/WPA2*/
2047 memcpy((&wpaRsnIEdata[0] + pConfig->RSNWPAReqIELength), pIe, pIe[1] + 2);
2048 pConfig->RSNWPAReqIELength += pIe[1] + 2;
2049 }
2050 else
2051 {
2052 pConfig->RSNWPAReqIELength = pIe[1] + 2;
2053 memcpy(&wpaRsnIEdata[0], pIe, pConfig->RSNWPAReqIELength);
2054 pConfig->pRSNWPAReqIE = &wpaRsnIEdata[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302055 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -07002056 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
2057 &RSNEncryptType,
2058 &mcRSNEncryptType,
2059 &RSNAuthType,
Chet Lanctot8cecea22014-02-11 19:09:36 -08002060 &MFPCapable,
2061 &MFPRequired,
Jeff Johnson295189b2012-06-20 16:38:30 -07002062 pConfig->pRSNWPAReqIE[1]+2,
2063 pConfig->pRSNWPAReqIE );
2064
2065 if( VOS_STATUS_SUCCESS == status )
2066 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302067 /* Now copy over all the security attributes you have
2068 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -07002069 * */
2070 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
2071 pConfig->mcRSNEncryptType = mcRSNEncryptType;
2072 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
2073 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05302074 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -08002075 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -07002076 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
2077 }
2078 }
2079 }
2080
Jeff Johnson4416a782013-03-25 14:17:50 -07002081 if (pConfig->RSNWPAReqIELength > sizeof wpaRsnIEdata) {
2082 hddLog( VOS_TRACE_LEVEL_ERROR, "**RSNWPAReqIELength is too large***");
2083 return -EINVAL;
2084 }
2085
Jeff Johnson295189b2012-06-20 16:38:30 -07002086 pConfig->SSIDinfo.ssidHidden = VOS_FALSE;
2087
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002088#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07002089 if (params->ssid != NULL)
2090 {
2091 memcpy(pConfig->SSIDinfo.ssid.ssId, params->ssid, params->ssid_len);
2092 pConfig->SSIDinfo.ssid.length = params->ssid_len;
2093 if (params->hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
2094 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
2095 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002096#else
2097 if (ssid != NULL)
2098 {
2099 memcpy(pConfig->SSIDinfo.ssid.ssId, ssid, ssid_len);
2100 pConfig->SSIDinfo.ssid.length = ssid_len;
2101 if (hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
2102 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
2103 }
2104#endif
2105
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302106 vos_mem_copy(pConfig->self_macaddr.bytes,
Jeff Johnson295189b2012-06-20 16:38:30 -07002107 pHostapdAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302108
Jeff Johnson295189b2012-06-20 16:38:30 -07002109 /* default value */
2110 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
2111 pConfig->num_accept_mac = 0;
2112 pConfig->num_deny_mac = 0;
2113
2114 pIe = wlan_hdd_get_vendor_oui_ie_ptr(BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
2115 pBeacon->tail, pBeacon->tail_len);
2116
2117 /* pIe for black list is following form:
2118 type : 1 byte
2119 length : 1 byte
2120 OUI : 4 bytes
2121 acl type : 1 byte
2122 no of mac addr in black list: 1 byte
2123 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302124 */
2125 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07002126 {
2127 pConfig->SapMacaddr_acl = pIe[6];
2128 pConfig->num_deny_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -08002129 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no deny mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07002130 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05302131 if (pConfig->num_deny_mac > MAX_ACL_MAC_ADDRESS)
2132 pConfig->num_deny_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07002133 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
2134 for (i = 0; i < pConfig->num_deny_mac; i++)
2135 {
2136 vos_mem_copy(&pConfig->deny_mac[i], acl_entry->addr, sizeof(qcmacaddr));
2137 acl_entry++;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302138 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002139 }
2140 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
2141 pBeacon->tail, pBeacon->tail_len);
2142
2143 /* pIe for white list is following form:
2144 type : 1 byte
2145 length : 1 byte
2146 OUI : 4 bytes
2147 acl type : 1 byte
2148 no of mac addr in white list: 1 byte
2149 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302150 */
2151 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07002152 {
2153 pConfig->SapMacaddr_acl = pIe[6];
2154 pConfig->num_accept_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -08002155 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no accept mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07002156 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05302157 if (pConfig->num_accept_mac > MAX_ACL_MAC_ADDRESS)
2158 pConfig->num_accept_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07002159 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
2160 for (i = 0; i < pConfig->num_accept_mac; i++)
2161 {
2162 vos_mem_copy(&pConfig->accept_mac[i], acl_entry->addr, sizeof(qcmacaddr));
2163 acl_entry++;
2164 }
2165 }
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05302166
Jeff Johnson295189b2012-06-20 16:38:30 -07002167 wlan_hdd_set_sapHwmode(pHostapdAdapter);
2168
Jeff Johnsone7245742012-09-05 17:12:55 -07002169#ifdef WLAN_FEATURE_11AC
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -08002170 /* Overwrite the hostapd setting for HW mode only for 11ac.
Kiet Lam0f320422013-11-21 19:29:17 +05302171 * This is valid only if mode is set to 11n in hostapd, either AUTO or
2172 * 11ac in .ini and 11ac is supported by both host and firmware.
2173 * Otherwise, leave whatever is set in hostapd (a OR b OR g OR n mode)
2174 */
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -08002175 if( ((pConfig->SapHw_mode == eSAP_DOT11_MODE_11n) ||
2176 (pConfig->SapHw_mode == eSAP_DOT11_MODE_11n_ONLY)) &&
Abhishek Singhf0ac1752014-03-05 17:47:09 +05302177 (( sapDot11Mode == eHDD_DOT11_MODE_AUTO ) ||
2178 ( sapDot11Mode == eHDD_DOT11_MODE_11ac ) ||
2179 ( sapDot11Mode == eHDD_DOT11_MODE_11ac_ONLY ) ) &&
2180 (sme_IsFeatureSupportedByDriver(DOT11AC)) &&
2181 (sme_IsFeatureSupportedByFW(DOT11AC)) )
Jeff Johnsone7245742012-09-05 17:12:55 -07002182 {
2183 pConfig->SapHw_mode = eSAP_DOT11_MODE_11ac;
Ravi Joshi83bfaa12013-05-28 22:12:08 -07002184
2185 /* Disable VHT support in 2.4 GHz band */
2186 if (pConfig->channel <= 14 &&
2187 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->enableVhtFor24GHzBand == FALSE)
2188 {
2189 pConfig->SapHw_mode = eSAP_DOT11_MODE_11n;
2190 }
Jeff Johnsone7245742012-09-05 17:12:55 -07002191 }
2192#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302193
Ravi Joshiaeb7d9e2013-05-02 12:28:14 -07002194 if ( AUTO_CHANNEL_SELECT != pConfig->channel )
2195 {
2196 sme_SelectCBMode(hHal,
2197 sapConvertSapPhyModeToCsrPhyMode(pConfig->SapHw_mode),
2198 pConfig->channel);
2199 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002200 // ht_capab is not what the name conveys,this is used for protection bitmap
2201 pConfig->ht_capab =
2202 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtection;
2203
2204 if ( 0 != wlan_hdd_cfg80211_update_apies(pHostapdAdapter, params) )
2205 {
2206 hddLog(LOGE, FL("SAP Not able to set AP IEs"));
2207 return -EINVAL;
2208 }
2209
2210 //Uapsd Enabled Bit
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302211 pConfig->UapsdEnable =
Jeff Johnson295189b2012-06-20 16:38:30 -07002212 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apUapsdEnabled;
2213 //Enable OBSS protection
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302214 pConfig->obssProtEnabled =
2215 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apOBSSProtEnabled;
Jeff Johnson295189b2012-06-20 16:38:30 -07002216
Chet Lanctot8cecea22014-02-11 19:09:36 -08002217#ifdef WLAN_FEATURE_11W
2218 pConfig->mfpCapable = MFPCapable;
2219 pConfig->mfpRequired = MFPRequired;
2220 hddLog(LOGW, FL("Soft AP MFP capable %d, MFP required %d\n"),
2221 pConfig->mfpCapable, pConfig->mfpRequired);
2222#endif
2223
Arif Hussain6d2a3322013-11-17 19:50:10 -08002224 hddLog(LOGW, FL("SOftAP macaddress : "MAC_ADDRESS_STR),
Jeff Johnson295189b2012-06-20 16:38:30 -07002225 MAC_ADDR_ARRAY(pHostapdAdapter->macAddressCurrent.bytes));
Arif Hussain6d2a3322013-11-17 19:50:10 -08002226 hddLog(LOGW,FL("ssid =%s, beaconint=%d, channel=%d"),
2227 pConfig->SSIDinfo.ssid.ssId, (int)pConfig->beacon_int,
2228 (int)pConfig->channel);
2229 hddLog(LOGW,FL("hw_mode=%x, privacy=%d, authType=%d"),
2230 pConfig->SapHw_mode, pConfig->privacy,
2231 pConfig->authType);
2232 hddLog(LOGW,FL("RSN/WPALen=%d, Uapsd = %d"),
2233 (int)pConfig->RSNWPAReqIELength, pConfig->UapsdEnable);
2234 hddLog(LOGW,FL("ProtEnabled = %d, OBSSProtEnabled = %d"),
2235 pConfig->protEnabled, pConfig->obssProtEnabled);
Jeff Johnson295189b2012-06-20 16:38:30 -07002236
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302237 if(test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -07002238 {
2239 //Bss already started. just return.
2240 //TODO Probably it should update some beacon params.
2241 hddLog( LOGE, "Bss Already started...Ignore the request");
2242 EXIT();
2243 return 0;
2244 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302245
Jeff Johnson295189b2012-06-20 16:38:30 -07002246 pConfig->persona = pHostapdAdapter->device_mode;
2247
2248 pSapEventCallback = hdd_hostapd_SAPEventCB;
2249 if(WLANSAP_StartBss(pVosContext, pSapEventCallback, pConfig,
2250 (v_PVOID_t)pHostapdAdapter->dev) != VOS_STATUS_SUCCESS)
2251 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08002252 hddLog(LOGE,FL("SAP Start Bss fail"));
Jeff Johnson295189b2012-06-20 16:38:30 -07002253 return -EINVAL;
2254 }
2255
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302256 hddLog(LOG1,
Jeff Johnson295189b2012-06-20 16:38:30 -07002257 FL("Waiting for Scan to complete(auto mode) and BSS to start"));
2258
2259 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302260
Jeff Johnson295189b2012-06-20 16:38:30 -07002261 if (!VOS_IS_STATUS_SUCCESS(status))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302262 {
2263 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08002264 ("ERROR: HDD vos wait for single_event failed!!"));
Tushnim Bhattacharyyaad37df12013-10-02 12:01:33 -07002265 smeGetCommandQStatus(hHal);
Jeff Johnson295189b2012-06-20 16:38:30 -07002266 VOS_ASSERT(0);
2267 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302268
Jeff Johnson295189b2012-06-20 16:38:30 -07002269 set_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags);
2270
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07002271#ifdef WLAN_FEATURE_P2P_DEBUG
2272 if (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO)
2273 {
2274 if(globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED)
2275 {
2276 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
2277 hddLog(LOGE,"[P2P State] From Go nego completed to "
Jeff Johnson1250df42012-12-10 14:31:52 -08002278 "Non-autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07002279 }
2280 else if(globalP2PConnectionStatus == P2P_NOT_ACTIVE)
2281 {
2282 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
2283 hddLog(LOGE,"[P2P State] From Inactive to "
Jeff Johnson1250df42012-12-10 14:31:52 -08002284 "Autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07002285 }
2286 }
2287#endif
2288
Jeff Johnson295189b2012-06-20 16:38:30 -07002289 pHostapdState->bCommit = TRUE;
2290 EXIT();
2291
2292 return 0;
2293}
2294
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002295#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302296static int wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy,
2297 struct net_device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -07002298 struct beacon_parameters *params)
2299{
2300 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302301 hdd_context_t *pHddCtx;
2302 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07002303
2304 ENTER();
2305
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302306 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2307 TRACE_CODE_HDD_CFG80211_ADD_BEACON,
2308 pAdapter->sessionId, params->interval));
Arif Hussain6d2a3322013-11-17 19:50:10 -08002309 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "device mode=%d",pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07002310
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302311 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2312 status = wlan_hdd_validate_context(pHddCtx);
2313
2314 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002315 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302316 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2317 "%s: HDD context is not valid", __func__);
2318 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002319 }
2320
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302321 if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07002322 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07002323 )
2324 {
2325 beacon_data_t *old,*new;
2326
2327 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302328
Jeff Johnson295189b2012-06-20 16:38:30 -07002329 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302330 {
2331 hddLog(VOS_TRACE_LEVEL_WARN,
2332 FL("already beacon info added to session(%d)"),
2333 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07002334 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302335 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002336
2337 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
2338
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302339 if(status != VOS_STATUS_SUCCESS)
Jeff Johnson295189b2012-06-20 16:38:30 -07002340 {
2341 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08002342 "%s:Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002343 return -EINVAL;
2344 }
2345
2346 pAdapter->sessionCtx.ap.beacon = new;
2347
2348 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
2349 }
2350
2351 EXIT();
2352 return status;
2353}
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302354
2355static int wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07002356 struct net_device *dev,
2357 struct beacon_parameters *params)
2358{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302359 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302360 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302361 hdd_context_t *pHddCtx;
2362 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07002363
2364 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302365 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2366 TRACE_CODE_HDD_CFG80211_SET_BEACON,
2367 pAdapter->sessionId, pHddStaCtx->conn_info.authType));
Arif Hussain6d2a3322013-11-17 19:50:10 -08002368 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07002369 __func__,pAdapter->device_mode);
2370
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302371 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2372 status = wlan_hdd_validate_context(pHddCtx);
2373
2374 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002375 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302376 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2377 "%s: HDD context is not valid", __func__);
2378 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002379 }
2380
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302381 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07002382 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302383 )
Jeff Johnson295189b2012-06-20 16:38:30 -07002384 {
2385 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302386
Jeff Johnson295189b2012-06-20 16:38:30 -07002387 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302388
Jeff Johnson295189b2012-06-20 16:38:30 -07002389 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302390 {
2391 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2392 FL("session(%d) old and new heads points to NULL"),
2393 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07002394 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302395 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002396
2397 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
2398
2399 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302400 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08002401 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002402 return -EINVAL;
2403 }
2404
2405 pAdapter->sessionCtx.ap.beacon = new;
2406
2407 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
2408 }
2409
2410 EXIT();
2411 return status;
2412}
2413
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002414#endif //(LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
2415
2416#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07002417static int wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy,
2418 struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002419#else
2420static int wlan_hdd_cfg80211_stop_ap (struct wiphy *wiphy,
2421 struct net_device *dev)
2422#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07002423{
2424 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnsone7245742012-09-05 17:12:55 -07002425 hdd_context_t *pHddCtx = NULL;
2426 hdd_scaninfo_t *pScanInfo = NULL;
2427 hdd_adapter_t *staAdapter = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302428 VOS_STATUS status;
Jeff Johnson295189b2012-06-20 16:38:30 -07002429
2430 ENTER();
2431
2432 if (NULL == pAdapter)
2433 {
2434 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002435 "%s: HDD adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002436 return -ENODEV;
2437 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07002438
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302439 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2440 TRACE_CODE_HDD_CFG80211_STOP_AP,
2441 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302442 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2443 status = wlan_hdd_validate_context(pHddCtx);
2444
2445 if (0 != status)
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07002446 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302447 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2448 "%s: HDD context is not valid", __func__);
2449 return status;
Jeff Johnson4416a782013-03-25 14:17:50 -07002450 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07002451
2452 staAdapter = hdd_get_adapter(pAdapter->pHddCtx, WLAN_HDD_INFRA_STATION);
2453 if (NULL == staAdapter)
2454 {
2455 staAdapter = hdd_get_adapter(pAdapter->pHddCtx, WLAN_HDD_P2P_CLIENT);
2456 if (NULL == staAdapter)
2457 {
Rajesh Chauhan52d885b2013-11-01 10:54:25 -07002458 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
2459 "%s: HDD adapter context for STA/P2P-CLI is Null",
2460 __func__);
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07002461 }
2462 }
2463
2464 pScanInfo = &pHddCtx->scan_info;
2465
Arif Hussain6d2a3322013-11-17 19:50:10 -08002466 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07002467 __func__,pAdapter->device_mode);
2468
Rajesh Chauhan52d885b2013-11-01 10:54:25 -07002469 if ((pScanInfo != NULL) && pScanInfo->mScanPending && staAdapter)
Jeff Johnsone7245742012-09-05 17:12:55 -07002470 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302471 long ret;
2472
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -08002473 INIT_COMPLETION(pScanInfo->abortscan_event_var);
Srinivas, Dasari138af4f2014-02-07 11:13:45 +05302474 hdd_abort_mac_scan(staAdapter->pHddCtx, pAdapter->sessionId,
2475 eCSR_SCAN_ABORT_DEFAULT);
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302476 ret = wait_for_completion_interruptible_timeout(
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -08002477 &pScanInfo->abortscan_event_var,
Jeff Johnsone7245742012-09-05 17:12:55 -07002478 msecs_to_jiffies(WLAN_WAIT_TIME_ABORTSCAN));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302479 if (ret <= 0)
Jeff Johnsone7245742012-09-05 17:12:55 -07002480 {
Rajesh Chauhan52d885b2013-11-01 10:54:25 -07002481 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302482 FL("Timeout occurred while waiting for abortscan %ld"),
2483 ret);
Yue Ma4f55ef32014-01-23 16:45:33 -08002484
2485 if (pHddCtx->isLogpInProgress)
2486 {
2487 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2488 "%s: LOGP in Progress. Ignore!!!", __func__);
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302489
2490 VOS_ASSERT(pScanInfo->mScanPending);
Yue Ma4f55ef32014-01-23 16:45:33 -08002491 return -EAGAIN;
2492 }
Jeff Johnsone7245742012-09-05 17:12:55 -07002493 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -07002494 }
2495 }
2496
Arun Kumar Khandavallia3bd8002014-01-17 16:21:19 +05302497 hdd_hostapd_stop(dev);
2498
Jeff Johnson295189b2012-06-20 16:38:30 -07002499 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07002500 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07002501 )
2502 {
2503 beacon_data_t *old;
2504
2505 old = pAdapter->sessionCtx.ap.beacon;
2506
2507 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302508 {
2509 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2510 FL("session(%d) beacon data points to NULL"),
2511 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07002512 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302513 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002514
Jeff Johnson295189b2012-06-20 16:38:30 -07002515 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07002516
2517 mutex_lock(&pHddCtx->sap_lock);
2518 if(test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
2519 {
Jeff Johnson4416a782013-03-25 14:17:50 -07002520 if ( VOS_STATUS_SUCCESS == (status = WLANSAP_StopBss(pHddCtx->pvosContext) ) )
Jeff Johnson295189b2012-06-20 16:38:30 -07002521 {
2522 hdd_hostapd_state_t *pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
2523
2524 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
2525
2526 if (!VOS_IS_STATUS_SUCCESS(status))
2527 {
2528 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08002529 ("ERROR: HDD vos wait for single_event failed!!"));
Jeff Johnson295189b2012-06-20 16:38:30 -07002530 VOS_ASSERT(0);
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302531 }
2532 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002533 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
2534 }
2535 mutex_unlock(&pHddCtx->sap_lock);
2536
2537 if(status != VOS_STATUS_SUCCESS)
2538 {
2539 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08002540 "%s:Error!!! Stopping the BSS",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002541 return -EINVAL;
2542 }
2543
Jeff Johnson4416a782013-03-25 14:17:50 -07002544 if (ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -07002545 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 0,NULL, eANI_BOOLEAN_FALSE)
2546 ==eHAL_STATUS_FAILURE)
2547 {
2548 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08002549 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07002550 }
2551
Jeff Johnson4416a782013-03-25 14:17:50 -07002552 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -07002553 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
2554 eANI_BOOLEAN_FALSE) )
2555 {
2556 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08002557 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07002558 }
2559
2560 // Reset WNI_CFG_PROBE_RSP Flags
2561 wlan_hdd_reset_prob_rspies(pAdapter);
2562
2563 pAdapter->sessionCtx.ap.beacon = NULL;
2564 kfree(old);
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07002565#ifdef WLAN_FEATURE_P2P_DEBUG
2566 if((pAdapter->device_mode == WLAN_HDD_P2P_GO) &&
2567 (globalP2PConnectionStatus == P2P_GO_COMPLETED_STATE))
2568 {
2569 hddLog(LOGE,"[P2P State] From GO completed to Inactive state "
2570 "GO got removed");
2571 globalP2PConnectionStatus = P2P_NOT_ACTIVE;
2572 }
2573#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07002574 }
2575 EXIT();
2576 return status;
2577}
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002578
2579#if (LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
2580
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302581static int wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
2582 struct net_device *dev,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002583 struct cfg80211_ap_settings *params)
2584{
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302585 hdd_adapter_t *pAdapter;
2586 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302587 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002588
2589 ENTER();
2590
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302591 if (NULL == dev)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07002592 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302593 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302594 "%s: Device is Null", __func__);
2595 return -ENODEV;
2596 }
2597
2598 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2599 if (NULL == pAdapter)
2600 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302601 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302602 "%s: HDD adapter is Null", __func__);
2603 return -ENODEV;
2604 }
2605
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302606 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2607 TRACE_CODE_HDD_CFG80211_START_AP, pAdapter->sessionId,
2608 params-> beacon_interval));
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302609 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
2610 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302611 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302612 "%s: HDD adapter magic is invalid", __func__);
2613 return -ENODEV;
2614 }
2615
2616 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302617 status = wlan_hdd_validate_context(pHddCtx);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302618
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302619 if (0 != status)
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302620 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302621 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2622 "%s: HDD context is not valid", __func__);
2623 return status;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302624 }
2625
2626 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device mode = %d",
2627 __func__, pAdapter->device_mode);
2628
2629 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002630 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002631 )
2632 {
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302633 beacon_data_t *old, *new;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002634
2635 old = pAdapter->sessionCtx.ap.beacon;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302636
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002637 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302638 {
2639 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
2640 FL("already beacon info added to session(%d)"),
2641 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002642 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302643 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002644
2645 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter, &new, &params->beacon, params->dtim_period);
2646
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302647 if (status != 0)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002648 {
2649 hddLog(VOS_TRACE_LEVEL_FATAL,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302650 "%s:Error!!! Allocating the new beacon", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002651 return -EINVAL;
2652 }
2653 pAdapter->sessionCtx.ap.beacon = new;
Viral Modi3a32cc52013-02-08 11:14:52 -08002654#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
Yue Maf49ba872013-08-19 12:04:25 -07002655 wlan_hdd_cfg80211_set_channel(wiphy, dev,
2656#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
2657 params->channel, params->channel_type);
2658#else
2659 params->chandef.chan, cfg80211_get_chandef_type(&(params->chandef)));
2660#endif
Viral Modi3a32cc52013-02-08 11:14:52 -08002661#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002662 status = wlan_hdd_cfg80211_start_bss(pAdapter, &params->beacon, params->ssid,
2663 params->ssid_len, params->hidden_ssid);
2664 }
2665
2666 EXIT();
2667 return status;
2668}
2669
2670
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302671static int wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002672 struct net_device *dev,
2673 struct cfg80211_beacon_data *params)
2674{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302675 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302676 hdd_context_t *pHddCtx;
2677 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002678
2679 ENTER();
2680
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302681 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2682 TRACE_CODE_HDD_CFG80211_CHANGE_BEACON,
2683 pAdapter->sessionId, pAdapter->device_mode));
Arif Hussain6d2a3322013-11-17 19:50:10 -08002684 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002685 __func__, pAdapter->device_mode);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302686
2687 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2688 status = wlan_hdd_validate_context(pHddCtx);
2689
2690 if (0 != status)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07002691 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302692 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2693 "%s: HDD context is not valid", __func__);
2694 return status;
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07002695 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002696
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302697 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002698 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302699 )
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002700 {
2701 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302702
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002703 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302704
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002705 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302706 {
2707 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2708 FL("session(%d) beacon data points to NULL"),
2709 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002710 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302711 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002712
2713 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter, &new, params, 0);
2714
2715 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302716 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08002717 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002718 return -EINVAL;
2719 }
2720
2721 pAdapter->sessionCtx.ap.beacon = new;
2722
2723 status = wlan_hdd_cfg80211_start_bss(pAdapter, params, NULL, 0, 0);
2724 }
2725
2726 EXIT();
2727 return status;
2728}
2729
2730#endif //(LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
2731
Jeff Johnson295189b2012-06-20 16:38:30 -07002732
2733static int wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
2734 struct net_device *dev,
2735 struct bss_parameters *params)
2736{
2737 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2738
2739 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302740
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302741 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2742 TRACE_CODE_HDD_CFG80211_CHANGE_BSS,
2743 pAdapter->sessionId, params->ap_isolate));
Arif Hussain6d2a3322013-11-17 19:50:10 -08002744 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07002745 __func__,pAdapter->device_mode);
2746
2747 if((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07002748 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302749 )
Jeff Johnson295189b2012-06-20 16:38:30 -07002750 {
2751 /* ap_isolate == -1 means that in change bss, upper layer doesn't
2752 * want to update this parameter */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302753 if (-1 != params->ap_isolate)
Jeff Johnson295189b2012-06-20 16:38:30 -07002754 {
2755 pAdapter->sessionCtx.ap.apDisableIntraBssFwd = !!params->ap_isolate;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302756 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002757 }
2758
2759 EXIT();
2760 return 0;
2761}
2762
Kiet Lam10841362013-11-01 11:36:50 +05302763/* FUNCTION: wlan_hdd_change_country_code_cd
2764* to wait for contry code completion
2765*/
2766void* wlan_hdd_change_country_code_cb(void *pAdapter)
2767{
2768 hdd_adapter_t *call_back_pAdapter = pAdapter;
2769 complete(&call_back_pAdapter->change_country_code);
2770 return NULL;
2771}
2772
Jeff Johnson295189b2012-06-20 16:38:30 -07002773/*
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +05302774 * FUNCTION: __wlan_hdd_cfg80211_change_iface
Jeff Johnson295189b2012-06-20 16:38:30 -07002775 * This function is used to set the interface type (INFRASTRUCTURE/ADHOC)
2776 */
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +05302777int __wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07002778 struct net_device *ndev,
2779 enum nl80211_iftype type,
2780 u32 *flags,
2781 struct vif_params *params
2782 )
2783{
2784 struct wireless_dev *wdev;
2785 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Rajesh Chauhana0516c62014-01-30 16:11:18 -08002786 hdd_context_t *pHddCtx;
Mohit Khanna0f232092012-09-11 14:46:08 -07002787 hdd_adapter_t *pP2pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07002788 tCsrRoamProfile *pRoamProfile = NULL;
2789 eCsrRoamBssType LastBSSType;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302790 hdd_config_t *pConfig = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07002791 eMib_dot11DesiredBssType connectedBssType;
2792 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302793 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07002794
2795 ENTER();
2796
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302797 if (!pAdapter)
Rajesh Chauhana0516c62014-01-30 16:11:18 -08002798 {
2799 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2800 "%s: Adapter context is null", __func__);
2801 return VOS_STATUS_E_FAILURE;
2802 }
2803
2804 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2805 if (!pHddCtx)
2806 {
2807 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2808 "%s: HDD context is null", __func__);
2809 return VOS_STATUS_E_FAILURE;
2810 }
2811
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302812 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2813 TRACE_CODE_HDD_CFG80211_CHANGE_IFACE,
2814 pAdapter->sessionId, type));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302815 status = wlan_hdd_validate_context(pHddCtx);
2816
2817 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -07002818 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302819 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2820 "%s: HDD context is not valid", __func__);
2821 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -07002822 }
2823
2824 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
2825 __func__, pAdapter->device_mode);
2826
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302827 pConfig = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -07002828 wdev = ndev->ieee80211_ptr;
2829
2830#ifdef WLAN_BTAMP_FEATURE
2831 if((NL80211_IFTYPE_P2P_CLIENT == type)||
2832 (NL80211_IFTYPE_ADHOC == type)||
2833 (NL80211_IFTYPE_AP == type)||
2834 (NL80211_IFTYPE_P2P_GO == type))
2835 {
2836 pHddCtx->isAmpAllowed = VOS_FALSE;
2837 // stop AMP traffic
2838 status = WLANBAP_StopAmp();
2839 if(VOS_STATUS_SUCCESS != status )
2840 {
2841 pHddCtx->isAmpAllowed = VOS_TRUE;
2842 hddLog(VOS_TRACE_LEVEL_FATAL,
2843 "%s: Failed to stop AMP", __func__);
2844 return -EINVAL;
2845 }
2846 }
2847#endif //WLAN_BTAMP_FEATURE
2848 /* Reset the current device mode bit mask*/
2849 wlan_hdd_clear_concurrency_mode(pHddCtx, pAdapter->device_mode);
2850
2851 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -07002852 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnsone7245742012-09-05 17:12:55 -07002853 || (pAdapter->device_mode == WLAN_HDD_P2P_DEVICE)
Jeff Johnson295189b2012-06-20 16:38:30 -07002854 )
2855 {
2856 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -08002857 if (!pWextState)
2858 {
2859 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2860 "%s: pWextState is null", __func__);
2861 return VOS_STATUS_E_FAILURE;
2862 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002863 pRoamProfile = &pWextState->roamProfile;
2864 LastBSSType = pRoamProfile->BSSType;
2865
2866 switch (type)
2867 {
2868 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -07002869 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -07002870 hddLog(VOS_TRACE_LEVEL_INFO,
2871 "%s: setting interface Type to INFRASTRUCTURE", __func__);
2872 pRoamProfile->BSSType = eCSR_BSS_TYPE_INFRASTRUCTURE;
Jeff Johnsone7245742012-09-05 17:12:55 -07002873#ifdef WLAN_FEATURE_11AC
2874 if(pConfig->dot11Mode == eHDD_DOT11_MODE_AUTO)
2875 {
2876 pConfig->dot11Mode = eHDD_DOT11_MODE_11ac;
2877 }
2878#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302879 pRoamProfile->phyMode =
Jeff Johnsone7245742012-09-05 17:12:55 -07002880 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07002881 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08002882 //Check for sub-string p2p to confirm its a p2p interface
2883 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302884 {
Gopichand Nakkala864d3552012-12-31 16:08:51 -08002885 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
2886 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
2887 }
2888 else
2889 {
2890 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -07002891 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -08002892 }
Madan Mohan Koyyalamudi81746922013-07-17 14:38:51 +05302893#ifdef FEATURE_WLAN_TDLS
2894 /* The open adapter for the p2p shall skip initializations in
2895 * tdls_init if the device mode is WLAN_HDD_P2P_DEVICE, for
2896 * TDLS is supported only on WLAN_HDD_P2P_CLIENT. Hence invoke
2897 * tdls_init when the change_iface sets the device mode to
2898 * WLAN_HDD_P2P_CLIENT.
2899 */
2900
2901 if ( pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
2902 {
2903 if (0 != wlan_hdd_tdls_init (pAdapter))
2904 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302905 hddLog(VOS_TRACE_LEVEL_ERROR,
2906 "%s: tdls initialization failed", __func__);
Madan Mohan Koyyalamudi81746922013-07-17 14:38:51 +05302907 return -EINVAL;
2908 }
2909 }
2910#endif
2911
Jeff Johnson295189b2012-06-20 16:38:30 -07002912 break;
2913 case NL80211_IFTYPE_ADHOC:
2914 hddLog(VOS_TRACE_LEVEL_INFO,
2915 "%s: setting interface Type to ADHOC", __func__);
2916 pRoamProfile->BSSType = eCSR_BSS_TYPE_START_IBSS;
2917 pRoamProfile->phyMode =
2918 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Shailender Karmuchia734f332013-04-19 14:02:48 -07002919 pAdapter->device_mode = WLAN_HDD_IBSS;
Jeff Johnson295189b2012-06-20 16:38:30 -07002920 wdev->iftype = type;
2921 break;
2922
2923 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -07002924 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07002925 {
2926 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
2927 "%s: setting interface Type to %s", __func__,
2928 (type == NL80211_IFTYPE_AP) ? "SoftAP" : "P2pGo");
2929
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08002930 //Cancel any remain on channel for GO mode
2931 if (NL80211_IFTYPE_P2P_GO == type)
2932 {
2933 wlan_hdd_cancel_existing_remain_on_channel(pAdapter);
2934 }
Mohit Khanna0f232092012-09-11 14:46:08 -07002935 if (NL80211_IFTYPE_AP == type)
2936 {
2937 /* As Loading WLAN Driver one interface being created for p2p device
2938 * address. This will take one HW STA and the max number of clients
2939 * that can connect to softAP will be reduced by one. so while changing
2940 * the interface type to NL80211_IFTYPE_AP (SoftAP) remove p2p0
2941 * interface as it is not required in SoftAP mode.
2942 */
2943
2944 // Get P2P Adapter
2945 pP2pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_DEVICE);
2946
2947 if (pP2pAdapter)
2948 {
2949 hdd_stop_adapter(pHddCtx, pP2pAdapter);
2950 hdd_deinit_adapter(pHddCtx, pP2pAdapter);
2951 hdd_close_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
2952 }
2953 }
Swaroop Goltia2e32212014-04-09 23:37:33 +05302954 //Disable IMPS & BMPS for SAP/GO
2955 if(VOS_STATUS_E_FAILURE ==
2956 hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_P2P_GO))
2957 {
2958 //Fail to Exit BMPS
2959 VOS_ASSERT(0);
2960 }
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05302961#ifdef FEATURE_WLAN_TDLS
Mohit Khanna0f232092012-09-11 14:46:08 -07002962
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05302963 /* A Mutex Lock is introduced while changing the mode to
2964 * protect the concurrent access for the Adapters by TDLS
2965 * module.
2966 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05302967 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05302968#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07002969 //De-init the adapter.
2970 hdd_stop_adapter( pHddCtx, pAdapter );
2971 hdd_deinit_adapter( pHddCtx, pAdapter );
2972 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
Jeff Johnson295189b2012-06-20 16:38:30 -07002973 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
2974 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05302975#ifdef FEATURE_WLAN_TDLS
2976 mutex_unlock(&pHddCtx->tdls_lock);
2977#endif
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -07002978 if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) &&
2979 (pConfig->apRandomBssidEnabled))
2980 {
2981 /* To meet Android requirements create a randomized
2982 MAC address of the form 02:1A:11:Fx:xx:xx */
2983 get_random_bytes(&ndev->dev_addr[3], 3);
2984 ndev->dev_addr[0] = 0x02;
2985 ndev->dev_addr[1] = 0x1A;
2986 ndev->dev_addr[2] = 0x11;
2987 ndev->dev_addr[3] |= 0xF0;
2988 memcpy(pAdapter->macAddressCurrent.bytes, ndev->dev_addr,
2989 VOS_MAC_ADDR_SIZE);
Arif Hussain24bafea2013-11-15 15:10:03 -08002990 pr_info("wlan: Generated HotSpot BSSID " MAC_ADDRESS_STR"\n",
2991 MAC_ADDR_ARRAY(ndev->dev_addr));
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -07002992 }
2993
Jeff Johnson295189b2012-06-20 16:38:30 -07002994 hdd_set_ap_ops( pAdapter->dev );
2995
Kiet Lam10841362013-11-01 11:36:50 +05302996 /* This is for only SAP mode where users can
2997 * control country through ini.
2998 * P2P GO follows station country code
2999 * acquired during the STA scanning. */
3000 if((NL80211_IFTYPE_AP == type) &&
3001 (memcmp(pConfig->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0))
3002 {
3003 int status = 0;
3004 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_INFO,
3005 "%s: setting country code from INI ", __func__);
3006 init_completion(&pAdapter->change_country_code);
3007 status = (int)sme_ChangeCountryCode(pHddCtx->hHal,
3008 (void *)(tSmeChangeCountryCallback)
3009 wlan_hdd_change_country_code_cb,
3010 pConfig->apCntryCode, pAdapter,
3011 pHddCtx->pvosContext,
Abhishek Singha306a442013-11-07 18:39:01 +05303012 eSIR_FALSE,
3013 eSIR_TRUE);
Kiet Lam10841362013-11-01 11:36:50 +05303014 if (eHAL_STATUS_SUCCESS == status)
3015 {
3016 /* Wait for completion */
c_hpothu6ff1c3c2013-10-01 19:01:57 +05303017 ret = wait_for_completion_interruptible_timeout(
Kiet Lam10841362013-11-01 11:36:50 +05303018 &pAdapter->change_country_code,
3019 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05303020 if (ret <= 0)
Kiet Lam10841362013-11-01 11:36:50 +05303021 {
3022 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05303023 FL("SME Timed out while setting country code %ld"),
3024 ret);
Yue Ma4f55ef32014-01-23 16:45:33 -08003025
3026 if (pHddCtx->isLogpInProgress)
3027 {
3028 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3029 "%s: LOGP in Progress. Ignore!!!", __func__);
3030 return -EAGAIN;
3031 }
Kiet Lam10841362013-11-01 11:36:50 +05303032 }
3033 }
3034 else
3035 {
3036 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08003037 "%s: SME Change Country code failed",__func__);
Kiet Lam10841362013-11-01 11:36:50 +05303038 return -EINVAL;
3039 }
3040 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003041 status = hdd_init_ap_mode(pAdapter);
3042 if(status != VOS_STATUS_SUCCESS)
3043 {
3044 hddLog(VOS_TRACE_LEVEL_FATAL,
3045 "%s: Error initializing the ap mode", __func__);
3046 return -EINVAL;
3047 }
3048 hdd_set_conparam(1);
3049
Jeff Johnson295189b2012-06-20 16:38:30 -07003050 /*interface type changed update in wiphy structure*/
3051 if(wdev)
3052 {
3053 wdev->iftype = type;
3054 pHddCtx->change_iface = type;
3055 }
3056 else
3057 {
3058 hddLog(VOS_TRACE_LEVEL_ERROR,
3059 "%s: ERROR !!!! Wireless dev is NULL", __func__);
3060 return -EINVAL;
3061 }
3062 goto done;
3063 }
3064
3065 default:
3066 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
3067 __func__);
3068 return -EOPNOTSUPP;
3069 }
3070 }
3071 else if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07003072 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07003073 )
3074 {
3075 switch(type)
3076 {
3077 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -07003078 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -07003079 case NL80211_IFTYPE_ADHOC:
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05303080#ifdef FEATURE_WLAN_TDLS
3081
3082 /* A Mutex Lock is introduced while changing the mode to
3083 * protect the concurrent access for the Adapters by TDLS
3084 * module.
3085 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05303086 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05303087#endif
Jeff Johnson32d95a32012-09-10 13:15:23 -07003088 hdd_stop_adapter( pHddCtx, pAdapter );
3089 hdd_deinit_adapter( pHddCtx, pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07003090 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08003091 //Check for sub-string p2p to confirm its a p2p interface
3092 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala864d3552012-12-31 16:08:51 -08003093 {
3094 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
3095 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
3096 }
3097 else
3098 {
3099 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -07003100 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -08003101 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003102 hdd_set_conparam(0);
3103 pHddCtx->change_iface = type;
Jeff Johnson295189b2012-06-20 16:38:30 -07003104 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
3105 hdd_set_station_ops( pAdapter->dev );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05303106#ifdef FEATURE_WLAN_TDLS
3107 mutex_unlock(&pHddCtx->tdls_lock);
3108#endif
Sunil Dutt66485cb2013-12-19 19:05:03 +05303109 status = hdd_init_station_mode( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07003110 if( VOS_STATUS_SUCCESS != status )
3111 return -EOPNOTSUPP;
Jeff Johnsone7245742012-09-05 17:12:55 -07003112 /* In case of JB, for P2P-GO, only change interface will be called,
3113 * This is the right place to enable back bmps_imps()
3114 */
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05303115 if (pHddCtx->hdd_wlan_suspended)
3116 {
3117 hdd_set_pwrparams(pHddCtx);
3118 }
Jeff Johnsone7245742012-09-05 17:12:55 -07003119 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07003120 goto done;
3121 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -07003122 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07003123 wdev->iftype = type;
Jeff Johnson295189b2012-06-20 16:38:30 -07003124 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
3125 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Jeff Johnson295189b2012-06-20 16:38:30 -07003126 goto done;
3127 default:
3128 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
3129 __func__);
3130 return -EOPNOTSUPP;
3131
3132 }
3133
3134 }
3135 else
3136 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05303137 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: unsupported device mode(%d)",
3138 __func__, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07003139 return -EOPNOTSUPP;
3140 }
3141
3142
3143 if(pRoamProfile)
3144 {
3145 if ( LastBSSType != pRoamProfile->BSSType )
3146 {
3147 /*interface type changed update in wiphy structure*/
3148 wdev->iftype = type;
3149
3150 /*the BSS mode changed, We need to issue disconnect
3151 if connected or in IBSS disconnect state*/
3152 if ( hdd_connGetConnectedBssType(
3153 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), &connectedBssType ) ||
3154 ( eCSR_BSS_TYPE_START_IBSS == LastBSSType ) )
3155 {
3156 /*need to issue a disconnect to CSR.*/
3157 INIT_COMPLETION(pAdapter->disconnect_comp_var);
3158 if( eHAL_STATUS_SUCCESS ==
3159 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
3160 pAdapter->sessionId,
3161 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
3162 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05303163 ret = wait_for_completion_interruptible_timeout(
3164 &pAdapter->disconnect_comp_var,
3165 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
3166 if (ret <= 0)
3167 {
3168 hddLog(VOS_TRACE_LEVEL_ERROR,
3169 FL("wait on disconnect_comp_var failed %ld"), ret);
3170 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003171 }
3172 }
3173 }
3174 }
3175
3176done:
3177 /*set bitmask based on updated value*/
3178 wlan_hdd_set_concurrency_mode(pHddCtx, pAdapter->device_mode);
Leo Chang6fe1f922013-06-07 19:21:24 -07003179
3180 /* Only STA mode support TM now
3181 * all other mode, TM feature should be disabled */
3182 if ( (pHddCtx->cfg_ini->thermalMitigationEnable) &&
3183 (~VOS_STA & pHddCtx->concurrency_mode) )
3184 {
3185 hddDevTmLevelChangedHandler(pHddCtx->parent_dev, 0);
3186 }
3187
Jeff Johnson295189b2012-06-20 16:38:30 -07003188#ifdef WLAN_BTAMP_FEATURE
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303189 if((NL80211_IFTYPE_STATION == type) && (pHddCtx->concurrency_mode <= 1) &&
Jeff Johnson295189b2012-06-20 16:38:30 -07003190 (pHddCtx->no_of_sessions[WLAN_HDD_INFRA_STATION] <=1))
3191 {
3192 //we are ok to do AMP
3193 pHddCtx->isAmpAllowed = VOS_TRUE;
3194 }
3195#endif //WLAN_BTAMP_FEATURE
3196 EXIT();
3197 return 0;
3198}
3199
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +05303200/*
3201 * FUNCTION: wlan_hdd_cfg80211_change_iface
3202 * wrapper function to protect the actual implementation from SSR.
3203 */
3204int wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
3205 struct net_device *ndev,
3206 enum nl80211_iftype type,
3207 u32 *flags,
3208 struct vif_params *params
3209 )
3210{
3211 int ret;
3212
3213 vos_ssr_protect(__func__);
3214 ret = __wlan_hdd_cfg80211_change_iface(wiphy, ndev, type, flags, params);
3215 vos_ssr_unprotect(__func__);
3216
3217 return ret;
3218}
3219
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003220#ifdef FEATURE_WLAN_TDLS
3221static int wlan_hdd_tdls_add_station(struct wiphy *wiphy,
3222 struct net_device *dev, u8 *mac, bool update, tCsrStaParams *StaParams)
3223{
3224 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3225 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3226 VOS_STATUS status;
Hoonki Lee5305c3a2013-04-29 23:28:59 -07003227 hddTdlsPeer_t *pTdlsPeer;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05303228 long ret;
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05303229 tANI_U16 numCurrTdlsPeers;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003230
3231 ENTER();
3232
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05303233 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003234 {
3235 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3236 "Invalid arguments");
3237 return -EINVAL;
3238 }
Hoonki Lee27511902013-03-14 18:19:06 -07003239
3240 if ((eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode) ||
3241 (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode))
3242 {
3243 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
3244 "%s: TDLS mode is disabled OR not enabled in FW."
3245 MAC_ADDRESS_STR " Request declined.",
3246 __func__, MAC_ADDR_ARRAY(mac));
3247 return -ENOTSUPP;
3248 }
3249
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003250 if (pHddCtx->isLogpInProgress)
3251 {
3252 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3253 "%s:LOGP in Progress. Ignore!!!", __func__);
Gopichand Nakkala05922802013-03-14 12:23:19 -07003254 wlan_hdd_tdls_set_link_status(pAdapter, mac, eTDLS_LINK_IDLE);
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003255 return -EBUSY;
3256 }
3257
Naresh Jayaram9c6f4462014-02-13 12:20:31 +05303258 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, mac);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07003259
3260 if ( NULL == pTdlsPeer ) {
3261 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
3262 "%s: " MAC_ADDRESS_STR " (update %d) not exist. return invalid",
3263 __func__, MAC_ADDR_ARRAY(mac), update);
3264 return -EINVAL;
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07003265 }
Hoonki Lee5305c3a2013-04-29 23:28:59 -07003266
3267 /* in add station, we accept existing valid staId if there is */
3268 if ((0 == update) &&
3269 ((pTdlsPeer->link_status >= eTDLS_LINK_CONNECTING) ||
3270 (TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003271 {
Hoonki Lee5305c3a2013-04-29 23:28:59 -07003272 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003273 "%s: " MAC_ADDRESS_STR
Hoonki Lee5305c3a2013-04-29 23:28:59 -07003274 " link_status %d. staId %d. add station ignored.",
3275 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, pTdlsPeer->staId);
3276 return 0;
3277 }
3278 /* in change station, we accept only when staId is valid */
3279 if ((1 == update) &&
3280 ((pTdlsPeer->link_status > eTDLS_LINK_CONNECTING) ||
3281 (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
3282 {
3283 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
3284 "%s: " MAC_ADDRESS_STR
3285 " link status %d. staId %d. change station %s.",
3286 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, pTdlsPeer->staId,
3287 (TDLS_STA_INDEX_VALID(pTdlsPeer->staId)) ? "ignored" : "declined");
3288 return (TDLS_STA_INDEX_VALID(pTdlsPeer->staId)) ? 0 : -EPERM;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003289 }
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07003290
3291 /* when others are on-going, we want to change link_status to idle */
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05303292 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, mac, TRUE))
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003293 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07003294 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3295 "%s: " MAC_ADDRESS_STR
3296 " TDLS setup is ongoing. Request declined.",
3297 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala05922802013-03-14 12:23:19 -07003298 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003299 }
3300
3301 /* first to check if we reached to maximum supported TDLS peer.
3302 TODO: for now, return -EPERM looks working fine,
3303 but need to check if any other errno fit into this category.*/
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05303304 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
3305 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003306 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07003307 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3308 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05303309 " TDLS Max peer already connected. Request declined."
3310 " Num of peers (%d), Max allowed (%d).",
3311 __func__, MAC_ADDR_ARRAY(mac), numCurrTdlsPeers,
3312 HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -07003313 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003314 }
3315 else
3316 {
3317 hddTdlsPeer_t *pTdlsPeer;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05303318 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, mac, TRUE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003319 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003320 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07003321 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3322 "%s: " MAC_ADDRESS_STR " already connected. Request declined.",
3323 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003324 return -EPERM;
3325 }
3326 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003327 if (0 == update)
3328 wlan_hdd_tdls_set_link_status(pAdapter, mac, eTDLS_LINK_CONNECTING);
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003329
Jeff Johnsond75fe012013-04-06 10:53:06 -07003330 /* debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05303331 if (NULL != StaParams)
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003332 {
3333 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
3334 "%s: TDLS Peer Parameters.", __func__);
Hoonki Lee66b75f32013-04-16 18:30:07 -07003335 if(StaParams->htcap_present)
3336 {
3337 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
3338 "ht_capa->cap_info: %0x", StaParams->HTCap.capInfo);
3339 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
3340 "ht_capa->extended_capabilities: %0x",
3341 StaParams->HTCap.extendedHtCapInfo);
3342 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003343 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
3344 "params->capability: %0x",StaParams->capability);
3345 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07003346 "params->ext_capab_len: %0x",StaParams->extn_capability[0]);
Hoonki Lee66b75f32013-04-16 18:30:07 -07003347 if(StaParams->vhtcap_present)
3348 {
3349 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
3350 "rxMcsMap %x rxHighest %x txMcsMap %x txHighest %x",
3351 StaParams->VHTCap.suppMcs.rxMcsMap, StaParams->VHTCap.suppMcs.rxHighest,
3352 StaParams->VHTCap.suppMcs.txMcsMap, StaParams->VHTCap.suppMcs.txHighest);
3353 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003354 {
3355 int i = 0;
Hoonki Lee5305c3a2013-04-29 23:28:59 -07003356 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "Supported rates:");
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003357 for (i = 0; i < sizeof(StaParams->supported_rates); i++)
3358 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
3359 "[%d]: %x ", i, StaParams->supported_rates[i]);
3360 }
Jeff Johnsond75fe012013-04-06 10:53:06 -07003361 } /* end debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05303362 else if ((1 == update) && (NULL == StaParams))
3363 {
3364 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3365 "%s : update is true, but staParams is NULL. Error!", __func__);
3366 return -EPERM;
3367 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003368
3369 INIT_COMPLETION(pAdapter->tdls_add_station_comp);
3370
3371 if (!update)
3372 {
3373 status = sme_AddTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
3374 pAdapter->sessionId, mac);
3375 }
3376 else
3377 {
3378 status = sme_ChangeTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
3379 pAdapter->sessionId, mac, StaParams);
3380 }
3381
c_hpothu6ff1c3c2013-10-01 19:01:57 +05303382 ret = wait_for_completion_interruptible_timeout(&pAdapter->tdls_add_station_comp,
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003383 msecs_to_jiffies(WAIT_TIME_TDLS_ADD_STA));
3384
c_hpothu6ff1c3c2013-10-01 19:01:57 +05303385 if (ret <= 0)
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003386 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07003387 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05303388 "%s: timeout waiting for tdls add station indication %ld",
3389 __func__, ret);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07003390 return -EPERM;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003391 }
c_hpothu6ff1c3c2013-10-01 19:01:57 +05303392
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003393 if ( eHAL_STATUS_SUCCESS != pAdapter->tdlsAddStaStatus)
3394 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07003395 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003396 "%s: Add Station is unsucessful", __func__);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07003397 return -EPERM;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003398 }
3399
3400 return 0;
Gopichand Nakkala05922802013-03-14 12:23:19 -07003401
3402error:
3403 wlan_hdd_tdls_set_link_status(pAdapter, mac, eTDLS_LINK_IDLE);
3404 return -EPERM;
3405
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003406}
3407#endif
3408
Jeff Johnson295189b2012-06-20 16:38:30 -07003409static int wlan_hdd_change_station(struct wiphy *wiphy,
3410 struct net_device *dev,
3411 u8 *mac,
3412 struct station_parameters *params)
3413{
3414 VOS_STATUS status = VOS_STATUS_SUCCESS;
3415 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Gopichand Nakkala29149562013-05-10 21:43:41 +05303416 hdd_context_t *pHddCtx;
3417 hdd_station_ctx_t *pHddStaCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07003418 v_MACADDR_t STAMacAddress;
Gopichand Nakkalab0856222013-03-12 22:39:05 -07003419#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003420 tCsrStaParams StaParams = {0};
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003421 tANI_U8 isBufSta = 0;
Naresh Jayaram3180aa42014-02-12 21:47:26 +05303422 tANI_U8 isOffChannelSupported = 0;
Gopichand Nakkalab0856222013-03-12 22:39:05 -07003423#endif
Jeff Johnsone7245742012-09-05 17:12:55 -07003424 ENTER();
3425
Gopichand Nakkala29149562013-05-10 21:43:41 +05303426 if ((NULL == pAdapter))
3427 {
3428 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
3429 "invalid adapter ");
3430 return -EINVAL;
3431 }
3432
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05303433 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
3434 TRACE_CODE_HDD_CHANGE_STATION,
3435 pAdapter->sessionId, params->listen_interval));
Gopichand Nakkala29149562013-05-10 21:43:41 +05303436 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
3437 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3438
3439 if ((NULL == pHddCtx) || (NULL == pHddStaCtx))
3440 {
3441 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
3442 "invalid HDD state or HDD station context");
3443 return -EINVAL;
3444 }
3445
3446 if (pHddCtx->isLogpInProgress)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07003447 {
3448 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3449 "%s:LOGP in Progress. Ignore!!!", __func__);
3450 return -EAGAIN;
3451 }
3452
Jeff Johnson295189b2012-06-20 16:38:30 -07003453 vos_mem_copy(STAMacAddress.bytes, mac, sizeof(v_MACADDR_t));
3454
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003455 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
3456 || (pAdapter->device_mode == WLAN_HDD_P2P_GO))
Jeff Johnson295189b2012-06-20 16:38:30 -07003457 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003458 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED))
Jeff Johnson295189b2012-06-20 16:38:30 -07003459 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303460 status = hdd_softap_change_STA_state( pAdapter, &STAMacAddress,
Jeff Johnson295189b2012-06-20 16:38:30 -07003461 WLANTL_STA_AUTHENTICATED);
3462
Gopichand Nakkala29149562013-05-10 21:43:41 +05303463 if (status != VOS_STATUS_SUCCESS)
3464 {
3465 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3466 "%s: Not able to change TL state to AUTHENTICATED", __func__);
3467 return -EINVAL;
3468 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003469 }
3470 }
Hoonki Leea6d49be2013-04-05 09:43:25 -07003471 else if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
3472 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)) {
Gopichand Nakkala29149562013-05-10 21:43:41 +05303473#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003474 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
3475 StaParams.capability = params->capability;
3476 StaParams.uapsd_queues = params->uapsd_queues;
3477 StaParams.max_sp = params->max_sp;
3478
Naresh Jayaram3180aa42014-02-12 21:47:26 +05303479 /* Convert (first channel , number of channels) tuple to
3480 * the total list of channels. This goes with the assumption
3481 * that if the first channel is < 14, then the next channels
3482 * are an incremental of 1 else an incremental of 4 till the number
3483 * of channels.
3484 */
3485 if (0 != params->supported_channels_len) {
3486 int i = 0,j = 0,k = 0, no_of_channels = 0 ;
3487 for ( i = 0 ; i < params->supported_channels_len ; i+=2)
3488 {
3489 int wifi_chan_index;
3490 StaParams.supported_channels[j] = params->supported_channels[i];
3491 wifi_chan_index =
3492 ((StaParams.supported_channels[j] <= HDD_CHANNEL_14 ) ? 1 : 4 );
3493 no_of_channels = params->supported_channels[i+1];
3494 for(k=1; k <= no_of_channels; k++)
3495 {
3496 StaParams.supported_channels[j+1] =
3497 StaParams.supported_channels[j] + wifi_chan_index;
3498 j+=1;
3499 }
3500 }
3501 StaParams.supported_channels_len = j;
3502 }
3503 vos_mem_copy(StaParams.supported_oper_classes,
3504 params->supported_oper_classes,
3505 params->supported_oper_classes_len);
3506 StaParams.supported_oper_classes_len =
3507 params->supported_oper_classes_len;
3508
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003509 if (0 != params->ext_capab_len)
3510 vos_mem_copy(StaParams.extn_capability, params->ext_capab,
3511 sizeof(StaParams.extn_capability));
3512
3513 if (NULL != params->ht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -07003514 {
3515 StaParams.htcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003516 vos_mem_copy(&StaParams.HTCap, params->ht_capa, sizeof(tSirHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -07003517 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003518
3519 StaParams.supported_rates_len = params->supported_rates_len;
3520
3521 /* Note : The Maximum sizeof supported_rates sent by the Supplicant is 32.
3522 * The supported_rates array , for all the structures propogating till Add Sta
3523 * to the firmware has to be modified , if the supplicant (ieee80211) is
3524 * modified to send more rates.
3525 */
3526
3527 /* To avoid Data Currption , set to max length to SIR_MAC_MAX_SUPP_RATES
3528 */
3529 if (StaParams.supported_rates_len > SIR_MAC_MAX_SUPP_RATES)
3530 StaParams.supported_rates_len = SIR_MAC_MAX_SUPP_RATES;
3531
3532 if (0 != StaParams.supported_rates_len) {
3533 int i = 0;
3534 vos_mem_copy(StaParams.supported_rates, params->supported_rates,
3535 StaParams.supported_rates_len);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07003536 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003537 "Supported Rates with Length %d", StaParams.supported_rates_len);
3538 for (i=0; i < StaParams.supported_rates_len; i++)
Hoonki Lee5305c3a2013-04-29 23:28:59 -07003539 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003540 "[%d]: %0x", i, StaParams.supported_rates[i]);
3541 }
3542
3543 if (NULL != params->vht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -07003544 {
3545 StaParams.vhtcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003546 vos_mem_copy(&StaParams.VHTCap, params->vht_capa, sizeof(tSirVHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -07003547 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003548
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003549 if (0 != params->ext_capab_len ) {
3550 /*Define A Macro : TODO Sunil*/
3551 if ((1<<4) & StaParams.extn_capability[3]) {
3552 isBufSta = 1;
3553 }
Naresh Jayaram3180aa42014-02-12 21:47:26 +05303554 /* TDLS Channel Switching Support */
3555 if ((1<<6) & StaParams.extn_capability[3]) {
3556 isOffChannelSupported = 1;
3557 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003558 }
Naresh Jayaram3180aa42014-02-12 21:47:26 +05303559 status = wlan_hdd_tdls_set_peer_caps( pAdapter, mac,
3560 &StaParams, isBufSta,
3561 isOffChannelSupported);
3562
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05303563 if (VOS_STATUS_SUCCESS != status) {
3564 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3565 "%s: wlan_hdd_tdls_set_peer_caps failed!", __func__);
3566 return -EINVAL;
3567 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003568 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 1, &StaParams);
3569
3570 if (VOS_STATUS_SUCCESS != status) {
3571 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3572 "%s: sme_ChangeTdlsPeerSta failed!", __func__);
3573 return -EINVAL;
3574 }
3575 }
Gopichand Nakkalab0856222013-03-12 22:39:05 -07003576#endif
Gopichand Nakkala6239acd2013-06-14 14:48:00 +05303577 }
Jeff Johnsone7245742012-09-05 17:12:55 -07003578 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07003579 return status;
3580}
3581
3582/*
Jeff Johnson295189b2012-06-20 16:38:30 -07003583 * FUNCTION: wlan_hdd_cfg80211_add_key
3584 * This function is used to initialize the key information
3585 */
3586#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003587static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07003588 struct net_device *ndev,
3589 u8 key_index, bool pairwise,
3590 const u8 *mac_addr,
3591 struct key_params *params
3592 )
3593#else
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003594static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07003595 struct net_device *ndev,
3596 u8 key_index, const u8 *mac_addr,
3597 struct key_params *params
3598 )
3599#endif
3600{
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003601 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -07003602 tCsrRoamSetKey setKey;
3603 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05303604 int status;
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003605 v_U32_t roamId= 0xFF;
3606 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07003607 hdd_hostapd_state_t *pHostapdState;
3608 VOS_STATUS vos_status;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07003609 eHalStatus halStatus;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05303610 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07003611
3612 ENTER();
3613
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05303614 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
3615 TRACE_CODE_HDD_CFG80211_ADD_KEY,
3616 pAdapter->sessionId, params->key_len));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05303617 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
3618 status = wlan_hdd_validate_context(pHddCtx);
3619
3620 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07003621 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05303622 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3623 "%s: HDD context is not valid", __func__);
3624 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07003625 }
3626
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003627 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
3628 __func__, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07003629
3630 if (CSR_MAX_NUM_KEY <= key_index)
3631 {
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003632 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07003633 key_index);
3634
3635 return -EINVAL;
3636 }
3637
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003638 if (CSR_MAX_KEY_LEN < params->key_len)
3639 {
3640 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key length %d", __func__,
3641 params->key_len);
3642
3643 return -EINVAL;
3644 }
3645
3646 hddLog(VOS_TRACE_LEVEL_INFO,
3647 "%s: called with key index = %d & key length %d",
3648 __func__, key_index, params->key_len);
Jeff Johnson295189b2012-06-20 16:38:30 -07003649
3650 /*extract key idx, key len and key*/
3651 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
3652 setKey.keyId = key_index;
3653 setKey.keyLength = params->key_len;
3654 vos_mem_copy(&setKey.Key[0],params->key, params->key_len);
3655
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003656 switch (params->cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -07003657 {
3658 case WLAN_CIPHER_SUITE_WEP40:
3659 setKey.encType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
3660 break;
3661
3662 case WLAN_CIPHER_SUITE_WEP104:
3663 setKey.encType = eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
3664 break;
3665
3666 case WLAN_CIPHER_SUITE_TKIP:
3667 {
3668 u8 *pKey = &setKey.Key[0];
3669 setKey.encType = eCSR_ENCRYPT_TYPE_TKIP;
3670
3671 vos_mem_zero(pKey, CSR_MAX_KEY_LEN);
3672
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003673 /*Supplicant sends the 32bytes key in this order
Jeff Johnson295189b2012-06-20 16:38:30 -07003674
3675 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003676 | Tk1 |TX-MIC | RX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -07003677 |--------------|----------|----------|
3678 <---16bytes---><--8bytes--><--8bytes-->
3679
3680 */
3681 /*Sme expects the 32 bytes key to be in the below order
3682
3683 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003684 | Tk1 |RX-MIC | TX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -07003685 |--------------|----------|----------|
3686 <---16bytes---><--8bytes--><--8bytes-->
3687 */
3688 /* Copy the Temporal Key 1 (TK1) */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003689 vos_mem_copy(pKey, params->key, 16);
Jeff Johnson295189b2012-06-20 16:38:30 -07003690
3691 /*Copy the rx mic first*/
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003692 vos_mem_copy(&pKey[16], &params->key[24], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -07003693
3694 /*Copy the tx mic */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003695 vos_mem_copy(&pKey[24], &params->key[16], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -07003696
3697
3698 break;
3699 }
3700
3701 case WLAN_CIPHER_SUITE_CCMP:
3702 setKey.encType = eCSR_ENCRYPT_TYPE_AES;
3703 break;
3704
3705#ifdef FEATURE_WLAN_WAPI
3706 case WLAN_CIPHER_SUITE_SMS4:
3707 {
3708 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
3709 wlan_hdd_cfg80211_set_key_wapi(pAdapter, key_index, mac_addr,
3710 params->key, params->key_len);
3711 return 0;
3712 }
3713#endif
Chet Lanctot186b5732013-03-18 10:26:30 -07003714
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003715#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -07003716 case WLAN_CIPHER_SUITE_KRK:
3717 setKey.encType = eCSR_ENCRYPT_TYPE_KRK;
3718 break;
3719#endif
Chet Lanctot186b5732013-03-18 10:26:30 -07003720
3721#ifdef WLAN_FEATURE_11W
3722 case WLAN_CIPHER_SUITE_AES_CMAC:
3723 setKey.encType = eCSR_ENCRYPT_TYPE_AES_CMAC;
Chet Lanctot3b5158a2013-03-31 16:45:21 -07003724 break;
Chet Lanctot186b5732013-03-18 10:26:30 -07003725#endif
3726
Jeff Johnson295189b2012-06-20 16:38:30 -07003727 default:
Jeff Johnson0299d0a2013-10-30 12:37:43 -07003728 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unsupported cipher type %u",
Jeff Johnson295189b2012-06-20 16:38:30 -07003729 __func__, params->cipher);
3730 return -EOPNOTSUPP;
3731 }
3732
3733 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: encryption type %d",
3734 __func__, setKey.encType);
3735
Shailender Karmuchi642e9812013-05-30 14:34:49 -07003736 if (
Jeff Johnson295189b2012-06-20 16:38:30 -07003737#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
3738 (!pairwise)
3739#else
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003740 (!mac_addr || is_broadcast_ether_addr(mac_addr))
Jeff Johnson295189b2012-06-20 16:38:30 -07003741#endif
Shailender Karmuchi642e9812013-05-30 14:34:49 -07003742 )
3743 {
3744 /* set group key*/
3745 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3746 "%s- %d: setting Broadcast key",
3747 __func__, __LINE__);
3748 setKey.keyDirection = eSIR_RX_ONLY;
3749 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
3750 }
3751 else
3752 {
3753 /* set pairwise key*/
3754 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3755 "%s- %d: setting pairwise key",
3756 __func__, __LINE__);
3757 setKey.keyDirection = eSIR_TX_RX;
3758 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
3759 }
3760 if ((WLAN_HDD_IBSS == pAdapter->device_mode) && !pairwise)
3761 {
3762 setKey.keyDirection = eSIR_TX_RX;
3763 /*Set the group key*/
3764 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
3765 pAdapter->sessionId, &setKey, &roamId );
Jeff Johnson295189b2012-06-20 16:38:30 -07003766
Shailender Karmuchi642e9812013-05-30 14:34:49 -07003767 if ( 0 != status )
3768 {
3769 hddLog(VOS_TRACE_LEVEL_ERROR,
3770 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
3771 return -EINVAL;
3772 }
3773 /*Save the keys here and call sme_RoamSetKey for setting
3774 the PTK after peer joins the IBSS network*/
3775 vos_mem_copy(&pAdapter->sessionCtx.station.ibss_enc_key,
3776 &setKey, sizeof(tCsrRoamSetKey));
3777 return status;
3778 }
Gopichand Nakkala29149562013-05-10 21:43:41 +05303779 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP) ||
3780 (pAdapter->device_mode == WLAN_HDD_P2P_GO))
3781 {
Jeff Johnson295189b2012-06-20 16:38:30 -07003782 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003783 if( pHostapdState->bssState == BSS_START )
3784 {
c_hpothu7c55da62014-01-23 18:34:02 +05303785 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3786 vos_status = wlan_hdd_check_ula_done(pAdapter);
3787
3788 if ( vos_status != VOS_STATUS_SUCCESS )
3789 {
3790 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3791 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
3792 __LINE__, vos_status );
3793
3794 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
3795
3796 return -EINVAL;
3797 }
3798
Jeff Johnson295189b2012-06-20 16:38:30 -07003799 status = WLANSAP_SetKeySta( pVosContext, &setKey);
3800
3801 if ( status != eHAL_STATUS_SUCCESS )
3802 {
3803 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3804 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
3805 __LINE__, status );
3806 }
3807 }
3808
3809 /* Saving WEP keys */
3810 else if( eCSR_ENCRYPT_TYPE_WEP40_STATICKEY == setKey.encType ||
3811 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY == setKey.encType )
3812 {
3813 //Save the wep key in ap context. Issue setkey after the BSS is started.
3814 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
3815 vos_mem_copy(&pAPCtx->wepKey[key_index], &setKey, sizeof(tCsrRoamSetKey));
3816 }
3817 else
3818 {
3819 //Save the key in ap context. Issue setkey after the BSS is started.
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003820 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07003821 vos_mem_copy(&pAPCtx->groupKey, &setKey, sizeof(tCsrRoamSetKey));
3822 }
3823 }
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003824 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION) ||
3825 (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT) )
Jeff Johnson295189b2012-06-20 16:38:30 -07003826 {
3827 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
3828 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3829
Gopichand Nakkala3d295922013-05-07 16:19:14 +05303830#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
3831 if (!pairwise)
3832#else
3833 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
3834#endif
3835 {
3836 /* set group key*/
3837 if (pHddStaCtx->roam_info.deferKeyComplete)
3838 {
3839 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3840 "%s- %d: Perform Set key Complete",
3841 __func__, __LINE__);
3842 hdd_PerformRoamSetKeyComplete(pAdapter);
3843 }
3844 }
3845
Jeff Johnson295189b2012-06-20 16:38:30 -07003846 pWextState->roamProfile.Keys.KeyLength[key_index] = (u8)params->key_len;
3847
Venkata Prathyusha Kuntupalliee2ce712013-01-17 14:09:24 -08003848 pWextState->roamProfile.Keys.defaultIndex = key_index;
3849
3850
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003851 vos_mem_copy(&pWextState->roamProfile.Keys.KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -07003852 params->key, params->key_len);
3853
Gopichand Nakkala3d295922013-05-07 16:19:14 +05303854
Jeff Johnson295189b2012-06-20 16:38:30 -07003855 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
3856
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303857 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -07003858 "%s: set key for peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303859 __func__, setKey.peerMac[0], setKey.peerMac[1],
3860 setKey.peerMac[2], setKey.peerMac[3],
3861 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -07003862 setKey.keyDirection);
3863
3864 vos_status = wlan_hdd_check_ula_done(pAdapter);
3865
3866 if ( vos_status != VOS_STATUS_SUCCESS )
3867 {
3868 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3869 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
3870 __LINE__, vos_status );
3871
3872 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
3873
3874 return -EINVAL;
3875
3876 }
3877
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07003878#ifdef WLAN_FEATURE_VOWIFI_11R
Gopichand Nakkala3d295922013-05-07 16:19:14 +05303879 /* The supplicant may attempt to set the PTK once pre-authentication
3880 is done. Save the key in the UMAC and include it in the ADD BSS
3881 request */
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07003882 halStatus = sme_FTUpdateKey( WLAN_HDD_GET_HAL_CTX(pAdapter), &setKey);
Gopichand Nakkala3d295922013-05-07 16:19:14 +05303883 if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_SUCCESS )
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07003884 {
Gopichand Nakkala3d295922013-05-07 16:19:14 +05303885 hddLog(VOS_TRACE_LEVEL_INFO_MED,
3886 "%s: Update PreAuth Key success", __func__);
3887 return 0;
3888 }
3889 else if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_FAILED )
3890 {
3891 hddLog(VOS_TRACE_LEVEL_ERROR,
3892 "%s: Update PreAuth Key failed", __func__);
Gopichand Nakkalad7d13652013-02-15 01:48:00 +05303893 return -EINVAL;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07003894 }
3895#endif /* WLAN_FEATURE_VOWIFI_11R */
Jeff Johnson295189b2012-06-20 16:38:30 -07003896
3897 /* issue set key request to SME*/
3898 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
3899 pAdapter->sessionId, &setKey, &roamId );
3900
3901 if ( 0 != status )
3902 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303903 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07003904 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
3905 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
3906 return -EINVAL;
3907 }
3908
3909
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303910 /* in case of IBSS as there was no information available about WEP keys during
3911 * IBSS join, group key intialized with NULL key, so re-initialize group key
Jeff Johnson295189b2012-06-20 16:38:30 -07003912 * with correct value*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303913 if ( (eCSR_BSS_TYPE_START_IBSS == pWextState->roamProfile.BSSType) &&
3914 !( ( IW_AUTH_KEY_MGMT_802_1X
3915 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X))
Jeff Johnson295189b2012-06-20 16:38:30 -07003916 && (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType)
3917 )
3918 &&
3919 ( (WLAN_CIPHER_SUITE_WEP40 == params->cipher)
3920 || (WLAN_CIPHER_SUITE_WEP104 == params->cipher)
3921 )
3922 )
3923 {
3924 setKey.keyDirection = eSIR_RX_ONLY;
3925 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
3926
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303927 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -07003928 "%s: set key peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303929 __func__, setKey.peerMac[0], setKey.peerMac[1],
3930 setKey.peerMac[2], setKey.peerMac[3],
3931 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -07003932 setKey.keyDirection);
3933
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303934 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07003935 pAdapter->sessionId, &setKey, &roamId );
3936
3937 if ( 0 != status )
3938 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303939 hddLog(VOS_TRACE_LEVEL_ERROR,
3940 "%s: sme_RoamSetKey failed for group key (IBSS), returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07003941 __func__, status);
3942 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
3943 return -EINVAL;
3944 }
3945 }
3946 }
3947
3948 return 0;
3949}
3950
3951/*
3952 * FUNCTION: wlan_hdd_cfg80211_get_key
3953 * This function is used to get the key information
3954 */
3955#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303956static int wlan_hdd_cfg80211_get_key(
3957 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07003958 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303959 u8 key_index, bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -07003960 const u8 *mac_addr, void *cookie,
3961 void (*callback)(void *cookie, struct key_params*)
3962 )
3963#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303964static int wlan_hdd_cfg80211_get_key(
3965 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07003966 struct net_device *ndev,
3967 u8 key_index, const u8 *mac_addr, void *cookie,
3968 void (*callback)(void *cookie, struct key_params*)
3969 )
3970#endif
3971{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303972 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -07003973 hdd_wext_state_t *pWextState= WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
3974 tCsrRoamProfile *pRoamProfile = &(pWextState->roamProfile);
3975 struct key_params params;
3976
3977 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303978
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05303979 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
3980 TRACE_CODE_HDD_CFG80211_GET_KEY,
3981 pAdapter->sessionId, params.cipher));
Arif Hussain6d2a3322013-11-17 19:50:10 -08003982 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07003983 __func__,pAdapter->device_mode);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303984
Jeff Johnson295189b2012-06-20 16:38:30 -07003985 memset(&params, 0, sizeof(params));
3986
3987 if (CSR_MAX_NUM_KEY <= key_index)
3988 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05303989 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid key index %d"), key_index);
Jeff Johnson295189b2012-06-20 16:38:30 -07003990 return -EINVAL;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303991 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003992
3993 switch(pRoamProfile->EncryptionType.encryptionType[0])
3994 {
3995 case eCSR_ENCRYPT_TYPE_NONE:
3996 params.cipher = IW_AUTH_CIPHER_NONE;
3997 break;
3998
3999 case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY:
4000 case eCSR_ENCRYPT_TYPE_WEP40:
4001 params.cipher = WLAN_CIPHER_SUITE_WEP40;
4002 break;
4003
4004 case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY:
4005 case eCSR_ENCRYPT_TYPE_WEP104:
4006 params.cipher = WLAN_CIPHER_SUITE_WEP104;
4007 break;
4008
4009 case eCSR_ENCRYPT_TYPE_TKIP:
4010 params.cipher = WLAN_CIPHER_SUITE_TKIP;
4011 break;
4012
4013 case eCSR_ENCRYPT_TYPE_AES:
4014 params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
4015 break;
4016
4017 default:
4018 params.cipher = IW_AUTH_CIPHER_NONE;
4019 break;
4020 }
4021
4022 params.key_len = pRoamProfile->Keys.KeyLength[key_index];
4023 params.seq_len = 0;
4024 params.seq = NULL;
4025 params.key = &pRoamProfile->Keys.KeyMaterial[key_index][0];
4026 callback(cookie, &params);
4027 return 0;
4028}
4029
4030/*
4031 * FUNCTION: wlan_hdd_cfg80211_del_key
4032 * This function is used to delete the key information
4033 */
4034#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304035static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07004036 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304037 u8 key_index,
4038 bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -07004039 const u8 *mac_addr
4040 )
4041#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304042static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07004043 struct net_device *ndev,
4044 u8 key_index,
4045 const u8 *mac_addr
4046 )
4047#endif
4048{
4049 int status = 0;
4050
4051 //This code needs to be revisited. There is sme_removeKey API, we should
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304052 //plan to use that. After the change to use correct index in setkey,
Jeff Johnson295189b2012-06-20 16:38:30 -07004053 //it is observed that this is invalidating peer
4054 //key index whenever re-key is done. This is affecting data link.
4055 //It should be ok to ignore del_key.
4056#if 0
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304057 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
4058 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07004059 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
4060 tCsrRoamSetKey setKey;
4061 v_U32_t roamId= 0xFF;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304062
Jeff Johnson295189b2012-06-20 16:38:30 -07004063 ENTER();
4064
4065 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device_mode = %d\n",
4066 __func__,pAdapter->device_mode);
4067
4068 if (CSR_MAX_NUM_KEY <= key_index)
4069 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304070 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07004071 key_index);
4072
4073 return -EINVAL;
4074 }
4075
4076 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
4077 setKey.keyId = key_index;
4078
4079 if (mac_addr)
4080 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
4081 else
4082 vos_mem_copy(setKey.peerMac, groupmacaddr, WNI_CFG_BSSID_LEN);
4083
4084 setKey.encType = eCSR_ENCRYPT_TYPE_NONE;
4085
4086 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07004087 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304088 )
4089 {
4090
4091 hdd_hostapd_state_t *pHostapdState =
Jeff Johnson295189b2012-06-20 16:38:30 -07004092 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
4093 if( pHostapdState->bssState == BSS_START)
4094 {
4095 status = WLANSAP_SetKeySta( pVosContext, &setKey);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304096
Jeff Johnson295189b2012-06-20 16:38:30 -07004097 if ( status != eHAL_STATUS_SUCCESS )
4098 {
4099 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4100 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
4101 __LINE__, status );
4102 }
4103 }
4104 }
4105 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304106 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnson295189b2012-06-20 16:38:30 -07004107 )
4108 {
4109 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4110
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304111 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
4112
4113 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -07004114 "%s: delete key for peerMac %2x:%2x:%2x:%2x:%2x:%2x",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304115 __func__, setKey.peerMac[0], setKey.peerMac[1],
4116 setKey.peerMac[2], setKey.peerMac[3],
Jeff Johnson295189b2012-06-20 16:38:30 -07004117 setKey.peerMac[4], setKey.peerMac[5]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304118 if(pAdapter->sessionCtx.station.conn_info.connState ==
4119 eConnectionState_Associated)
Jeff Johnson295189b2012-06-20 16:38:30 -07004120 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304121 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07004122 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304123
Jeff Johnson295189b2012-06-20 16:38:30 -07004124 if ( 0 != status )
4125 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304126 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07004127 "%s: sme_RoamSetKey failure, returned %d",
4128 __func__, status);
4129 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
4130 return -EINVAL;
4131 }
4132 }
4133 }
4134#endif
Jeff Johnsone7245742012-09-05 17:12:55 -07004135 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07004136 return status;
4137}
4138
4139/*
4140 * FUNCTION: wlan_hdd_cfg80211_set_default_key
4141 * This function is used to set the default tx key index
4142 */
4143#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
4144static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
4145 struct net_device *ndev,
4146 u8 key_index,
4147 bool unicast, bool multicast)
4148#else
4149static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
4150 struct net_device *ndev,
4151 u8 key_index)
4152#endif
4153{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304154 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05304155 int status;
Gopichand Nakkala29149562013-05-10 21:43:41 +05304156 hdd_wext_state_t *pWextState;
4157 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05304158 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07004159
4160 ENTER();
4161
Gopichand Nakkala29149562013-05-10 21:43:41 +05304162 if ((NULL == pAdapter))
4163 {
4164 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
4165 "invalid adapter");
4166 return -EINVAL;
4167 }
4168
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05304169 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
4170 TRACE_CODE_HDD_CFG80211_SET_DEFAULT_KEY,
4171 pAdapter->sessionId, key_index));
4172
Gopichand Nakkala29149562013-05-10 21:43:41 +05304173 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
4174 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4175
4176 if ((NULL == pWextState) || (NULL == pHddStaCtx))
4177 {
4178 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
4179 "invalid Wext state or HDD context");
4180 return -EINVAL;
4181 }
4182
Arif Hussain6d2a3322013-11-17 19:50:10 -08004183 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d key_index = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07004184 __func__,pAdapter->device_mode, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304185
Jeff Johnson295189b2012-06-20 16:38:30 -07004186 if (CSR_MAX_NUM_KEY <= key_index)
4187 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304188 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07004189 key_index);
4190
4191 return -EINVAL;
4192 }
4193
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05304194 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
4195 status = wlan_hdd_validate_context(pHddCtx);
4196
4197 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004198 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05304199 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4200 "%s: HDD context is not valid", __func__);
4201 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004202 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304203
Jeff Johnson295189b2012-06-20 16:38:30 -07004204 if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -07004205 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304206 )
Jeff Johnson295189b2012-06-20 16:38:30 -07004207 {
Gopichand Nakkala29149562013-05-10 21:43:41 +05304208 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
Arif Hussain6943f522013-11-04 20:10:10 -08004209 pHddStaCtx->conn_info.ucEncryptionType) &&
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304210 (eCSR_ENCRYPT_TYPE_AES !=
Arif Hussain6943f522013-11-04 20:10:10 -08004211 pHddStaCtx->conn_info.ucEncryptionType)
Jeff Johnson295189b2012-06-20 16:38:30 -07004212 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304213 {
4214 /* if default key index is not same as previous one,
Jeff Johnson295189b2012-06-20 16:38:30 -07004215 * then update the default key index */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304216
Jeff Johnson295189b2012-06-20 16:38:30 -07004217 tCsrRoamSetKey setKey;
4218 v_U32_t roamId= 0xFF;
4219 tCsrKeys *Keys = &pWextState->roamProfile.Keys;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304220
4221 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: default tx key index %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07004222 __func__, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304223
Jeff Johnson295189b2012-06-20 16:38:30 -07004224 Keys->defaultIndex = (u8)key_index;
4225 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
4226 setKey.keyId = key_index;
4227 setKey.keyLength = Keys->KeyLength[key_index];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304228
4229 vos_mem_copy(&setKey.Key[0],
4230 &Keys->KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -07004231 Keys->KeyLength[key_index]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304232
Gopichand Nakkala29149562013-05-10 21:43:41 +05304233 setKey.keyDirection = eSIR_TX_RX;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304234
4235 vos_mem_copy(setKey.peerMac,
Jeff Johnson295189b2012-06-20 16:38:30 -07004236 &pHddStaCtx->conn_info.bssId[0],
4237 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304238
Gopichand Nakkala29149562013-05-10 21:43:41 +05304239 if (Keys->KeyLength[key_index] == CSR_WEP40_KEY_LEN &&
4240 pWextState->roamProfile.EncryptionType.encryptionType[0] ==
4241 eCSR_ENCRYPT_TYPE_WEP104)
4242 {
4243 /*In the case of dynamic wep supplicant hardcodes DWEP type to eCSR_ENCRYPT_TYPE_WEP104
4244 even though ap is configured for WEP-40 encryption. In this canse the key length
4245 is 5 but the encryption type is 104 hence checking the key langht(5) and encryption
4246 type(104) and switching encryption type to 40*/
4247 pWextState->roamProfile.EncryptionType.encryptionType[0] =
4248 eCSR_ENCRYPT_TYPE_WEP40;
4249 pWextState->roamProfile.mcEncryptionType.encryptionType[0] =
4250 eCSR_ENCRYPT_TYPE_WEP40;
4251 }
4252
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304253 setKey.encType =
Jeff Johnson295189b2012-06-20 16:38:30 -07004254 pWextState->roamProfile.EncryptionType.encryptionType[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304255
Jeff Johnson295189b2012-06-20 16:38:30 -07004256 /* issue set key request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304257 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07004258 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304259
Jeff Johnson295189b2012-06-20 16:38:30 -07004260 if ( 0 != status )
4261 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304262 hddLog(VOS_TRACE_LEVEL_ERROR,
4263 "%s: sme_RoamSetKey failed, returned %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07004264 status);
4265 return -EINVAL;
4266 }
4267 }
4268 }
4269
4270 /* In SoftAp mode setting key direction for default mode */
4271 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
4272 {
4273 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
4274 pWextState->roamProfile.EncryptionType.encryptionType[0]) &&
4275 (eCSR_ENCRYPT_TYPE_AES !=
4276 pWextState->roamProfile.EncryptionType.encryptionType[0])
4277 )
4278 {
4279 /* Saving key direction for default key index to TX default */
4280 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
4281 pAPCtx->wepKey[key_index].keyDirection = eSIR_TX_DEFAULT;
4282 }
4283 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304284
Jeff Johnson295189b2012-06-20 16:38:30 -07004285 return status;
4286}
4287
Jeff Johnson295189b2012-06-20 16:38:30 -07004288/*
4289 * FUNCTION: wlan_hdd_cfg80211_inform_bss
4290 * This function is used to inform the BSS details to nl80211 interface.
4291 */
4292static struct cfg80211_bss* wlan_hdd_cfg80211_inform_bss(
4293 hdd_adapter_t *pAdapter, tCsrRoamConnectedProfile *roamProfile)
4294{
4295 struct net_device *dev = pAdapter->dev;
4296 struct wireless_dev *wdev = dev->ieee80211_ptr;
4297 struct wiphy *wiphy = wdev->wiphy;
4298 tSirBssDescription *pBssDesc = roamProfile->pBssDesc;
4299 int chan_no;
4300 int ie_length;
4301 const char *ie;
4302 unsigned int freq;
4303 struct ieee80211_channel *chan;
4304 int rssi = 0;
4305 struct cfg80211_bss *bss = NULL;
4306
4307 ENTER();
4308
4309 if( NULL == pBssDesc )
4310 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08004311 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pBssDesc is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004312 return bss;
4313 }
4314
4315 chan_no = pBssDesc->channelId;
4316 ie_length = GET_IE_LEN_IN_BSS_DESC( pBssDesc->length );
4317 ie = ((ie_length != 0) ? (const char *)&pBssDesc->ieFields: NULL);
4318
4319 if( NULL == ie )
4320 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08004321 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: IE of BSS descriptor is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004322 return bss;
4323 }
4324
4325#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
4326 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
4327 {
4328 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
4329 }
4330 else
4331 {
4332 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
4333 }
4334#else
4335 freq = ieee80211_channel_to_frequency(chan_no);
4336#endif
4337
4338 chan = __ieee80211_get_channel(wiphy, freq);
4339
Santhosh Kumar Padmaa45fdb12014-04-15 15:54:38 +05304340 if (!chan) {
4341 hddLog(VOS_TRACE_LEVEL_ERROR, "%s chan pointer is NULL", __func__);
4342 return NULL;
4343 }
4344
Jeff Johnson295189b2012-06-20 16:38:30 -07004345 bss = cfg80211_get_bss(wiphy, chan, pBssDesc->bssId,
4346 &roamProfile->SSID.ssId[0], roamProfile->SSID.length,
4347 WLAN_CAPABILITY_ESS, WLAN_CAPABILITY_ESS);
4348 if (bss == NULL)
4349 {
4350 rssi = (VOS_MIN ((pBssDesc->rssi + pBssDesc->sinr), 0))*100;
4351
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304352 return (cfg80211_inform_bss(wiphy, chan, pBssDesc->bssId,
4353 le64_to_cpu(*(__le64 *)pBssDesc->timeStamp),
Jeff Johnson295189b2012-06-20 16:38:30 -07004354 pBssDesc->capabilityInfo,
4355 pBssDesc->beaconInterval, ie, ie_length,
4356 rssi, GFP_KERNEL ));
4357}
4358 else
4359 {
4360 return bss;
4361 }
4362}
4363
4364
4365
4366/*
4367 * FUNCTION: wlan_hdd_cfg80211_inform_bss_frame
4368 * This function is used to inform the BSS details to nl80211 interface.
4369 */
4370struct cfg80211_bss*
4371wlan_hdd_cfg80211_inform_bss_frame( hdd_adapter_t *pAdapter,
4372 tSirBssDescription *bss_desc
4373 )
4374{
4375 /*
4376 cfg80211_inform_bss() is not updating ie field of bss entry, if entry
4377 already exists in bss data base of cfg80211 for that particular BSS ID.
4378 Using cfg80211_inform_bss_frame to update the bss entry instead of
4379 cfg80211_inform_bss, But this call expects mgmt packet as input. As of
4380 now there is no possibility to get the mgmt(probe response) frame from PE,
4381 converting bss_desc to ieee80211_mgmt(probe response) and passing to
4382 cfg80211_inform_bss_frame.
4383 */
4384 struct net_device *dev = pAdapter->dev;
4385 struct wireless_dev *wdev = dev->ieee80211_ptr;
4386 struct wiphy *wiphy = wdev->wiphy;
4387 int chan_no = bss_desc->channelId;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08004388#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
4389 qcom_ie_age *qie_age = NULL;
4390 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length ) + sizeof(qcom_ie_age);
4391#else
Jeff Johnson295189b2012-06-20 16:38:30 -07004392 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length );
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08004393#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07004394 const char *ie =
4395 ((ie_length != 0) ? (const char *)&bss_desc->ieFields: NULL);
4396 unsigned int freq;
4397 struct ieee80211_channel *chan;
Abhishek Singh1e2bfa32014-01-02 15:44:15 +05304398 struct ieee80211_mgmt *mgmt = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07004399 struct cfg80211_bss *bss_status = NULL;
4400 size_t frame_len = sizeof (struct ieee80211_mgmt) + ie_length;
4401 int rssi = 0;
Wilson Yangf80a0542013-10-07 13:02:37 -07004402 hdd_context_t *pHddCtx;
4403 int status;
Jeff Johnsone7245742012-09-05 17:12:55 -07004404#ifdef WLAN_OPEN_SOURCE
4405 struct timespec ts;
4406#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07004407
Wilson Yangf80a0542013-10-07 13:02:37 -07004408 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
4409 status = wlan_hdd_validate_context(pHddCtx);
4410
4411 /*bss_update is not allowed during wlan driver loading or unloading*/
Mihir Shete18156292014-03-11 15:38:30 +05304412 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Wilson Yangf80a0542013-10-07 13:02:37 -07004413 {
4414 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4415 "%s:Loading_unloading in Progress. Ignore!!!",__func__);
4416 return NULL;
4417 }
4418
4419
4420 if (0 != status)
4421 {
4422 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4423 "%s: HDD context is not valid", __func__);
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -07004424 return NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -07004425 }
4426
Abhishek Singh1e2bfa32014-01-02 15:44:15 +05304427 mgmt = kzalloc((sizeof (struct ieee80211_mgmt) + ie_length), GFP_KERNEL);
Wilson Yangf80a0542013-10-07 13:02:37 -07004428 if (!mgmt)
4429 {
4430 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4431 "%s: memory allocation failed ", __func__);
4432 return NULL;
4433 }
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -07004434
Jeff Johnson295189b2012-06-20 16:38:30 -07004435 memcpy(mgmt->bssid, bss_desc->bssId, ETH_ALEN);
Jeff Johnsone7245742012-09-05 17:12:55 -07004436
4437#ifdef WLAN_OPEN_SOURCE
4438 /* Android does not want the timestamp from the frame.
4439 Instead it wants a monotonic increasing value */
4440 get_monotonic_boottime(&ts);
4441 mgmt->u.probe_resp.timestamp =
4442 ((u64)ts.tv_sec * 1000000) + (ts.tv_nsec / 1000);
4443#else
4444 /* keep old behavior for non-open source (for now) */
Jeff Johnson295189b2012-06-20 16:38:30 -07004445 memcpy(&mgmt->u.probe_resp.timestamp, bss_desc->timeStamp,
4446 sizeof (bss_desc->timeStamp));
Jeff Johnsone7245742012-09-05 17:12:55 -07004447
4448#endif
4449
Jeff Johnson295189b2012-06-20 16:38:30 -07004450 mgmt->u.probe_resp.beacon_int = bss_desc->beaconInterval;
4451 mgmt->u.probe_resp.capab_info = bss_desc->capabilityInfo;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08004452
4453#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
4454 /* GPS Requirement: need age ie per entry. Using vendor specific. */
4455 /* Assuming this is the last IE, copy at the end */
4456 ie_length -=sizeof(qcom_ie_age);
4457 qie_age = (qcom_ie_age *)(mgmt->u.probe_resp.variable + ie_length);
4458 qie_age->element_id = QCOM_VENDOR_IE_ID;
4459 qie_age->len = QCOM_VENDOR_IE_AGE_LEN;
4460 qie_age->oui_1 = QCOM_OUI1;
4461 qie_age->oui_2 = QCOM_OUI2;
4462 qie_age->oui_3 = QCOM_OUI3;
4463 qie_age->type = QCOM_VENDOR_IE_AGE_TYPE;
4464 qie_age->age = vos_timer_get_system_ticks() - bss_desc->nReceivedTime;
4465#endif
4466
Jeff Johnson295189b2012-06-20 16:38:30 -07004467 memcpy(mgmt->u.probe_resp.variable, ie, ie_length);
Gopichand Nakkalad908ec82013-05-16 19:32:19 +05304468 if (bss_desc->fProbeRsp)
4469 {
4470 mgmt->frame_control |=
4471 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_RESP);
4472 }
4473 else
4474 {
4475 mgmt->frame_control |=
4476 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_BEACON);
4477 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004478
4479#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304480 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ) &&
Jeff Johnson295189b2012-06-20 16:38:30 -07004481 (wiphy->bands[IEEE80211_BAND_2GHZ] != NULL))
4482 {
4483 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
4484 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304485 else if ((chan_no > ARRAY_SIZE(hdd_channels_2_4_GHZ)) &&
Jeff Johnson295189b2012-06-20 16:38:30 -07004486 (wiphy->bands[IEEE80211_BAND_5GHZ] != NULL))
4487
4488 {
4489 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
4490 }
4491 else
4492 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05304493 hddLog(VOS_TRACE_LEVEL_ERROR, "%s Invalid chan_no:%d",
4494 __func__, chan_no);
Jeff Johnson295189b2012-06-20 16:38:30 -07004495 kfree(mgmt);
4496 return NULL;
4497 }
4498#else
4499 freq = ieee80211_channel_to_frequency(chan_no);
4500#endif
4501 chan = __ieee80211_get_channel(wiphy, freq);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -08004502 /*when the band is changed on the fly using the GUI, three things are done
4503 * 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)
4504 * as part of the scan abort, message willbe queued to PE and we proceed with flushing and changinh the band.
4505 * pe will stop the scanning further and report back the results what ever it had till now by calling the call back function.
4506 * if the time between update band and scandone call back is sufficent enough the band change reflects in SME, SME validates the channels
4507 * and discards the channels correponding to previous band and calls back with zero bss results.
4508 * 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
4509 * all the channels correponding to previous band.this is due to race condition.but those channels are invalid to the new band and so
4510 * this function __ieee80211_get_channel will return NULL.Each time we report scan result with this pointer null warning kernel trace is printed.
4511 * if the scan results contain large number of APs continuosly kernel warning trace is printed and it will lead to apps watch dog bark.
4512 * So drop the bss and continue to next bss.
4513 */
4514 if(chan == NULL)
4515 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05304516 hddLog(VOS_TRACE_LEVEL_ERROR, "%s chan pointer is NULL", __func__);
Chilam Ngc4244af2013-04-01 15:37:32 -07004517 kfree(mgmt);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -08004518 return NULL;
4519 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004520 /*To keep the rssi icon of the connected AP in the scan window
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304521 *and the rssi icon of the wireless networks in sync
Jeff Johnson295189b2012-06-20 16:38:30 -07004522 * */
4523 if (( eConnectionState_Associated ==
4524 pAdapter->sessionCtx.station.conn_info.connState ) &&
4525 ( VOS_TRUE == vos_mem_compare(bss_desc->bssId,
4526 pAdapter->sessionCtx.station.conn_info.bssId,
4527 WNI_CFG_BSSID_LEN)))
4528 {
4529 /* supplicant takes the signal strength in terms of mBm(100*dBm) */
4530 rssi = (pAdapter->rssi * 100);
4531 }
4532 else
4533 {
4534 rssi = (VOS_MIN ((bss_desc->rssi + bss_desc->sinr), 0))*100;
4535 }
4536
Nirav Shah20ac06f2013-12-12 18:14:06 +05304537 hddLog(VOS_TRACE_LEVEL_INFO, "%s: BSSID:" MAC_ADDRESS_STR " Channel:%d"
4538 "RSSI:%d", __func__, MAC_ADDR_ARRAY(mgmt->bssid),
4539 chan->center_freq, (int)(rssi/100));
4540
Jeff Johnson295189b2012-06-20 16:38:30 -07004541 bss_status = cfg80211_inform_bss_frame(wiphy, chan, mgmt,
4542 frame_len, rssi, GFP_KERNEL);
4543 kfree(mgmt);
4544 return bss_status;
4545}
4546
4547/*
4548 * FUNCTION: wlan_hdd_cfg80211_update_bss_db
4549 * This function is used to update the BSS data base of CFG8011
4550 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304551struct cfg80211_bss* wlan_hdd_cfg80211_update_bss_db( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07004552 tCsrRoamInfo *pRoamInfo
4553 )
4554{
4555 tCsrRoamConnectedProfile roamProfile;
4556 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
4557 struct cfg80211_bss *bss = NULL;
4558
4559 ENTER();
4560
4561 memset(&roamProfile, 0, sizeof(tCsrRoamConnectedProfile));
4562 sme_RoamGetConnectProfile(hHal, pAdapter->sessionId, &roamProfile);
4563
4564 if (NULL != roamProfile.pBssDesc)
4565 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304566 bss = wlan_hdd_cfg80211_inform_bss(pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07004567 &roamProfile);
4568
4569 if (NULL == bss)
4570 {
4571 hddLog(VOS_TRACE_LEVEL_INFO, "%s: cfg80211_inform_bss return NULL",
4572 __func__);
4573 }
4574
4575 sme_RoamFreeConnectProfile(hHal, &roamProfile);
4576 }
4577 else
4578 {
4579 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: roamProfile.pBssDesc is NULL",
4580 __func__);
4581 }
4582 return bss;
4583}
4584
4585/*
4586 * FUNCTION: wlan_hdd_cfg80211_update_bss
4587 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304588static int wlan_hdd_cfg80211_update_bss( struct wiphy *wiphy,
4589 hdd_adapter_t *pAdapter
Jeff Johnson295189b2012-06-20 16:38:30 -07004590 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304591{
Jeff Johnson295189b2012-06-20 16:38:30 -07004592 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
4593 tCsrScanResultInfo *pScanResult;
4594 eHalStatus status = 0;
4595 tScanResultHandle pResult;
4596 struct cfg80211_bss *bss_status = NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -07004597 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07004598
4599 ENTER();
4600
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05304601 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
4602 TRACE_CODE_HDD_CFG80211_UPDATE_BSS,
4603 NO_SESSION, pAdapter->sessionId));
4604
Wilson Yangf80a0542013-10-07 13:02:37 -07004605 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
4606
4607 if (pHddCtx->isLogpInProgress)
Jeff Johnson295189b2012-06-20 16:38:30 -07004608 {
Wilson Yangf80a0542013-10-07 13:02:37 -07004609 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
4610 "%s:LOGP in Progress. Ignore!!!",__func__);
4611 return -EAGAIN;
Jeff Johnson295189b2012-06-20 16:38:30 -07004612 }
4613
Wilson Yangf80a0542013-10-07 13:02:37 -07004614
4615 /*bss_update is not allowed during wlan driver loading or unloading*/
Mihir Shete18156292014-03-11 15:38:30 +05304616 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Wilson Yangf80a0542013-10-07 13:02:37 -07004617 {
4618 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4619 "%s:Loading_unloading in Progress. Ignore!!!",__func__);
4620 return VOS_STATUS_E_PERM;
4621 }
4622
4623
Jeff Johnson295189b2012-06-20 16:38:30 -07004624 /*
4625 * start getting scan results and populate cgf80211 BSS database
4626 */
4627 status = sme_ScanGetResult(hHal, pAdapter->sessionId, NULL, &pResult);
4628
4629 /* no scan results */
4630 if (NULL == pResult)
4631 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05304632 hddLog(VOS_TRACE_LEVEL_INFO, "%s: No scan result Status %d",
4633 __func__, status);
Jeff Johnson295189b2012-06-20 16:38:30 -07004634 return status;
4635 }
4636
4637 pScanResult = sme_ScanResultGetFirst(hHal, pResult);
4638
4639 while (pScanResult)
4640 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304641 /*
4642 * cfg80211_inform_bss() is not updating ie field of bss entry, if
4643 * entry already exists in bss data base of cfg80211 for that
4644 * particular BSS ID. Using cfg80211_inform_bss_frame to update the
4645 * bss entry instead of cfg80211_inform_bss, But this call expects
4646 * mgmt packet as input. As of now there is no possibility to get
4647 * the mgmt(probe response) frame from PE, converting bss_desc to
Jeff Johnson295189b2012-06-20 16:38:30 -07004648 * ieee80211_mgmt(probe response) and passing to c
4649 * fg80211_inform_bss_frame.
4650 * */
4651
4652 bss_status = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
4653 &pScanResult->BssDescriptor);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304654
Jeff Johnson295189b2012-06-20 16:38:30 -07004655
4656 if (NULL == bss_status)
4657 {
4658 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -08004659 "%s: NULL returned by cfg80211_inform_bss", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004660 }
4661 else
4662 {
Yue Maf49ba872013-08-19 12:04:25 -07004663 cfg80211_put_bss(
4664#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0))
4665 wiphy,
4666#endif
4667 bss_status);
Jeff Johnson295189b2012-06-20 16:38:30 -07004668 }
4669
4670 pScanResult = sme_ScanResultGetNext(hHal, pResult);
4671 }
4672
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304673 sme_ScanResultPurge(hHal, pResult);
Jeff Johnson295189b2012-06-20 16:38:30 -07004674
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304675 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07004676}
4677
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004678void
4679hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel)
4680{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304681 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussaina7c8e412013-11-20 11:06:42 -08004682 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(macAddr));
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004683} /****** end hddPrintMacAddr() ******/
4684
4685void
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07004686hddPrintPmkId(tANI_U8 *pmkId, tANI_U8 logLevel)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004687{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304688 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussain6d2a3322013-11-17 19:50:10 -08004689 "%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X",
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07004690 pmkId[0], pmkId[1], pmkId[2], pmkId[3], pmkId[4],
4691 pmkId[5], pmkId[6], pmkId[7], pmkId[8], pmkId[9], pmkId[10],
4692 pmkId[11], pmkId[12], pmkId[13], pmkId[14], pmkId[15]);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004693} /****** end hddPrintPmkId() ******/
4694
4695//hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel);
4696//hddPrintMacAddr(macAddr, VOS_TRACE_LEVEL_FATAL);
4697
4698//void sirDumpBuf(tpAniSirGlobal pMac, tANI_U8 modId, tANI_U32 level, tANI_U8 *buf, tANI_U32 size);
4699//sirDumpBuf(pMac, VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, pmkid, 16);
4700
4701#define dump_bssid(bssid) \
4702 { \
Jeff Johnsone7245742012-09-05 17:12:55 -07004703 hddLog(VOS_TRACE_LEVEL_INFO, "BSSID (MAC) address:\t"); \
4704 hddPrintMacAddr(bssid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004705 }
4706
4707#define dump_pmkid(pMac, pmkid) \
4708 { \
Jeff Johnsone7245742012-09-05 17:12:55 -07004709 hddLog(VOS_TRACE_LEVEL_INFO, "PMKSA-ID:\t"); \
4710 hddPrintPmkId(pmkid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004711 }
4712
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -07004713#if defined(FEATURE_WLAN_LFR) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004714/*
4715 * FUNCTION: wlan_hdd_cfg80211_pmksa_candidate_notify
4716 * This function is used to notify the supplicant of a new PMKSA candidate.
4717 */
4718int wlan_hdd_cfg80211_pmksa_candidate_notify(
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304719 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004720 int index, bool preauth )
4721{
Jeff Johnsone7245742012-09-05 17:12:55 -07004722#ifdef FEATURE_WLAN_OKC
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004723 struct net_device *dev = pAdapter->dev;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004724 hdd_context_t *pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004725
4726 ENTER();
Jeff Johnsone7245742012-09-05 17:12:55 -07004727 hddLog(VOS_TRACE_LEVEL_INFO, "%s is going to notify supplicant of:", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004728
4729 if( NULL == pRoamInfo )
4730 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08004731 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pRoamInfo is NULL", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004732 return -EINVAL;
4733 }
4734
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004735 if (eANI_BOOLEAN_TRUE == hdd_is_okc_mode_enabled(pHddCtx))
4736 {
4737 dump_bssid(pRoamInfo->bssid);
4738 cfg80211_pmksa_candidate_notify(dev, index,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004739 pRoamInfo->bssid, preauth, GFP_KERNEL);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004740 }
Jeff Johnsone7245742012-09-05 17:12:55 -07004741#endif /* FEATURE_WLAN_OKC */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304742 return 0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004743}
4744#endif //FEATURE_WLAN_LFR
4745
Yue Maef608272013-04-08 23:09:17 -07004746#ifdef FEATURE_WLAN_LFR_METRICS
4747/*
4748 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth
4749 * 802.11r/LFR metrics reporting function to report preauth initiation
4750 *
4751 */
4752#define MAX_LFR_METRICS_EVENT_LENGTH 100
4753VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth(hdd_adapter_t *pAdapter,
4754 tCsrRoamInfo *pRoamInfo)
4755{
4756 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
4757 union iwreq_data wrqu;
4758
4759 ENTER();
4760
4761 if (NULL == pAdapter)
4762 {
4763 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
4764 return VOS_STATUS_E_FAILURE;
4765 }
4766
4767 /* create the event */
4768 memset(&wrqu, 0, sizeof(wrqu));
4769 memset(metrics_notification, 0, sizeof(metrics_notification));
4770
4771 wrqu.data.pointer = metrics_notification;
4772 wrqu.data.length = scnprintf(metrics_notification,
4773 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_INIT "
4774 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
4775
4776 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
4777
4778 EXIT();
4779
4780 return VOS_STATUS_SUCCESS;
4781}
4782
4783/*
4784 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth_status
4785 * 802.11r/LFR metrics reporting function to report preauth completion
4786 * or failure
4787 */
4788VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth_status(
4789 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo, bool preauth_status)
4790{
4791 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
4792 union iwreq_data wrqu;
4793
4794 ENTER();
4795
4796 if (NULL == pAdapter)
4797 {
4798 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
4799 return VOS_STATUS_E_FAILURE;
4800 }
4801
4802 /* create the event */
4803 memset(&wrqu, 0, sizeof(wrqu));
4804 memset(metrics_notification, 0, sizeof(metrics_notification));
4805
4806 scnprintf(metrics_notification, sizeof(metrics_notification),
4807 "QCOM: LFR_PREAUTH_STATUS "MAC_ADDRESS_STR,
4808 MAC_ADDR_ARRAY(pRoamInfo->bssid));
4809
4810 if (1 == preauth_status)
4811 strncat(metrics_notification, " TRUE", 5);
4812 else
4813 strncat(metrics_notification, " FALSE", 6);
4814
4815 wrqu.data.pointer = metrics_notification;
4816 wrqu.data.length = strlen(metrics_notification);
4817
4818 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
4819
4820 EXIT();
4821
4822 return VOS_STATUS_SUCCESS;
4823}
4824
4825/*
4826 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_handover
4827 * 802.11r/LFR metrics reporting function to report handover initiation
4828 *
4829 */
4830VOS_STATUS wlan_hdd_cfg80211_roam_metrics_handover(hdd_adapter_t * pAdapter,
4831 tCsrRoamInfo *pRoamInfo)
4832{
4833 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
4834 union iwreq_data wrqu;
4835
4836 ENTER();
4837
4838 if (NULL == pAdapter)
4839 {
4840 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
4841 return VOS_STATUS_E_FAILURE;
4842 }
4843
4844 /* create the event */
4845 memset(&wrqu, 0, sizeof(wrqu));
4846 memset(metrics_notification, 0, sizeof(metrics_notification));
4847
4848 wrqu.data.pointer = metrics_notification;
4849 wrqu.data.length = scnprintf(metrics_notification,
4850 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_HANDOVER "
4851 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
4852
4853 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
4854
4855 EXIT();
4856
4857 return VOS_STATUS_SUCCESS;
4858}
4859#endif
4860
Jeff Johnson295189b2012-06-20 16:38:30 -07004861/*
4862 * FUNCTION: hdd_cfg80211_scan_done_callback
4863 * scanning callback function, called after finishing scan
4864 *
4865 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304866static eHalStatus hdd_cfg80211_scan_done_callback(tHalHandle halHandle,
Jeff Johnson295189b2012-06-20 16:38:30 -07004867 void *pContext, tANI_U32 scanId, eCsrScanStatus status)
4868{
4869 struct net_device *dev = (struct net_device *) pContext;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304870 //struct wireless_dev *wdev = dev->ieee80211_ptr;
Jeff Johnson295189b2012-06-20 16:38:30 -07004871 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07004872 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
4873 hdd_scaninfo_t *pScanInfo = &pHddCtx->scan_info;
Jeff Johnson295189b2012-06-20 16:38:30 -07004874 struct cfg80211_scan_request *req = NULL;
4875 int ret = 0;
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +05304876 bool aborted = false;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05304877 long waitRet = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07004878
4879 ENTER();
4880
4881 hddLog(VOS_TRACE_LEVEL_INFO,
4882 "%s called with halHandle = %p, pContext = %p,"
Arif Hussain6d2a3322013-11-17 19:50:10 -08004883 "scanID = %d, returned status = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07004884 __func__, halHandle, pContext, (int) scanId, (int) status);
4885
Kiet Lamac06e2c2013-10-23 16:25:07 +05304886 pScanInfo->mScanPendingCounter = 0;
4887
Jeff Johnson295189b2012-06-20 16:38:30 -07004888 //Block on scan req completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +05304889 waitRet = wait_for_completion_interruptible_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07004890 &pScanInfo->scan_req_completion_event,
4891 msecs_to_jiffies(WLAN_WAIT_TIME_SCAN_REQ));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05304892 if (waitRet <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -07004893 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05304894 hddLog(VOS_TRACE_LEVEL_ERROR,
4895 "%s wait on scan_req_completion_event failed %ld",__func__, waitRet);
Jeff Johnson295189b2012-06-20 16:38:30 -07004896 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -07004897 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -07004898 }
4899
Yue Maef608272013-04-08 23:09:17 -07004900 if (pScanInfo->mScanPending != VOS_TRUE)
Jeff Johnson295189b2012-06-20 16:38:30 -07004901 {
4902 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -07004903 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -07004904 }
4905
4906 /* Check the scanId */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304907 if (pScanInfo->scanId != scanId)
Jeff Johnson295189b2012-06-20 16:38:30 -07004908 {
4909 hddLog(VOS_TRACE_LEVEL_INFO,
4910 "%s called with mismatched scanId pScanInfo->scanId = %d "
Arif Hussain6d2a3322013-11-17 19:50:10 -08004911 "scanId = %d", __func__, (int) pScanInfo->scanId,
Jeff Johnson295189b2012-06-20 16:38:30 -07004912 (int) scanId);
4913 }
4914
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304915 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07004916 pAdapter);
4917
4918 if (0 > ret)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304919 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004920
4921
4922 /* If any client wait scan result through WEXT
4923 * send scan done event to client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07004924 if (pHddCtx->scan_info.waitScanResult)
Jeff Johnson295189b2012-06-20 16:38:30 -07004925 {
4926 /* The other scan request waiting for current scan finish
4927 * Send event to notify current scan finished */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07004928 if(WEXT_SCAN_PENDING_DELAY == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -07004929 {
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07004930 vos_event_set(&pHddCtx->scan_info.scan_finished_event);
Jeff Johnson295189b2012-06-20 16:38:30 -07004931 }
4932 /* Send notify to WEXT client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07004933 else if(WEXT_SCAN_PENDING_PIGGYBACK == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -07004934 {
4935 struct net_device *dev = pAdapter->dev;
4936 union iwreq_data wrqu;
4937 int we_event;
4938 char *msg;
4939
4940 memset(&wrqu, '\0', sizeof(wrqu));
4941 we_event = SIOCGIWSCAN;
4942 msg = NULL;
4943 wireless_send_event(dev, we_event, &wrqu, msg);
4944 }
4945 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07004946 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07004947
4948 /* Get the Scan Req */
4949 req = pAdapter->request;
4950
4951 if (!req)
4952 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08004953 hddLog(VOS_TRACE_LEVEL_ERROR, "request is became NULL");
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07004954 pScanInfo->mScanPending = VOS_FALSE;
Jeff Johnsone7245742012-09-05 17:12:55 -07004955 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -07004956 }
4957
4958 /*
4959 * setting up 0, just in case.
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304960 */
Jeff Johnson295189b2012-06-20 16:38:30 -07004961 req->n_ssids = 0;
4962 req->n_channels = 0;
4963 req->ie = 0;
4964
Jeff Johnson295189b2012-06-20 16:38:30 -07004965 pAdapter->request = NULL;
Jeff Johnsone7245742012-09-05 17:12:55 -07004966 /* Scan is no longer pending */
4967 pScanInfo->mScanPending = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07004968
Madan Mohan Koyyalamudib764bf82012-10-11 16:38:51 -07004969 /*
4970 * cfg80211_scan_done informing NL80211 about completion
4971 * of scanning
4972 */
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +05304973 if (status == eCSR_SCAN_ABORT || status == eCSR_SCAN_FAILURE)
4974 {
4975 aborted = true;
4976 }
4977 cfg80211_scan_done(req, aborted);
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -08004978 complete(&pScanInfo->abortscan_event_var);
Jeff Johnson295189b2012-06-20 16:38:30 -07004979
Jeff Johnsone7245742012-09-05 17:12:55 -07004980allow_suspend:
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07004981 /* release the wake lock at the end of the scan*/
4982 hdd_allow_suspend();
Jeff Johnsone7245742012-09-05 17:12:55 -07004983
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -07004984 /* Acquire wakelock to handle the case where APP's tries to suspend
4985 * immediatly after the driver gets connect request(i.e after scan)
4986 * from supplicant, this result in app's is suspending and not able
4987 * to process the connect request to AP */
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +05304988 hdd_prevent_suspend_timeout(1000);
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -07004989
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07004990#ifdef FEATURE_WLAN_TDLS
4991 wlan_hdd_tdls_scan_done_callback(pAdapter);
4992#endif
4993
Jeff Johnson295189b2012-06-20 16:38:30 -07004994 EXIT();
4995 return 0;
4996}
4997
4998/*
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08004999 * FUNCTION: hdd_isScanAllowed
5000 * Go through each adapter and check if scan allowed
5001 *
5002 */
5003v_BOOL_t hdd_isScanAllowed( hdd_context_t *pHddCtx )
5004{
5005 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
5006 hdd_station_ctx_t *pHddStaCtx = NULL;
5007 hdd_adapter_t *pAdapter = NULL;
5008 VOS_STATUS status = 0;
5009 v_U8_t staId = 0;
5010 v_U8_t *staMac = NULL;
5011
c_hpothu9b781ba2013-12-30 20:57:45 +05305012 if (TRUE == pHddCtx->btCoexModeSet)
5013 {
5014 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5015 FL("BTCoex Mode operation in progress, Do not allow scan"));
5016 return VOS_FALSE;
5017 }
5018
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08005019 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
5020
5021 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
5022 {
5023 pAdapter = pAdapterNode->pAdapter;
5024
5025 if( pAdapter )
5026 {
5027 hddLog(VOS_TRACE_LEVEL_INFO,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305028 "%s: Adapter with device mode %d exists",
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08005029 __func__, pAdapter->device_mode);
5030 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
5031 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
5032 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
5033 {
5034 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
5035 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
5036 (VOS_FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
5037 {
5038 staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]);
5039 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain24bafea2013-11-15 15:10:03 -08005040 "%s: client " MAC_ADDRESS_STR
5041 " is in the middle of WPS/EAPOL exchange.", __func__,
5042 MAC_ADDR_ARRAY(staMac));
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08005043 return VOS_FALSE;
5044 }
5045 }
5046 else if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) ||
5047 (WLAN_HDD_P2P_GO == pAdapter->device_mode))
5048 {
5049 for (staId = 0; staId < WLAN_MAX_STA_COUNT; staId++)
5050 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305051 if ((pAdapter->aStaInfo[staId].isUsed) &&
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08005052 (WLANTL_STA_CONNECTED == pAdapter->aStaInfo[staId].tlSTAState))
5053 {
5054 staMac = (v_U8_t *) &(pAdapter->aStaInfo[staId].macAddrSTA.bytes[0]);
5055
5056 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain24bafea2013-11-15 15:10:03 -08005057 "%s: client " MAC_ADDRESS_STR " of SoftAP/P2P-GO is in the "
5058 "middle of WPS/EAPOL exchange.", __func__,
5059 MAC_ADDR_ARRAY(staMac));
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08005060 return VOS_FALSE;
5061 }
5062 }
5063 }
5064 }
5065 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
5066 pAdapterNode = pNext;
5067 }
5068 hddLog(VOS_TRACE_LEVEL_INFO,
5069 "%s: Scan allowed", __func__);
5070 return VOS_TRUE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305071}
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08005072
5073/*
Jeff Johnson295189b2012-06-20 16:38:30 -07005074 * FUNCTION: wlan_hdd_cfg80211_scan
5075 * this scan respond to scan trigger and update cfg80211 scan database
5076 * later, scan dump command can be used to recieve scan results
5077 */
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -08005078int wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
5079#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
5080 struct net_device *dev,
5081#endif
5082 struct cfg80211_scan_request *request)
5083{
5084#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
5085 struct net_device *dev = request->wdev->netdev;
5086#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305087 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Jeff Johnson295189b2012-06-20 16:38:30 -07005088 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
5089 hdd_wext_state_t *pwextBuf = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305090 hdd_config_t *cfg_param = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07005091 tCsrScanRequest scanRequest;
5092 tANI_U8 *channelList = NULL, i;
5093 v_U32_t scanId = 0;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305094 int status;
5095 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07005096 v_U8_t* pP2pIe = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07005097
5098 ENTER();
5099
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05305100 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
5101 TRACE_CODE_HDD_CFG80211_SCAN,
5102 pAdapter->sessionId, request->n_channels));
5103
Arif Hussain6d2a3322013-11-17 19:50:10 -08005104 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07005105 __func__,pAdapter->device_mode);
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08005106
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305107 status = wlan_hdd_validate_context(pHddCtx);
5108
5109 if (0 != status)
5110 {
5111 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5112 "%s: HDD context is not valid", __func__);
5113 return status;
5114 }
5115
5116 cfg_param = pHddCtx->cfg_ini;
5117 pScanInfo = &pHddCtx->scan_info;
5118
Gopichand Nakkala681989c2013-03-06 22:27:48 -08005119 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08005120 (eConnectionState_Connecting ==
Gopichand Nakkala681989c2013-03-06 22:27:48 -08005121 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08005122 {
5123 hddLog(VOS_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08005124 "%s: %p(%d) Connection in progress: Scan request denied (EBUSY)", __func__, \
5125 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08005126 return -EBUSY;
5127 }
5128
Jeff Johnson295189b2012-06-20 16:38:30 -07005129#ifdef WLAN_BTAMP_FEATURE
5130 //Scan not supported when AMP traffic is on.
Gopichand Nakkala681989c2013-03-06 22:27:48 -08005131 if (VOS_TRUE == WLANBAP_AmpSessionOn())
Jeff Johnson295189b2012-06-20 16:38:30 -07005132 {
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08005133 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07005134 "%s: No scanning when AMP is on", __func__);
5135 return -EOPNOTSUPP;
5136 }
5137#endif
5138 //Scan on any other interface is not supported.
Gopichand Nakkala681989c2013-03-06 22:27:48 -08005139 if (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07005140 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -08005141 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07005142 "%s: Not scanning on device_mode = %d",
5143 __func__, pAdapter->device_mode);
5144 return -EOPNOTSUPP;
5145 }
5146
5147 if (TRUE == pScanInfo->mScanPending)
5148 {
Kiet Lamac06e2c2013-10-23 16:25:07 +05305149 if ( MAX_PENDING_LOG > pScanInfo->mScanPendingCounter++ )
5150 {
5151 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: mScanPending is TRUE", __func__);
5152 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08005153 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -07005154 }
5155
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305156 //Don't Allow Scan and return busy if Remain On
Jeff Johnson32d95a32012-09-10 13:15:23 -07005157 //Channel and action frame is pending
5158 //Otherwise Cancel Remain On Channel and allow Scan
5159 //If no action frame pending
Gopichand Nakkala681989c2013-03-06 22:27:48 -08005160 if (0 != wlan_hdd_check_remain_on_channel(pAdapter))
Jeff Johnson32d95a32012-09-10 13:15:23 -07005161 {
Kiet Lamac06e2c2013-10-23 16:25:07 +05305162 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Remain On Channel Pending", __func__);
Jeff Johnson32d95a32012-09-10 13:15:23 -07005163 return -EBUSY;
5164 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08005165#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07005166 /* if tdls disagree scan right now, return immediately.
5167 tdls will schedule the scan when scan is allowed. (return SUCCESS)
5168 or will reject the scan if any TDLS is in progress. (return -EBUSY)
5169 */
5170 status = wlan_hdd_tdls_scan_callback (pAdapter,
5171 wiphy,
5172#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
5173 dev,
Gopichand Nakkalac3c42b92013-03-20 19:42:34 -07005174#endif
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07005175 request);
5176 if(status <= 0)
5177 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05305178 if(!status)
5179 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS in progress."
5180 "scan rejected %d", __func__, status);
5181 else
5182 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS teardown is ongoing %d",
5183 __func__, status);
5184
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07005185 return status;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08005186 }
5187#endif
Jeff Johnson32d95a32012-09-10 13:15:23 -07005188
Jeff Johnson295189b2012-06-20 16:38:30 -07005189 if (mutex_lock_interruptible(&pHddCtx->tmInfo.tmOperationLock))
5190 {
5191 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_ERROR,
Jeff Johnson1250df42012-12-10 14:31:52 -08005192 "%s: Acquire lock fail", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005193 return -EAGAIN;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305194 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005195 if (TRUE == pHddCtx->tmInfo.tmAction.enterImps)
5196 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05305197 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07005198 "%s: MAX TM Level Scan not allowed", __func__);
5199 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305200 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -07005201 }
5202 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
5203
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08005204 /* Check if scan is allowed at this point of time.
5205 */
5206 if (!hdd_isScanAllowed(pHddCtx))
5207 {
5208 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Scan not allowed", __func__);
5209 return -EBUSY;
5210 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305211
Jeff Johnson295189b2012-06-20 16:38:30 -07005212 vos_mem_zero( &scanRequest, sizeof(scanRequest));
5213
5214 if (NULL != request)
5215 {
5216 hddLog(VOS_TRACE_LEVEL_INFO, "scan request for ssid = %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305217 (int)request->n_ssids);
Jeff Johnson295189b2012-06-20 16:38:30 -07005218
5219 /* Even though supplicant doesn't provide any SSIDs, n_ssids is set to 1.
5220 * Becasue of this, driver is assuming that this is not wildcard scan and so
5221 * is not aging out the scan results.
5222 */
Jeff Johnson32d95a32012-09-10 13:15:23 -07005223 if (request->ssids && '\0' == request->ssids->ssid[0])
Jeff Johnson295189b2012-06-20 16:38:30 -07005224 {
5225 request->n_ssids = 0;
5226 }
5227
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07005228 if ((request->ssids) && (0 < request->n_ssids))
Jeff Johnson295189b2012-06-20 16:38:30 -07005229 {
5230 tCsrSSIDInfo *SsidInfo;
5231 int j;
5232 scanRequest.SSIDs.numOfSSIDs = request->n_ssids;
5233 /* Allocate num_ssid tCsrSSIDInfo structure */
5234 SsidInfo = scanRequest.SSIDs.SSIDList =
5235 ( tCsrSSIDInfo *)vos_mem_malloc(
5236 request->n_ssids*sizeof(tCsrSSIDInfo));
5237
5238 if(NULL == scanRequest.SSIDs.SSIDList)
5239 {
5240 hddLog(VOS_TRACE_LEVEL_ERROR,
Nirav Shah20ac06f2013-12-12 18:14:06 +05305241 "%s: memory alloc failed SSIDInfo buffer", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005242 return -ENOMEM;
5243 }
5244
5245 /* copy all the ssid's and their length */
5246 for(j = 0; j < request->n_ssids; j++, SsidInfo++)
5247 {
5248 /* get the ssid length */
5249 SsidInfo->SSID.length = request->ssids[j].ssid_len;
5250 vos_mem_copy(SsidInfo->SSID.ssId, &request->ssids[j].ssid[0],
5251 SsidInfo->SSID.length);
5252 SsidInfo->SSID.ssId[SsidInfo->SSID.length] = '\0';
Nirav Shah20ac06f2013-12-12 18:14:06 +05305253 hddLog(VOS_TRACE_LEVEL_INFO, "SSID number %d: %s",
Jeff Johnson295189b2012-06-20 16:38:30 -07005254 j, SsidInfo->SSID.ssId);
5255 }
5256 /* set the scan type to active */
5257 scanRequest.scanType = eSIR_ACTIVE_SCAN;
5258 }
5259 else if(WLAN_HDD_P2P_GO == pAdapter->device_mode)
5260 {
5261 /* set the scan type to active */
5262 scanRequest.scanType = eSIR_ACTIVE_SCAN;
5263 }
5264 else
5265 {
5266 /*Set the scan type to default type, in this case it is ACTIVE*/
5267 scanRequest.scanType = pScanInfo->scan_mode;
5268 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305269 scanRequest.minChnTime = cfg_param->nActiveMinChnTime;
Jeff Johnson295189b2012-06-20 16:38:30 -07005270 scanRequest.maxChnTime = cfg_param->nActiveMaxChnTime;
5271 }
5272 else
5273 {
5274 /* set the scan type to active */
5275 scanRequest.scanType = eSIR_ACTIVE_SCAN;
5276 vos_mem_set( scanRequest.bssid, sizeof( tCsrBssid ), 0xff );
5277
5278 /* set min and max channel time to zero */
5279 scanRequest.minChnTime = 0;
5280 scanRequest.maxChnTime = 0;
5281 }
5282
5283 /* set BSSType to default type */
5284 scanRequest.BSSType = eCSR_BSS_TYPE_ANY;
5285
5286 /*TODO: scan the requested channels only*/
5287
5288 /*Right now scanning all the channels */
5289 if( request )
5290 {
c_hpothu53512302014-04-15 18:49:53 +05305291 if (MAX_CHANNEL < request->n_channels)
5292 {
5293 hddLog(VOS_TRACE_LEVEL_WARN,
5294 "No of Scan Channels exceeded limit: %d", request->n_channels);
5295 request->n_channels = MAX_CHANNEL;
5296 }
Nirav Shah20ac06f2013-12-12 18:14:06 +05305297 hddLog(VOS_TRACE_LEVEL_INFO,
5298 "No of Scan Channels: %d", request->n_channels);
c_hpothu53512302014-04-15 18:49:53 +05305299
Jeff Johnson295189b2012-06-20 16:38:30 -07005300 if( request->n_channels )
5301 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05305302 char chList [(request->n_channels*5)+1];
5303 int len;
Jeff Johnson295189b2012-06-20 16:38:30 -07005304 channelList = vos_mem_malloc( request->n_channels );
5305 if( NULL == channelList )
5306 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305307 hddLog(VOS_TRACE_LEVEL_ERROR,
Nirav Shah20ac06f2013-12-12 18:14:06 +05305308 "%s: memory alloc failed channelList", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005309 status = -ENOMEM;
5310 goto free_mem;
5311 }
5312
Nirav Shah20ac06f2013-12-12 18:14:06 +05305313 for( i = 0, len = 0; i < request->n_channels ; i++ )
5314 {
Jeff Johnson295189b2012-06-20 16:38:30 -07005315 channelList[i] = request->channels[i]->hw_value;
Nirav Shah20ac06f2013-12-12 18:14:06 +05305316 len += snprintf(chList+len, 5, "%d ", channelList[i]);
5317 }
5318
5319 hddLog(VOS_TRACE_LEVEL_INFO,
5320 "Channel-List: %s ", chList);
Jeff Johnson295189b2012-06-20 16:38:30 -07005321 }
5322
5323 scanRequest.ChannelInfo.numOfChannels = request->n_channels;
5324 scanRequest.ChannelInfo.ChannelList = channelList;
5325
5326 /* set requestType to full scan */
5327 scanRequest.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305328
5329 /* Flush the scan results(only p2p beacons) for STA scan and P2P
Madan Mohan Koyyalamudi8d50f312012-11-27 15:48:57 -08005330 * search (Flush on both full scan and social scan but not on single
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305331 * channel scan).P2P search happens on 3 social channels (1, 6, 11)
Madan Mohan Koyyalamudi8d50f312012-11-27 15:48:57 -08005332 */
5333
5334 /* Supplicant does single channel scan after 8-way handshake
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305335 * and in that case driver shoudnt flush scan results. If
5336 * driver flushes the scan results here and unfortunately if
5337 * the AP doesnt respond to our probe req then association
Madan Mohan Koyyalamudi8d50f312012-11-27 15:48:57 -08005338 * fails which is not desired
5339 */
5340
5341 if( request->n_channels != WLAN_HDD_P2P_SINGLE_CHANNEL_SCAN )
5342 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05305343 hddLog(VOS_TRACE_LEVEL_DEBUG, "Flushing P2P Results");
Madan Mohan Koyyalamudi8d50f312012-11-27 15:48:57 -08005344 sme_ScanFlushP2PResult( WLAN_HDD_GET_HAL_CTX(pAdapter),
5345 pAdapter->sessionId );
5346 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005347
5348 if( request->ie_len )
5349 {
5350 /* save this for future association (join requires this) */
Agarwal Ashish4f616132013-12-30 23:32:50 +05305351 /*TODO: Array needs to be converted to dynamic allocation,
5352 * as multiple ie.s can be sent in cfg80211_scan_request structure
5353 * CR 597966
5354 */
Jeff Johnson295189b2012-06-20 16:38:30 -07005355 memset( &pScanInfo->scanAddIE, 0, sizeof(pScanInfo->scanAddIE) );
5356 memcpy( pScanInfo->scanAddIE.addIEdata, request->ie, request->ie_len);
5357 pScanInfo->scanAddIE.length = request->ie_len;
5358
Agarwal Ashish4f616132013-12-30 23:32:50 +05305359 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Jeff Johnsone7245742012-09-05 17:12:55 -07005360 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
Agarwal Ashish4f616132013-12-30 23:32:50 +05305361 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -07005362 {
Agarwal Ashish4f616132013-12-30 23:32:50 +05305363 if ( request->ie_len <= SIR_MAC_MAX_IE_LENGTH)
5364 {
5365 pwextBuf->roamProfile.nAddIEScanLength = request->ie_len;
5366 memcpy( pwextBuf->roamProfile.addIEScan,
5367 request->ie, request->ie_len);
5368 }
5369 else
5370 {
5371 hddLog(VOS_TRACE_LEVEL_ERROR, "Scan Ie length is invalid:"
Arun Kumar Khandavalli75eeb122014-03-27 21:43:12 +05305372 "%zu", request->ie_len);
Agarwal Ashish4f616132013-12-30 23:32:50 +05305373 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005374
Agarwal Ashish4f616132013-12-30 23:32:50 +05305375 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005376 scanRequest.uIEFieldLen = pScanInfo->scanAddIE.length;
5377 scanRequest.pIEField = pScanInfo->scanAddIE.addIEdata;
5378
Jeff Johnson295189b2012-06-20 16:38:30 -07005379 pP2pIe = wlan_hdd_get_p2p_ie_ptr((v_U8_t*)request->ie,
5380 request->ie_len);
5381 if (pP2pIe != NULL)
5382 {
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07005383#ifdef WLAN_FEATURE_P2P_DEBUG
5384 if (((globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED) ||
5385 (globalP2PConnectionStatus == P2P_GO_NEG_PROCESS)) &&
5386 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
5387 {
5388 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_1;
5389 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
5390 "Go nego completed to Connection is started");
5391 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
5392 "for 8way Handshake");
5393 }
5394 else if((globalP2PConnectionStatus == P2P_CLIENT_DISCONNECTED_STATE) &&
5395 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
5396 {
5397 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_2;
5398 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
5399 "Disconnected state to Connection is started");
5400 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
5401 "for 4way Handshake");
5402 }
5403#endif
5404
Jeff Johnsone7245742012-09-05 17:12:55 -07005405 /* no_cck will be set during p2p find to disable 11b rates */
5406 if(TRUE == request->no_cck)
Jeff Johnson295189b2012-06-20 16:38:30 -07005407 {
Jeff Johnson295189b2012-06-20 16:38:30 -07005408 hddLog(VOS_TRACE_LEVEL_INFO,
5409 "%s: This is a P2P Search", __func__);
5410 scanRequest.p2pSearch = 1;
Jeff Johnsone7245742012-09-05 17:12:55 -07005411
Jeff Johnsone7245742012-09-05 17:12:55 -07005412 if( request->n_channels == WLAN_HDD_P2P_SOCIAL_CHANNELS )
5413 {
Madan Mohan Koyyalamudi1b1d9e82012-10-21 11:38:33 -07005414 /* set requestType to P2P Discovery */
5415 scanRequest.requestType = eCSR_SCAN_P2P_DISCOVERY;
Jeff Johnsone7245742012-09-05 17:12:55 -07005416 }
5417
5418 /*
5419 Skip Dfs Channel in case of P2P Search
5420 if it is set in ini file
5421 */
5422 if(cfg_param->skipDfsChnlInP2pSearch)
5423 {
5424 scanRequest.skipDfsChnlInP2pSearch = 1;
5425 }
5426 else
5427 {
5428 scanRequest.skipDfsChnlInP2pSearch = 0;
5429 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005430
Jeff Johnson295189b2012-06-20 16:38:30 -07005431 }
5432 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005433 }
5434 }
5435
5436 INIT_COMPLETION(pScanInfo->scan_req_completion_event);
5437
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07005438 /* acquire the wakelock to avoid the apps suspend during the scan. To
5439 * address the following issues.
5440 * 1) Disconnected scenario: we are not allowing the suspend as WLAN is not in
5441 * BMPS/IMPS this result in android trying to suspend aggressively and backing off
5442 * for long time, this result in apps running at full power for long time.
5443 * 2) Connected scenario: If we allow the suspend during the scan, RIVA will
5444 * be stuck in full power because of resume BMPS
5445 */
5446 hdd_prevent_suspend();
Jeff Johnsone7245742012-09-05 17:12:55 -07005447
Nirav Shah20ac06f2013-12-12 18:14:06 +05305448 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
5449 "requestType %d, scanType %d, minChnTime %d, maxChnTime %d,"
5450 "p2pSearch %d, skipDfsChnlInP2pSearch %d", scanRequest.requestType,
5451 scanRequest.scanType, scanRequest.minChnTime, scanRequest.maxChnTime,
5452 scanRequest.p2pSearch, scanRequest.skipDfsChnlInP2pSearch);
5453
Jeff Johnsone7245742012-09-05 17:12:55 -07005454 status = sme_ScanRequest( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07005455 pAdapter->sessionId, &scanRequest, &scanId,
5456 &hdd_cfg80211_scan_done_callback, dev );
Jeff Johnsone7245742012-09-05 17:12:55 -07005457
Jeff Johnson295189b2012-06-20 16:38:30 -07005458 if (eHAL_STATUS_SUCCESS != status)
5459 {
5460 hddLog(VOS_TRACE_LEVEL_ERROR,
5461 "%s: sme_ScanRequest returned error %d", __func__, status);
5462 complete(&pScanInfo->scan_req_completion_event);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -07005463 if(eHAL_STATUS_RESOURCES == status)
5464 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05305465 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: HO is in progress."
5466 "So defer the scan by informing busy",__func__);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -07005467 status = -EBUSY;
5468 } else {
5469 status = -EIO;
5470 }
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07005471 hdd_allow_suspend();
Jeff Johnson295189b2012-06-20 16:38:30 -07005472 goto free_mem;
5473 }
5474
5475 pScanInfo->mScanPending = TRUE;
5476 pAdapter->request = request;
5477 pScanInfo->scanId = scanId;
5478
5479 complete(&pScanInfo->scan_req_completion_event);
5480
5481free_mem:
5482 if( scanRequest.SSIDs.SSIDList )
5483 {
5484 vos_mem_free(scanRequest.SSIDs.SSIDList);
5485 }
5486
5487 if( channelList )
5488 vos_mem_free( channelList );
5489
5490 EXIT();
5491
5492 return status;
5493}
5494
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07005495
5496void hdd_select_cbmode( hdd_adapter_t *pAdapter,v_U8_t operationChannel)
5497{
5498 v_U8_t iniDot11Mode =
5499 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->dot11Mode;
5500 eHddDot11Mode hddDot11Mode = iniDot11Mode;
5501
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +05305502 hddLog(LOG1, FL("Channel Bonding Mode Selected is %u"),
5503 iniDot11Mode);
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07005504 switch ( iniDot11Mode )
5505 {
5506 case eHDD_DOT11_MODE_AUTO:
5507 case eHDD_DOT11_MODE_11ac:
5508 case eHDD_DOT11_MODE_11ac_ONLY:
5509#ifdef WLAN_FEATURE_11AC
5510 hddDot11Mode = eHDD_DOT11_MODE_11ac;
5511#else
5512 hddDot11Mode = eHDD_DOT11_MODE_11n;
5513#endif
5514 break;
5515 case eHDD_DOT11_MODE_11n:
5516 case eHDD_DOT11_MODE_11n_ONLY:
5517 hddDot11Mode = eHDD_DOT11_MODE_11n;
5518 break;
5519 default:
5520 hddDot11Mode = iniDot11Mode;
5521 break;
5522 }
5523 /* This call decides required channel bonding mode */
5524 sme_SelectCBMode((WLAN_HDD_GET_CTX(pAdapter)->hHal),
5525 hdd_cfg_xlate_to_csr_phy_mode(hddDot11Mode),
5526 operationChannel);
5527}
5528
Jeff Johnson295189b2012-06-20 16:38:30 -07005529/*
5530 * FUNCTION: wlan_hdd_cfg80211_connect_start
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305531 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -07005532 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305533int wlan_hdd_cfg80211_connect_start( hdd_adapter_t *pAdapter,
Jeff Johnson32d95a32012-09-10 13:15:23 -07005534 const u8 *ssid, size_t ssid_len, const u8 *bssid, u8 operatingChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -07005535{
5536 int status = 0;
5537 hdd_wext_state_t *pWextState;
Yue Mae36e3552014-03-05 17:06:20 -08005538 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07005539 v_U32_t roamId;
5540 tCsrRoamProfile *pRoamProfile;
Jeff Johnson295189b2012-06-20 16:38:30 -07005541 eCsrAuthType RSNAuthType;
5542
5543 ENTER();
5544
5545 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Yue Mae36e3552014-03-05 17:06:20 -08005546 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
5547
5548 status = wlan_hdd_validate_context(pHddCtx);
5549 if (status)
5550 {
5551 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5552 "%s: HDD context is not valid!", __func__);
5553 return status;
5554 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305555
Jeff Johnson295189b2012-06-20 16:38:30 -07005556 if (SIR_MAC_MAX_SSID_LENGTH < ssid_len)
5557 {
5558 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wrong SSID len", __func__);
5559 return -EINVAL;
5560 }
5561
5562 pRoamProfile = &pWextState->roamProfile;
5563
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305564 if (pRoamProfile)
Jeff Johnson295189b2012-06-20 16:38:30 -07005565 {
Jeff Johnsone7245742012-09-05 17:12:55 -07005566 hdd_station_ctx_t *pHddStaCtx;
5567 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07005568
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305569 if (HDD_WMM_USER_MODE_NO_QOS ==
Jeff Johnson295189b2012-06-20 16:38:30 -07005570 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->WmmMode)
5571 {
5572 /*QoS not enabled in cfg file*/
5573 pRoamProfile->uapsd_mask = 0;
5574 }
5575 else
5576 {
5577 /*QoS enabled, update uapsd mask from cfg file*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305578 pRoamProfile->uapsd_mask =
Jeff Johnson295189b2012-06-20 16:38:30 -07005579 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask;
5580 }
5581
5582 pRoamProfile->SSIDs.numOfSSIDs = 1;
5583 pRoamProfile->SSIDs.SSIDList->SSID.length = ssid_len;
5584 vos_mem_zero(pRoamProfile->SSIDs.SSIDList->SSID.ssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305585 sizeof(pRoamProfile->SSIDs.SSIDList->SSID.ssId));
Jeff Johnson295189b2012-06-20 16:38:30 -07005586 vos_mem_copy((void *)(pRoamProfile->SSIDs.SSIDList->SSID.ssId),
5587 ssid, ssid_len);
5588
5589 if (bssid)
5590 {
5591 pRoamProfile->BSSIDs.numOfBSSIDs = 1;
5592 vos_mem_copy((void *)(pRoamProfile->BSSIDs.bssid), bssid,
5593 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305594 /* Save BSSID in seperate variable as well, as RoamProfile
5595 BSSID is getting zeroed out in the association process. And in
Jeff Johnson295189b2012-06-20 16:38:30 -07005596 case of join failure we should send valid BSSID to supplicant
5597 */
5598 vos_mem_copy((void *)(pWextState->req_bssId), bssid,
5599 WNI_CFG_BSSID_LEN);
5600 }
Dhanashri Atre51981c62013-06-13 11:47:57 -07005601 else
5602 {
5603 vos_mem_zero((void *)(pRoamProfile->BSSIDs.bssid),WNI_CFG_BSSID_LEN);
5604 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005605
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +05305606 hddLog(LOG1, FL("Connect to SSID: %s opertating Channel: %u"),
5607 pRoamProfile->SSIDs.SSIDList->SSID.ssId, operatingChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -07005608 if ((IW_AUTH_WPA_VERSION_WPA == pWextState->wpaVersion) ||
5609 (IW_AUTH_WPA_VERSION_WPA2 == pWextState->wpaVersion))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305610 {
Jeff Johnson295189b2012-06-20 16:38:30 -07005611 /*set gen ie*/
5612 hdd_SetGENIEToCsr(pAdapter, &RSNAuthType);
5613 /*set auth*/
5614 hdd_set_csr_auth_type(pAdapter, RSNAuthType);
5615 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005616#ifdef FEATURE_WLAN_WAPI
5617 if (pAdapter->wapi_info.nWapiMode)
5618 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005619 hddLog(LOG1, "%s: Setting WAPI AUTH Type and Encryption Mode values", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005620 switch (pAdapter->wapi_info.wapiAuthMode)
5621 {
5622 case WAPI_AUTH_MODE_PSK:
5623 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005624 hddLog(LOG1, "%s: WAPI AUTH TYPE: PSK: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07005625 pAdapter->wapi_info.wapiAuthMode);
5626 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_PSK;
5627 break;
5628 }
5629 case WAPI_AUTH_MODE_CERT:
5630 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005631 hddLog(LOG1, "%s: WAPI AUTH TYPE: CERT: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07005632 pAdapter->wapi_info.wapiAuthMode);
5633 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE;
5634 break;
5635 }
5636 } // End of switch
5637 if ( pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_PSK ||
5638 pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_CERT)
5639 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005640 hddLog(LOG1, "%s: WAPI PAIRWISE/GROUP ENCRYPTION: WPI", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005641 pRoamProfile->AuthType.numEntries = 1;
5642 pRoamProfile->EncryptionType.numEntries = 1;
5643 pRoamProfile->EncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
5644 pRoamProfile->mcEncryptionType.numEntries = 1;
5645 pRoamProfile->mcEncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
5646 }
5647 }
5648#endif /* FEATURE_WLAN_WAPI */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05305649#ifdef WLAN_FEATURE_GTK_OFFLOAD
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05305650 /* Initializing gtkOffloadReqParams */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05305651 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
5652 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
5653 {
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05305654 memset(&pHddStaCtx->gtkOffloadReqParams, 0,
5655 sizeof (tSirGtkOffloadParams));
5656 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_DISABLE;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05305657 }
5658#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005659 pRoamProfile->csrPersona = pAdapter->device_mode;
5660
Jeff Johnson32d95a32012-09-10 13:15:23 -07005661 if( operatingChannel )
5662 {
5663 pRoamProfile->ChannelInfo.ChannelList = &operatingChannel;
5664 pRoamProfile->ChannelInfo.numOfChannels = 1;
5665 }
Chet Lanctot186b5732013-03-18 10:26:30 -07005666 else
5667 {
5668 pRoamProfile->ChannelInfo.ChannelList = NULL;
5669 pRoamProfile->ChannelInfo.numOfChannels = 0;
5670 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07005671 if ( (WLAN_HDD_IBSS == pAdapter->device_mode) && operatingChannel)
5672 {
5673 hdd_select_cbmode(pAdapter,operatingChannel);
5674 }
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +05305675
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08005676 /* change conn_state to connecting before sme_RoamConnect(), because sme_RoamConnect()
5677 * has a direct path to call hdd_smeRoamCallback(), which will change the conn_state
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305678 * If direct path, conn_state will be accordingly changed to NotConnected or Associated
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08005679 * by either hdd_AssociationCompletionHandler() or hdd_DisConnectHandler() in sme_RoamCallback()
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -08005680 * if sme_RomConnect is to be queued, Connecting state will remain until it is completed.
5681 */
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05305682 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
5683 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode)
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -08005684 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
5685 eConnectionState_Connecting);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305686
5687 status = sme_RoamConnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07005688 pAdapter->sessionId, pRoamProfile, &roamId);
5689
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05305690 if ((eHAL_STATUS_SUCCESS != status) &&
5691 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
5692 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +05305693
5694 {
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08005695 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: sme_RoamConnect (session %d) failed with "
5696 "status %d. -> NotConnected", __func__, pAdapter->sessionId, status);
5697 /* change back to NotAssociated */
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +05305698 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08005699 eConnectionState_NotConnected);
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +05305700 }
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -08005701
5702 pRoamProfile->ChannelInfo.ChannelList = NULL;
5703 pRoamProfile->ChannelInfo.numOfChannels = 0;
5704
Jeff Johnson295189b2012-06-20 16:38:30 -07005705 }
5706 else
5707 {
5708 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid Roam profile", __func__);
5709 return -EINVAL;
5710 }
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08005711 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07005712 return status;
5713}
5714
5715/*
5716 * FUNCTION: wlan_hdd_set_cfg80211_auth_type
5717 * This function is used to set the authentication type (OPEN/SHARED).
5718 *
5719 */
5720static int wlan_hdd_cfg80211_set_auth_type(hdd_adapter_t *pAdapter,
5721 enum nl80211_auth_type auth_type)
5722{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305723 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07005724 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
5725
5726 ENTER();
5727
5728 /*set authentication type*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305729 switch (auth_type)
Jeff Johnson295189b2012-06-20 16:38:30 -07005730 {
Jeff Johnson295189b2012-06-20 16:38:30 -07005731 case NL80211_AUTHTYPE_AUTOMATIC:
Gopichand Nakkala29149562013-05-10 21:43:41 +05305732 hddLog(VOS_TRACE_LEVEL_INFO,
5733 "%s: set authentication type to AUTOSWITCH", __func__);
5734 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_AUTOSWITCH;
5735 break;
5736
5737 case NL80211_AUTHTYPE_OPEN_SYSTEM:
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07005738#ifdef WLAN_FEATURE_VOWIFI_11R
5739 case NL80211_AUTHTYPE_FT:
5740#endif /* WLAN_FEATURE_VOWIFI_11R */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305741 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -07005742 "%s: set authentication type to OPEN", __func__);
5743 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
5744 break;
5745
5746 case NL80211_AUTHTYPE_SHARED_KEY:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305747 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -07005748 "%s: set authentication type to SHARED", __func__);
5749 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_SHARED_KEY;
5750 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005751#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -07005752 case NL80211_AUTHTYPE_NETWORK_EAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305753 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -07005754 "%s: set authentication type to CCKM WPA", __func__);
5755 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_CCKM_WPA;//eCSR_AUTH_TYPE_CCKM_RSN needs to be handled as well if required.
5756 break;
5757#endif
5758
5759
5760 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305761 hddLog(VOS_TRACE_LEVEL_ERROR,
5762 "%s: Unsupported authentication type %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07005763 auth_type);
5764 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_UNKNOWN;
5765 return -EINVAL;
5766 }
5767
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305768 pWextState->roamProfile.AuthType.authType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -07005769 pHddStaCtx->conn_info.authType;
5770 return 0;
5771}
5772
5773/*
5774 * FUNCTION: wlan_hdd_set_akm_suite
5775 * This function is used to set the key mgmt type(PSK/8021x).
5776 *
5777 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305778static int wlan_hdd_set_akm_suite( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07005779 u32 key_mgmt
5780 )
5781{
5782 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
5783 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305784
Jeff Johnson295189b2012-06-20 16:38:30 -07005785 /*set key mgmt type*/
5786 switch(key_mgmt)
5787 {
5788 case WLAN_AKM_SUITE_PSK:
Gopichand Nakkala356fb102013-03-06 12:34:04 +05305789#ifdef WLAN_FEATURE_VOWIFI_11R
5790 case WLAN_AKM_SUITE_FT_PSK:
5791#endif
5792 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to PSK",
Jeff Johnson295189b2012-06-20 16:38:30 -07005793 __func__);
5794 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_PSK;
5795 break;
5796
5797 case WLAN_AKM_SUITE_8021X:
Gopichand Nakkala356fb102013-03-06 12:34:04 +05305798#ifdef WLAN_FEATURE_VOWIFI_11R
5799 case WLAN_AKM_SUITE_FT_8021X:
5800#endif
5801 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to 8021x",
Jeff Johnson295189b2012-06-20 16:38:30 -07005802 __func__);
5803 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
5804 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005805#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -07005806#define WLAN_AKM_SUITE_CCKM 0x00409600 /* Should be in ieee802_11_defs.h */
5807#define IW_AUTH_KEY_MGMT_CCKM 8 /* Should be in linux/wireless.h */
5808 case WLAN_AKM_SUITE_CCKM:
5809 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to CCKM",
5810 __func__);
5811 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_CCKM;
5812 break;
5813#endif
5814
5815 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305816 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported key mgmt type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07005817 __func__, key_mgmt);
5818 return -EINVAL;
5819
5820 }
5821 return 0;
5822}
5823
5824/*
5825 * FUNCTION: wlan_hdd_cfg80211_set_cipher
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305826 * This function is used to set the encryption type
Jeff Johnson295189b2012-06-20 16:38:30 -07005827 * (NONE/WEP40/WEP104/TKIP/CCMP).
5828 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305829static int wlan_hdd_cfg80211_set_cipher( hdd_adapter_t *pAdapter,
5830 u32 cipher,
Jeff Johnson295189b2012-06-20 16:38:30 -07005831 bool ucast
5832 )
5833{
5834 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305835 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07005836 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
5837
5838 ENTER();
5839
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305840 if (!cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -07005841 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305842 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: received cipher %d - considering none",
Jeff Johnson295189b2012-06-20 16:38:30 -07005843 __func__, cipher);
5844 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
5845 }
5846 else
5847 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305848
Jeff Johnson295189b2012-06-20 16:38:30 -07005849 /*set encryption method*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305850 switch (cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -07005851 {
5852 case IW_AUTH_CIPHER_NONE:
5853 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
5854 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305855
Jeff Johnson295189b2012-06-20 16:38:30 -07005856 case WLAN_CIPHER_SUITE_WEP40:
Gopichand Nakkala29149562013-05-10 21:43:41 +05305857 encryptionType = eCSR_ENCRYPT_TYPE_WEP40;
Jeff Johnson295189b2012-06-20 16:38:30 -07005858 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305859
Jeff Johnson295189b2012-06-20 16:38:30 -07005860 case WLAN_CIPHER_SUITE_WEP104:
Gopichand Nakkala29149562013-05-10 21:43:41 +05305861 encryptionType = eCSR_ENCRYPT_TYPE_WEP104;
Jeff Johnson295189b2012-06-20 16:38:30 -07005862 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305863
Jeff Johnson295189b2012-06-20 16:38:30 -07005864 case WLAN_CIPHER_SUITE_TKIP:
5865 encryptionType = eCSR_ENCRYPT_TYPE_TKIP;
5866 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305867
Jeff Johnson295189b2012-06-20 16:38:30 -07005868 case WLAN_CIPHER_SUITE_CCMP:
5869 encryptionType = eCSR_ENCRYPT_TYPE_AES;
5870 break;
5871#ifdef FEATURE_WLAN_WAPI
5872 case WLAN_CIPHER_SUITE_SMS4:
5873 encryptionType = eCSR_ENCRYPT_TYPE_WPI;
5874 break;
5875#endif
5876
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005877#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -07005878 case WLAN_CIPHER_SUITE_KRK:
5879 encryptionType = eCSR_ENCRYPT_TYPE_KRK;
5880 break;
5881#endif
5882 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305883 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported cipher type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07005884 __func__, cipher);
5885 return -EOPNOTSUPP;
5886 }
5887 }
5888
5889 if (ucast)
5890 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305891 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting unicast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07005892 __func__, encryptionType);
5893 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
5894 pWextState->roamProfile.EncryptionType.numEntries = 1;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305895 pWextState->roamProfile.EncryptionType.encryptionType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -07005896 encryptionType;
5897 }
5898 else
5899 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305900 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting mcast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07005901 __func__, encryptionType);
5902 pHddStaCtx->conn_info.mcEncryptionType = encryptionType;
5903 pWextState->roamProfile.mcEncryptionType.numEntries = 1;
5904 pWextState->roamProfile.mcEncryptionType.encryptionType[0] = encryptionType;
5905 }
5906
5907 return 0;
5908}
5909
5910
5911/*
5912 * FUNCTION: wlan_hdd_cfg80211_set_ie
5913 * This function is used to parse WPA/RSN IE's.
5914 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305915int wlan_hdd_cfg80211_set_ie( hdd_adapter_t *pAdapter,
5916 u8 *ie,
Jeff Johnson295189b2012-06-20 16:38:30 -07005917 size_t ie_len
5918 )
5919{
5920 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
5921 u8 *genie = ie;
5922 v_U16_t remLen = ie_len;
5923#ifdef FEATURE_WLAN_WAPI
5924 v_U32_t akmsuite[MAX_NUM_AKM_SUITES];
5925 u16 *tmp;
5926 v_U16_t akmsuiteCount;
5927 int *akmlist;
5928#endif
5929 ENTER();
5930
5931 /* clear previous assocAddIE */
5932 pWextState->assocAddIE.length = 0;
5933 pWextState->roamProfile.bWPSAssociation = VOS_FALSE;
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -07005934 pWextState->roamProfile.bOSENAssociation = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07005935
5936 while (remLen >= 2)
5937 {
5938 v_U16_t eLen = 0;
5939 v_U8_t elementId;
5940 elementId = *genie++;
5941 eLen = *genie++;
5942 remLen -= 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305943
Arif Hussain6d2a3322013-11-17 19:50:10 -08005944 hddLog(VOS_TRACE_LEVEL_INFO, "%s: IE[0x%X], LEN[%d]",
Jeff Johnson295189b2012-06-20 16:38:30 -07005945 __func__, elementId, eLen);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305946
5947 switch ( elementId )
Jeff Johnson295189b2012-06-20 16:38:30 -07005948 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305949 case DOT11F_EID_WPA:
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005950 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 -07005951 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305952 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07005953 "%s: Invalid WPA IE", __func__);
5954 return -EINVAL;
5955 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305956 else if (0 == memcmp(&genie[0], "\x00\x50\xf2\x04", 4))
Jeff Johnson295189b2012-06-20 16:38:30 -07005957 {
5958 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305959 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPS IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -07005960 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305961
Jeff Johnson295189b2012-06-20 16:38:30 -07005962 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
5963 {
Jeff Johnson902c9832012-12-10 14:28:09 -08005964 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE. "
5965 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -07005966 VOS_ASSERT(0);
5967 return -ENOMEM;
5968 }
5969 // WSC IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
5970 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
5971 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305972
Jeff Johnson295189b2012-06-20 16:38:30 -07005973 pWextState->roamProfile.bWPSAssociation = VOS_TRUE;
5974 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
5975 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
5976 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305977 else if (0 == memcmp(&genie[0], "\x00\x50\xf2", 3))
5978 {
Jeff Johnson295189b2012-06-20 16:38:30 -07005979 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPA IE (len %d)",__func__, eLen + 2);
5980 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
5981 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2) /*ie_len*/);
5982 pWextState->roamProfile.pWPAReqIE = pWextState->WPARSNIE;
5983 pWextState->roamProfile.nWPAReqIELength = eLen + 2;//ie_len;
5984 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305985 else if ( (0 == memcmp(&genie[0], P2P_OUI_TYPE,
Kiet Lam8da98992013-11-21 15:59:07 +05305986 P2P_OUI_TYPE_SIZE)))
Jeff Johnson295189b2012-06-20 16:38:30 -07005987 {
5988 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305989 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set P2P IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -07005990 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305991
Jeff Johnson295189b2012-06-20 16:38:30 -07005992 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
5993 {
Jeff Johnson902c9832012-12-10 14:28:09 -08005994 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
5995 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -07005996 VOS_ASSERT(0);
5997 return -ENOMEM;
5998 }
5999 // P2P IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
6000 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
6001 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306002
Jeff Johnson295189b2012-06-20 16:38:30 -07006003 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
6004 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
6005 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006006#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306007 else if ( (0 == memcmp(&genie[0], WFD_OUI_TYPE,
6008 WFD_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07006009 /*Consider WFD IE, only for P2P Client */
6010 && (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
6011 {
6012 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306013 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WFD IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -07006014 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306015
Jeff Johnson295189b2012-06-20 16:38:30 -07006016 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
6017 {
Jeff Johnson902c9832012-12-10 14:28:09 -08006018 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
6019 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -07006020 VOS_ASSERT(0);
6021 return -ENOMEM;
6022 }
6023 // WFD IE is saved to Additional IE ; it should be accumulated to handle
6024 // WPS IE + P2P IE + WFD IE
6025 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
6026 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306027
Jeff Johnson295189b2012-06-20 16:38:30 -07006028 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
6029 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
6030 }
6031#endif
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07006032 /* Appending HS 2.0 Indication Element in Assiciation Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306033 else if ( (0 == memcmp(&genie[0], HS20_OUI_TYPE,
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07006034 HS20_OUI_TYPE_SIZE)) )
6035 {
6036 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306037 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set HS20 IE(len %d)",
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07006038 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07006039
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07006040 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
6041 {
Jeff Johnson902c9832012-12-10 14:28:09 -08006042 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
6043 "Need bigger buffer space");
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07006044 VOS_ASSERT(0);
6045 return -ENOMEM;
6046 }
6047 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
6048 pWextState->assocAddIE.length += eLen + 2;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07006049
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07006050 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
6051 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
6052 }
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -07006053 /* Appending OSEN Information Element in Assiciation Request */
6054 else if ( (0 == memcmp(&genie[0], OSEN_OUI_TYPE,
6055 OSEN_OUI_TYPE_SIZE)) )
6056 {
6057 v_U16_t curAddIELen = pWextState->assocAddIE.length;
6058 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set OSEN IE(len %d)",
6059 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07006060
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -07006061 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
6062 {
6063 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
6064 "Need bigger buffer space");
6065 VOS_ASSERT(0);
6066 return -ENOMEM;
6067 }
6068 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
6069 pWextState->assocAddIE.length += eLen + 2;
6070
6071 pWextState->roamProfile.bOSENAssociation = VOS_TRUE;
6072 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
6073 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
6074 }
6075
6076 break;
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -07006077 if (WLAN_HDD_IBSS == pAdapter->device_mode) {
6078
6079 /* populating as ADDIE in beacon frames */
6080 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
6081 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, genie - 2, eLen + 2,
6082 NULL, eANI_BOOLEAN_FALSE)== eHAL_STATUS_SUCCESS)
6083 {
6084 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
6085 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
6086 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
6087 {
6088 hddLog(LOGE,
6089 "Coldn't pass "
6090 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
6091 }
6092 }/* ccmCfgSetStr(,WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, , )*/
6093 else
6094 hddLog(LOGE,
6095 "Could not pass on "
6096 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
6097
6098 /* IBSS mode doesn't contain params->proberesp_ies still
6099 beaconIE's need to be populated in probe response frames */
6100 if ( (NULL != (genie - 2)) && (0 != eLen + 2) )
6101 {
6102 u16 rem_probe_resp_ie_len = eLen + 2;
6103 u8 probe_rsp_ie_len[3] = {0};
6104 u8 counter = 0;
6105
6106 /* Check Probe Resp Length if it is greater then 255 then
6107 Store Probe Rsp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1
6108 & WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are
6109 not able Store More then 255 bytes into One Variable */
6110
6111 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
6112 {
6113 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
6114 {
6115 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
6116 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
6117 }
6118 else
6119 {
6120 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
6121 rem_probe_resp_ie_len = 0;
6122 }
6123 }
6124
6125 rem_probe_resp_ie_len = 0;
6126
6127 if (probe_rsp_ie_len[0] > 0)
6128 {
6129 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
6130 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
6131 (tANI_U8*)(genie - 2),
6132 probe_rsp_ie_len[0], NULL,
6133 eANI_BOOLEAN_FALSE)
6134 == eHAL_STATUS_FAILURE)
6135 {
6136 hddLog(LOGE,
6137 "Could not pass"
6138 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
6139 }
6140 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
6141 }
6142
6143 if (probe_rsp_ie_len[1] > 0)
6144 {
6145 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
6146 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
6147 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
6148 probe_rsp_ie_len[1], NULL,
6149 eANI_BOOLEAN_FALSE)
6150 == eHAL_STATUS_FAILURE)
6151 {
6152 hddLog(LOGE,
6153 "Could not pass"
6154 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
6155 }
6156 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
6157 }
6158
6159 if (probe_rsp_ie_len[2] > 0)
6160 {
6161 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
6162 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
6163 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
6164 probe_rsp_ie_len[2], NULL,
6165 eANI_BOOLEAN_FALSE)
6166 == eHAL_STATUS_FAILURE)
6167 {
6168 hddLog(LOGE,
6169 "Could not pass"
6170 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
6171 }
6172 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
6173 }
6174
6175 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
6176 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
6177 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
6178 {
6179 hddLog(LOGE,
6180 "Could not pass"
6181 "on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
6182 }
6183 }
6184 else
6185 {
6186 // Reset WNI_CFG_PROBE_RSP Flags
6187 wlan_hdd_reset_prob_rspies(pAdapter);
6188
6189 hddLog(VOS_TRACE_LEVEL_INFO,
6190 "%s: No Probe Response IE received in set beacon",
6191 __func__);
6192 }
6193 } /* end of if (WLAN_HDD_IBSS == pAdapter->device_mode) */
Jeff Johnson295189b2012-06-20 16:38:30 -07006194 break;
6195 case DOT11F_EID_RSN:
6196 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set RSN IE(len %d)",__func__, eLen + 2);
6197 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
6198 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2)/*ie_len*/);
6199 pWextState->roamProfile.pRSNReqIE = pWextState->WPARSNIE;
6200 pWextState->roamProfile.nRSNReqIELength = eLen + 2; //ie_len;
6201 break;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07006202 /* Appending Extended Capabilities with Interworking bit set in Assoc Req */
6203 case DOT11F_EID_EXTCAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306204 {
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07006205 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306206 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set Extended CAPS IE(len %d)",
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07006207 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306208
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07006209 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
6210 {
Jeff Johnson902c9832012-12-10 14:28:09 -08006211 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
6212 "Need bigger buffer space");
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07006213 VOS_ASSERT(0);
6214 return -ENOMEM;
6215 }
6216 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
6217 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306218
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07006219 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
6220 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
6221 break;
6222 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006223#ifdef FEATURE_WLAN_WAPI
6224 case WLAN_EID_WAPI:
6225 pAdapter->wapi_info.nWapiMode = 1; //Setting WAPI Mode to ON=1
Jeff Johnson0299d0a2013-10-30 12:37:43 -07006226 hddLog(VOS_TRACE_LEVEL_INFO, "WAPI MODE IS %u",
Jeff Johnson295189b2012-06-20 16:38:30 -07006227 pAdapter->wapi_info.nWapiMode);
6228 tmp = (u16 *)ie;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306229 tmp = tmp + 2; // Skip element Id and Len, Version
Jeff Johnson295189b2012-06-20 16:38:30 -07006230 akmsuiteCount = WPA_GET_LE16(tmp);
6231 tmp = tmp + 1;
6232 akmlist = (int *)(tmp);
6233 if(akmsuiteCount <= MAX_NUM_AKM_SUITES)
6234 {
6235 memcpy(akmsuite, akmlist, (4*akmsuiteCount));
6236 }
6237 else
6238 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08006239 hddLog(VOS_TRACE_LEVEL_FATAL, "Invalid akmSuite count");
Jeff Johnson295189b2012-06-20 16:38:30 -07006240 VOS_ASSERT(0);
6241 return -EINVAL;
6242 }
6243
6244 if (WAPI_PSK_AKM_SUITE == akmsuite[0])
6245 {
6246 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO PSK",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006247 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006248 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_PSK;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306249 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006250 if (WAPI_CERT_AKM_SUITE == akmsuite[0])
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306251 {
Jeff Johnson295189b2012-06-20 16:38:30 -07006252 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO CERTIFICATE",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006253 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006254 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_CERT;
6255 }
6256 break;
6257#endif
6258 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306259 hddLog (VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07006260 "%s Set UNKNOWN IE %X", __func__, elementId);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07006261 /* when Unknown IE is received we should break and continue
6262 * to the next IE in the buffer instead we were returning
6263 * so changing this to break */
6264 break;
Jeff Johnson295189b2012-06-20 16:38:30 -07006265 }
6266 genie += eLen;
6267 remLen -= eLen;
6268 }
6269 EXIT();
6270 return 0;
6271}
6272
6273/*
Gopichand Nakkala18f0c262013-05-07 23:25:08 +05306274 * FUNCTION: hdd_isWPAIEPresent
6275 * Parse the received IE to find the WPA IE
6276 *
6277 */
6278static bool hdd_isWPAIEPresent(u8 *ie, u8 ie_len)
6279{
6280 v_U8_t eLen = 0;
6281 v_U16_t remLen = ie_len;
6282 v_U8_t elementId = 0;
6283
6284 while (remLen >= 2)
6285 {
6286 elementId = *ie++;
6287 eLen = *ie++;
6288 remLen -= 2;
6289 if (eLen > remLen)
6290 {
6291 hddLog(VOS_TRACE_LEVEL_ERROR,
6292 "%s: IE length is wrong %d", __func__, eLen);
6293 return FALSE;
6294 }
6295 if ((elementId == DOT11F_EID_WPA) && (remLen > 5))
6296 {
6297 /* OUI - 0x00 0X50 0XF2
6298 WPA Information Element - 0x01
6299 WPA version - 0x01*/
6300 if (0 == memcmp(&ie[0], "\x00\x50\xf2\x01\x01", 5))
6301 return TRUE;
6302 }
6303 ie += eLen;
6304 remLen -= eLen;
6305 }
6306 return FALSE;
6307}
6308
6309/*
Jeff Johnson295189b2012-06-20 16:38:30 -07006310 * FUNCTION: wlan_hdd_cfg80211_set_privacy
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306311 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -07006312 * parameters during connect operation.
6313 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306314int wlan_hdd_cfg80211_set_privacy( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07006315 struct cfg80211_connect_params *req
6316 )
6317{
6318 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306319 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07006320 ENTER();
6321
6322 /*set wpa version*/
6323 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
6324
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306325 if (req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -07006326 {
Gopichand Nakkala781ded42013-06-28 12:10:45 +05306327 if (NL80211_WPA_VERSION_1 == req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -07006328 {
6329 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
6330 }
6331 else if (NL80211_WPA_VERSION_2 == req->crypto.wpa_versions)
6332 {
6333 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
6334 }
6335 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306336
6337 hddLog(VOS_TRACE_LEVEL_INFO, "%s: set wpa version to %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07006338 pWextState->wpaVersion);
6339
6340 /*set authentication type*/
6341 status = wlan_hdd_cfg80211_set_auth_type(pAdapter, req->auth_type);
6342
6343 if (0 > status)
6344 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306345 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07006346 "%s: failed to set authentication type ", __func__);
6347 return status;
6348 }
6349
6350 /*set key mgmt type*/
6351 if (req->crypto.n_akm_suites)
6352 {
6353 status = wlan_hdd_set_akm_suite(pAdapter, req->crypto.akm_suites[0]);
6354 if (0 > status)
6355 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306356 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set akm suite",
Jeff Johnson295189b2012-06-20 16:38:30 -07006357 __func__);
6358 return status;
6359 }
6360 }
6361
6362 /*set pairwise cipher type*/
6363 if (req->crypto.n_ciphers_pairwise)
6364 {
6365 status = wlan_hdd_cfg80211_set_cipher(pAdapter,
6366 req->crypto.ciphers_pairwise[0], true);
6367 if (0 > status)
6368 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306369 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07006370 "%s: failed to set unicast cipher type", __func__);
6371 return status;
6372 }
6373 }
6374 else
6375 {
6376 /*Reset previous cipher suite to none*/
6377 status = wlan_hdd_cfg80211_set_cipher(pAdapter, 0, true);
6378 if (0 > status)
6379 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306380 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07006381 "%s: failed to set unicast cipher type", __func__);
6382 return status;
6383 }
6384 }
6385
6386 /*set group cipher type*/
6387 status = wlan_hdd_cfg80211_set_cipher(pAdapter, req->crypto.cipher_group,
6388 false);
6389
6390 if (0 > status)
6391 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306392 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set mcast cipher type",
Jeff Johnson295189b2012-06-20 16:38:30 -07006393 __func__);
6394 return status;
6395 }
6396
Chet Lanctot186b5732013-03-18 10:26:30 -07006397#ifdef WLAN_FEATURE_11W
6398 pWextState->roamProfile.MFPEnabled = (req->mfp == NL80211_MFP_REQUIRED);
6399#endif
6400
Jeff Johnson295189b2012-06-20 16:38:30 -07006401 /*parse WPA/RSN IE, and set the correspoing fileds in Roam profile*/
6402 if (req->ie_len)
6403 {
6404 status = wlan_hdd_cfg80211_set_ie(pAdapter, req->ie, req->ie_len);
6405 if ( 0 > status)
6406 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306407 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse the WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -07006408 __func__);
6409 return status;
6410 }
6411 }
6412
6413 /*incase of WEP set default key information*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306414 if (req->key && req->key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -07006415 {
6416 if ( (WLAN_CIPHER_SUITE_WEP40 == req->crypto.ciphers_pairwise[0])
6417 || (WLAN_CIPHER_SUITE_WEP104 == req->crypto.ciphers_pairwise[0])
6418 )
6419 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306420 if ( IW_AUTH_KEY_MGMT_802_1X
Jeff Johnson295189b2012-06-20 16:38:30 -07006421 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X ))
6422 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306423 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Dynamic WEP not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -07006424 __func__);
6425 return -EOPNOTSUPP;
6426 }
6427 else
6428 {
6429 u8 key_len = req->key_len;
6430 u8 key_idx = req->key_idx;
6431
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306432 if ((eCSR_SECURITY_WEP_KEYSIZE_MAX_BYTES >= key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -07006433 && (CSR_MAX_NUM_KEY > key_idx)
6434 )
6435 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306436 hddLog(VOS_TRACE_LEVEL_INFO,
6437 "%s: setting default wep key, key_idx = %hu key_len %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07006438 __func__, key_idx, key_len);
6439 vos_mem_copy(
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306440 &pWextState->roamProfile.Keys.KeyMaterial[key_idx][0],
Jeff Johnson295189b2012-06-20 16:38:30 -07006441 req->key, key_len);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306442 pWextState->roamProfile.Keys.KeyLength[key_idx] =
Jeff Johnson295189b2012-06-20 16:38:30 -07006443 (u8)key_len;
6444 pWextState->roamProfile.Keys.defaultIndex = (u8)key_idx;
6445 }
6446 }
6447 }
6448 }
6449
6450 return status;
6451}
6452
6453/*
Vinay Krishna Eranna21042322014-01-08 19:21:39 +05306454 * FUNCTION: wlan_hdd_try_disconnect
6455 * This function is used to disconnect from previous
6456 * connection
6457 */
6458static int wlan_hdd_try_disconnect( hdd_adapter_t *pAdapter )
6459{
6460 long ret = 0;
6461 hdd_station_ctx_t *pHddStaCtx;
6462 eMib_dot11DesiredBssType connectedBssType;
6463
6464 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6465
6466 hdd_connGetConnectedBssType(pHddStaCtx,&connectedBssType );
6467
6468 if((eMib_dot11DesiredBssType_independent == connectedBssType) ||
6469 (eConnectionState_Associated == pHddStaCtx->conn_info.connState) ||
6470 (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState))
6471 {
6472 /* Issue disconnect to CSR */
6473 INIT_COMPLETION(pAdapter->disconnect_comp_var);
6474 if( eHAL_STATUS_SUCCESS ==
6475 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
6476 pAdapter->sessionId,
6477 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
6478 {
6479 ret = wait_for_completion_interruptible_timeout(
6480 &pAdapter->disconnect_comp_var,
6481 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
6482 if (0 >= ret)
6483 {
6484 hddLog(LOGE, FL("Failed to receive disconnect event"));
6485 return -EALREADY;
6486 }
6487 }
6488 }
6489 else if(eConnectionState_Disconnecting == pHddStaCtx->conn_info.connState)
6490 {
6491 ret = wait_for_completion_interruptible_timeout(
6492 &pAdapter->disconnect_comp_var,
6493 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
6494 if (0 >= ret)
6495 {
6496 hddLog(LOGE, FL("Failed to receive disconnect event"));
6497 return -EALREADY;
6498 }
6499 }
6500
6501 return 0;
6502}
6503
6504/*
Jeff Johnson295189b2012-06-20 16:38:30 -07006505 * FUNCTION: wlan_hdd_cfg80211_set_privacy
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306506 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -07006507 * parameters during connect operation.
6508 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306509static int wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07006510 struct net_device *ndev,
6511 struct cfg80211_connect_params *req
6512 )
6513{
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306514 int status;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306515 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -07006516 VOS_STATUS exitbmpsStatus = VOS_STATUS_E_INVAL;
Rajesh Chauhana0516c62014-01-30 16:11:18 -08006517 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07006518
6519 ENTER();
6520
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05306521 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
6522 TRACE_CODE_HDD_CFG80211_CONNECT,
6523 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306524 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006525 "%s: device_mode = %d",__func__,pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07006526
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306527 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -08006528 if (!pHddCtx)
6529 {
6530 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6531 "%s: HDD context is null", __func__);
6532 return VOS_STATUS_E_FAILURE;
6533 }
6534
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306535 status = wlan_hdd_validate_context(pHddCtx);
6536
6537 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -07006538 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306539 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6540 "%s: HDD context is not valid", __func__);
6541 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -07006542 }
6543
6544#ifdef WLAN_BTAMP_FEATURE
6545 //Infra connect not supported when AMP traffic is on.
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306546 if( VOS_TRUE == WLANBAP_AmpSessionOn() )
Jeff Johnson295189b2012-06-20 16:38:30 -07006547 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306548 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07006549 "%s: No connection when AMP is on", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08006550 return -ECONNREFUSED;
Jeff Johnson295189b2012-06-20 16:38:30 -07006551 }
6552#endif
Vinay Krishna Eranna21042322014-01-08 19:21:39 +05306553
6554 //If Device Mode is Station Concurrent Sessions Exit BMps
6555 //P2P Mode will be taken care in Open/close adapter
6556 if((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
6557 (vos_concurrent_sessions_running()))
6558 {
6559 exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
6560 }
6561
6562 /*Try disconnecting if already in connected state*/
6563 status = wlan_hdd_try_disconnect(pAdapter);
6564 if ( 0 > status)
6565 {
6566 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
6567 " connection"));
6568 return -EALREADY;
6569 }
6570
Jeff Johnson295189b2012-06-20 16:38:30 -07006571 /*initialise security parameters*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306572 status = wlan_hdd_cfg80211_set_privacy(pAdapter, req);
Jeff Johnson295189b2012-06-20 16:38:30 -07006573
6574 if ( 0 > status)
6575 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306576 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security params",
Jeff Johnson295189b2012-06-20 16:38:30 -07006577 __func__);
6578 return status;
6579 }
6580
Mohit Khanna765234a2012-09-11 15:08:35 -07006581 if ( req->channel )
6582 {
6583 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
6584 req->ssid_len, req->bssid,
6585 req->channel->hw_value);
6586 }
6587 else
6588 {
6589 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306590 req->ssid_len, req->bssid, 0);
Mohit Khanna765234a2012-09-11 15:08:35 -07006591 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006592
6593 if (0 > status)
6594 {
6595 //ReEnable BMPS if disabled
6596 if((VOS_STATUS_SUCCESS == exitbmpsStatus) &&
6597 (NULL != pHddCtx))
6598 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306599 if (pHddCtx->hdd_wlan_suspended)
6600 {
6601 hdd_set_pwrparams(pHddCtx);
6602 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006603 //ReEnable Bmps and Imps back
6604 hdd_enable_bmps_imps(pHddCtx);
6605 }
6606
6607 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: connect failed", __func__);
6608 return status;
6609 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306610 pHddCtx->isAmpAllowed = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07006611 EXIT();
6612 return status;
6613}
6614
6615
6616/*
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05306617 * FUNCTION: wlan_hdd_disconnect
6618 * This function is used to issue a disconnect request to SME
6619 */
6620int wlan_hdd_disconnect( hdd_adapter_t *pAdapter, u16 reason )
6621{
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306622 int status;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05306623 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306624 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
6625
6626 status = wlan_hdd_validate_context(pHddCtx);
6627
6628 if (0 != status)
6629 {
6630 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6631 "%s: HDD context is not valid", __func__);
6632 return status;
6633 }
6634
6635 pHddCtx->isAmpAllowed = VOS_TRUE;
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +05306636 pHddStaCtx->conn_info.connState = eConnectionState_Disconnecting;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05306637 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306638
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05306639 /*issue disconnect*/
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +05306640
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05306641 status = sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
6642 pAdapter->sessionId, reason);
6643
6644 if ( 0 != status )
6645 {
6646 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006647 "%s csrRoamDisconnect failure, returned %d",
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05306648 __func__, (int)status );
6649 return -EINVAL;
6650 }
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +05306651 status = wait_for_completion_interruptible_timeout(
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05306652 &pAdapter->disconnect_comp_var,
6653 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +05306654 if (!status)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306655 {
6656 hddLog(VOS_TRACE_LEVEL_ERROR,
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +05306657 "%s: Failed to disconnect, timed out", __func__);
6658 return -ETIMEDOUT;
6659 }
6660 else if (status == -ERESTARTSYS)
6661 {
6662 hddLog(VOS_TRACE_LEVEL_ERROR,
6663 "%s: Failed to disconnect, wait interrupted", __func__);
6664 return status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306665 }
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05306666 /*stop tx queues*/
6667 netif_tx_disable(pAdapter->dev);
6668 netif_carrier_off(pAdapter->dev);
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +05306669 return 0;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05306670}
6671
6672
6673/*
Jeff Johnson295189b2012-06-20 16:38:30 -07006674 * FUNCTION: wlan_hdd_cfg80211_disconnect
6675 * This function is used to issue a disconnect request to SME
6676 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306677static int wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07006678 struct net_device *dev,
6679 u16 reason
6680 )
6681{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306682 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
6683 tCsrRoamProfile *pRoamProfile =
Jeff Johnson295189b2012-06-20 16:38:30 -07006684 &(WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter))->roamProfile;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306685 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07006686 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkala4327a152013-03-04 23:22:42 -08006687 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaaa353782013-05-17 20:36:22 +05306688#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08006689 tANI_U8 staIdx;
6690#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306691
Jeff Johnson295189b2012-06-20 16:38:30 -07006692 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306693
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05306694 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
6695 TRACE_CODE_HDD_CFG80211_DISCONNECT,
6696 pAdapter->sessionId, reason));
6697 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",
Jeff Johnson295189b2012-06-20 16:38:30 -07006698 __func__,pAdapter->device_mode);
6699
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306700 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Disconnect called with reason code %d",
6701 __func__, reason);
Jeff Johnson295189b2012-06-20 16:38:30 -07006702
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306703 status = wlan_hdd_validate_context(pHddCtx);
6704
6705 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -07006706 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306707 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6708 "%s: HDD context is not valid", __func__);
6709 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -07006710 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306711
Jeff Johnson295189b2012-06-20 16:38:30 -07006712 if (NULL != pRoamProfile)
6713 {
6714 /*issue disconnect request to SME, if station is in connected state*/
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +05306715 if ((pHddStaCtx->conn_info.connState == eConnectionState_Associated) ||
6716 (pHddStaCtx->conn_info.connState == eConnectionState_Connecting))
Jeff Johnson295189b2012-06-20 16:38:30 -07006717 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306718 eCsrRoamDisconnectReason reasonCode =
Jeff Johnson295189b2012-06-20 16:38:30 -07006719 eCSR_DISCONNECT_REASON_UNSPECIFIED;
Gopichand Nakkalaaa353782013-05-17 20:36:22 +05306720 hdd_scaninfo_t *pScanInfo;
Jeff Johnson295189b2012-06-20 16:38:30 -07006721 switch(reason)
6722 {
6723 case WLAN_REASON_MIC_FAILURE:
6724 reasonCode = eCSR_DISCONNECT_REASON_MIC_ERROR;
6725 break;
6726
6727 case WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY:
6728 case WLAN_REASON_DISASSOC_AP_BUSY:
6729 case WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA:
6730 reasonCode = eCSR_DISCONNECT_REASON_DISASSOC;
6731 break;
6732
6733 case WLAN_REASON_PREV_AUTH_NOT_VALID:
6734 case WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA:
6735 reasonCode = eCSR_DISCONNECT_REASON_DEAUTH;
6736 break;
6737
6738 case WLAN_REASON_DEAUTH_LEAVING:
6739 default:
6740 reasonCode = eCSR_DISCONNECT_REASON_UNSPECIFIED;
6741 break;
6742 }
Gopichand Nakkalaaa353782013-05-17 20:36:22 +05306743 pScanInfo = &pHddCtx->scan_info;
6744 if (pScanInfo->mScanPending)
6745 {
Srinivas, Dasari138af4f2014-02-07 11:13:45 +05306746 hddLog(VOS_TRACE_LEVEL_INFO, "Disconnect is in progress, "
Gopichand Nakkalaaa353782013-05-17 20:36:22 +05306747 "Aborting Scan");
Srinivas, Dasari138af4f2014-02-07 11:13:45 +05306748 hdd_abort_mac_scan(pHddCtx, pAdapter->sessionId,
6749 eCSR_SCAN_ABORT_DEFAULT);
Gopichand Nakkalaaa353782013-05-17 20:36:22 +05306750 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006751
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08006752#ifdef FEATURE_WLAN_TDLS
6753 /* First clean up the tdls peers if any */
Gopichand Nakkala4327a152013-03-04 23:22:42 -08006754 for (staIdx = 0 ; staIdx < HDD_MAX_NUM_TDLS_STA; staIdx++)
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08006755 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -08006756 if ((pHddCtx->tdlsConnInfo[staIdx].sessionId == pAdapter->sessionId) &&
6757 (pHddCtx->tdlsConnInfo[staIdx].staId))
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08006758 {
Hoonki Lee11f7dda2013-02-14 16:55:44 -08006759 uint8 *mac;
Gopichand Nakkala4327a152013-03-04 23:22:42 -08006760 mac = pHddCtx->tdlsConnInfo[staIdx].peerMac.bytes;
Hoonki Lee11f7dda2013-02-14 16:55:44 -08006761 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07006762 "%s: call sme_DeleteTdlsPeerSta staId %d sessionId %d " MAC_ADDRESS_STR,
Gopichand Nakkala4327a152013-03-04 23:22:42 -08006763 __func__, pHddCtx->tdlsConnInfo[staIdx].staId, pAdapter->sessionId,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07006764 MAC_ADDR_ARRAY(mac));
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08006765 sme_DeleteTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala4327a152013-03-04 23:22:42 -08006766 pAdapter->sessionId,
6767 mac);
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08006768 }
6769 }
6770#endif
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +05306771 hddLog(LOG1, FL("Disconnecting with reasoncode:%u"), reasonCode);
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05306772 status = wlan_hdd_disconnect(pAdapter, reasonCode);
6773 if ( 0 != status )
Jeff Johnson295189b2012-06-20 16:38:30 -07006774 {
6775 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006776 "%s wlan_hdd_disconnect failure, returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07006777 __func__, (int)status );
6778 return -EINVAL;
6779 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006780 }
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +05306781 else
6782 {
6783 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unexpected cfg disconnect API"
6784 "called while in %d state", __func__,
6785 pHddStaCtx->conn_info.connState);
6786 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006787 }
6788 else
6789 {
6790 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid roam profile", __func__);
6791 }
6792
6793 return status;
6794}
6795
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05306796
Jeff Johnson295189b2012-06-20 16:38:30 -07006797/*
6798 * FUNCTION: wlan_hdd_cfg80211_set_privacy_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306799 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -07006800 * settings in IBSS mode.
6801 */
6802static int wlan_hdd_cfg80211_set_privacy_ibss(
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306803 hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07006804 struct cfg80211_ibss_params *params
6805 )
6806{
6807 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306808 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07006809 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
6810 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306811
Jeff Johnson295189b2012-06-20 16:38:30 -07006812 ENTER();
6813
6814 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
Ravi Joshib58ca0d2013-10-29 09:50:23 -07006815 vos_mem_zero(&pHddStaCtx->ibss_enc_key, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -07006816
6817 if (params->ie_len && ( NULL != params->ie) )
6818 {
Shailender Karmuchi67edd312013-06-18 16:30:48 -07006819 if (wlan_hdd_cfg80211_get_ie_ptr (params->ie,
6820 params->ie_len, WLAN_EID_RSN ))
Jeff Johnson295189b2012-06-20 16:38:30 -07006821 {
6822 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
6823 encryptionType = eCSR_ENCRYPT_TYPE_AES;
6824 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -07006825 else if ( hdd_isWPAIEPresent (params->ie, params->ie_len ))
Jeff Johnson295189b2012-06-20 16:38:30 -07006826 {
Shailender Karmuchi642e9812013-05-30 14:34:49 -07006827 tDot11fIEWPA dot11WPAIE;
6828 tHalHandle halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
Shailender Karmuchi67edd312013-06-18 16:30:48 -07006829 u8 *ie;
Shailender Karmuchi642e9812013-05-30 14:34:49 -07006830
Wilson Yang00256342013-10-10 23:13:38 -07006831 memset(&dot11WPAIE, 0, sizeof(dot11WPAIE));
Shailender Karmuchi67edd312013-06-18 16:30:48 -07006832 ie = wlan_hdd_cfg80211_get_ie_ptr (params->ie,
6833 params->ie_len, DOT11F_EID_WPA);
6834 if ( NULL != ie )
6835 {
6836 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
6837 // Unpack the WPA IE
6838 //Skip past the EID byte and length byte - and four byte WiFi OUI
6839 dot11fUnpackIeWPA((tpAniSirGlobal) halHandle,
6840 &ie[2+4],
6841 ie[1] - 4,
6842 &dot11WPAIE);
6843 /*Extract the multicast cipher, the encType for unicast
6844 cipher for wpa-none is none*/
6845 encryptionType =
6846 hdd_TranslateWPAToCsrEncryptionType(dot11WPAIE.multicast_cipher);
6847 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006848 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -07006849
Jeff Johnson295189b2012-06-20 16:38:30 -07006850 status = wlan_hdd_cfg80211_set_ie(pAdapter, params->ie, params->ie_len);
6851
6852 if (0 > status)
6853 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306854 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -07006855 __func__);
6856 return status;
6857 }
6858 }
6859
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306860 pWextState->roamProfile.AuthType.authType[0] =
6861 pHddStaCtx->conn_info.authType =
Jeff Johnson295189b2012-06-20 16:38:30 -07006862 eCSR_AUTH_TYPE_OPEN_SYSTEM;
6863
6864 if (params->privacy)
6865 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306866 /* Security enabled IBSS, At this time there is no information available
6867 * about the security paramters, so initialise the encryption type to
Jeff Johnson295189b2012-06-20 16:38:30 -07006868 * eCSR_ENCRYPT_TYPE_WEP40_STATICKEY.
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306869 * The correct security parameters will be updated later in
Jeff Johnson295189b2012-06-20 16:38:30 -07006870 * wlan_hdd_cfg80211_add_key */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306871 /* Hal expects encryption type to be set inorder
Jeff Johnson295189b2012-06-20 16:38:30 -07006872 *enable privacy bit in beacons */
6873
6874 encryptionType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
6875 }
Shailender Karmuchi642e9812013-05-30 14:34:49 -07006876 VOS_TRACE (VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
6877 "encryptionType=%d", encryptionType);
Jeff Johnson295189b2012-06-20 16:38:30 -07006878 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
6879 pWextState->roamProfile.EncryptionType.numEntries = 1;
6880 pWextState->roamProfile.EncryptionType.encryptionType[0] = encryptionType;
Jeff Johnson295189b2012-06-20 16:38:30 -07006881 return status;
6882}
6883
6884/*
6885 * FUNCTION: wlan_hdd_cfg80211_join_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306886 * This function is used to create/join an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -07006887 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306888static int wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07006889 struct net_device *dev,
6890 struct cfg80211_ibss_params *params
6891 )
6892{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306893 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Jeff Johnson295189b2012-06-20 16:38:30 -07006894 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
6895 tCsrRoamProfile *pRoamProfile;
6896 int status;
krunal sonie9002db2013-11-25 14:24:17 -08006897 bool alloc_bssid = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07006898 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306899 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07006900
6901 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306902
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05306903 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
6904 TRACE_CODE_HDD_CFG80211_JOIN_IBSS,
6905 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306906 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006907 "%s: device_mode = %d",__func__,pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07006908
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306909 status = wlan_hdd_validate_context(pHddCtx);
6910
6911 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -07006912 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306913 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6914 "%s: HDD context is not valid", __func__);
6915 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -07006916 }
6917
6918 if (NULL == pWextState)
6919 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08006920 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -07006921 __func__);
6922 return -EIO;
6923 }
6924
Vinay Krishna Eranna21042322014-01-08 19:21:39 +05306925 /*Try disconnecting if already in connected state*/
6926 status = wlan_hdd_try_disconnect(pAdapter);
6927 if ( 0 > status)
6928 {
6929 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
6930 " IBSS connection"));
6931 return -EALREADY;
6932 }
6933
Jeff Johnson295189b2012-06-20 16:38:30 -07006934 pRoamProfile = &pWextState->roamProfile;
6935
6936 if ( eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType )
6937 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306938 hddLog (VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006939 "%s Interface type is not set to IBSS", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006940 return -EINVAL;
6941 }
6942
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -07006943 /* BSSID is provided by upper layers hence no need to AUTO generate */
6944 if (NULL != params->bssid) {
6945 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
6946 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) {
6947 hddLog (VOS_TRACE_LEVEL_ERROR,
6948 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
6949 return -EIO;
6950 }
6951 }
krunal sonie9002db2013-11-25 14:24:17 -08006952 else if(pHddCtx->cfg_ini->isCoalesingInIBSSAllowed == 0)
6953 {
6954 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
6955 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
6956 {
6957 hddLog (VOS_TRACE_LEVEL_ERROR,
6958 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
6959 return -EIO;
6960 }
6961 params->bssid = vos_mem_malloc(sizeof(VOS_MAC_ADDR_SIZE));
6962 if (!params->bssid)
6963 {
6964 hddLog (VOS_TRACE_LEVEL_ERROR,
6965 "%s:Failed memory allocation", __func__);
6966 return -EIO;
6967 }
6968 vos_mem_copy((v_U8_t *)params->bssid,
6969 (v_U8_t *)&pHddCtx->cfg_ini->IbssBssid.bytes[0],
6970 VOS_MAC_ADDR_SIZE);
6971 alloc_bssid = VOS_TRUE;
6972 }
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -07006973
Jeff Johnson295189b2012-06-20 16:38:30 -07006974 /* Set Channel */
Yue Maf49ba872013-08-19 12:04:25 -07006975 if (NULL !=
6976#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
6977 params->chandef.chan)
6978#else
6979 params->channel)
6980#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006981 {
6982 u8 channelNum;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07006983 v_U32_t numChans = WNI_CFG_VALID_CHANNEL_LIST_LEN;
6984 v_U8_t validChan[WNI_CFG_VALID_CHANNEL_LIST_LEN];
6985 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
6986 int indx;
Jeff Johnson295189b2012-06-20 16:38:30 -07006987
6988 /* Get channel number */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306989 channelNum =
Yue Maf49ba872013-08-19 12:04:25 -07006990 ieee80211_frequency_to_channel(
6991#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
6992 params->chandef.chan->center_freq);
6993#else
6994 params->channel->center_freq);
6995#endif
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07006996
6997 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
6998 validChan, &numChans))
Jeff Johnson295189b2012-06-20 16:38:30 -07006999 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07007000 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid channel list",
7001 __func__);
7002 return -EOPNOTSUPP;
Jeff Johnson295189b2012-06-20 16:38:30 -07007003 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07007004
7005 for (indx = 0; indx < numChans; indx++)
Jeff Johnson295189b2012-06-20 16:38:30 -07007006 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07007007 if (channelNum == validChan[indx])
7008 {
7009 break;
7010 }
7011 }
7012 if (indx >= numChans)
7013 {
7014 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Not valid Channel %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07007015 __func__, channelNum);
7016 return -EINVAL;
7017 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07007018 /* Set the Operational Channel */
7019 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: set channel %d", __func__,
7020 channelNum);
7021 pRoamProfile->ChannelInfo.numOfChannels = 1;
7022 pHddStaCtx->conn_info.operationChannel = channelNum;
7023 pRoamProfile->ChannelInfo.ChannelList =
7024 &pHddStaCtx->conn_info.operationChannel;
Jeff Johnson295189b2012-06-20 16:38:30 -07007025 }
7026
7027 /* Initialize security parameters */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307028 status = wlan_hdd_cfg80211_set_privacy_ibss(pAdapter, params);
Jeff Johnson295189b2012-06-20 16:38:30 -07007029 if (status < 0)
7030 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307031 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security parameters",
Jeff Johnson295189b2012-06-20 16:38:30 -07007032 __func__);
7033 return status;
7034 }
7035
7036 /* Issue connect start */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307037 status = wlan_hdd_cfg80211_connect_start(pAdapter, params->ssid,
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07007038 params->ssid_len, params->bssid,
7039 pHddStaCtx->conn_info.operationChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -07007040
7041 if (0 > status)
7042 {
7043 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: connect failed", __func__);
7044 return status;
7045 }
7046
krunal sonie9002db2013-11-25 14:24:17 -08007047 if (NULL != params->bssid &&
7048 pHddCtx->cfg_ini->isCoalesingInIBSSAllowed == 0 &&
7049 alloc_bssid == VOS_TRUE)
7050 {
7051 vos_mem_free(params->bssid);
7052 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007053 return 0;
7054}
7055
7056/*
7057 * FUNCTION: wlan_hdd_cfg80211_leave_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307058 * This function is used to leave an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -07007059 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307060static int wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07007061 struct net_device *dev
7062 )
7063{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307064 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Jeff Johnson295189b2012-06-20 16:38:30 -07007065 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
7066 tCsrRoamProfile *pRoamProfile;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307067 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7068 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07007069
7070 ENTER();
7071
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307072 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7073 TRACE_CODE_HDD_CFG80211_LEAVE_IBSS,
7074 pAdapter->sessionId, eCSR_DISCONNECT_REASON_IBSS_LEAVE));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307075 status = wlan_hdd_validate_context(pHddCtx);
7076
7077 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007078 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307079 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7080 "%s: HDD context is not valid", __func__);
7081 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007082 }
7083
Arif Hussain6d2a3322013-11-17 19:50:10 -08007084 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",__func__,pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07007085 if (NULL == pWextState)
7086 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08007087 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -07007088 __func__);
7089 return -EIO;
7090 }
7091
7092 pRoamProfile = &pWextState->roamProfile;
7093
7094 /* Issue disconnect only if interface type is set to IBSS */
7095 if (eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType)
7096 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307097 hddLog (VOS_TRACE_LEVEL_ERROR, "%s: BSS Type is not set to IBSS",
Jeff Johnson295189b2012-06-20 16:38:30 -07007098 __func__);
7099 return -EINVAL;
7100 }
7101
7102 /* Issue Disconnect request */
7103 INIT_COMPLETION(pAdapter->disconnect_comp_var);
7104 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
7105 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
7106
7107 return 0;
7108}
7109
7110/*
7111 * FUNCTION: wlan_hdd_cfg80211_set_wiphy_params
7112 * This function is used to set the phy parameters
7113 * (RTS Threshold/FRAG Threshold/Retry Count etc ...)
7114 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307115static int wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07007116 u32 changed)
7117{
7118 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
7119 tHalHandle hHal = pHddCtx->hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307120 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07007121
7122 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307123 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7124 TRACE_CODE_HDD_CFG80211_SET_WIPHY_PARAMS,
7125 NO_SESSION, wiphy->rts_threshold));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307126 status = wlan_hdd_validate_context(pHddCtx);
7127
7128 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007129 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307130 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7131 "%s: HDD context is not valid", __func__);
7132 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007133 }
7134
Jeff Johnson295189b2012-06-20 16:38:30 -07007135 if (changed & WIPHY_PARAM_RTS_THRESHOLD)
7136 {
7137 u16 rts_threshold = (wiphy->rts_threshold == -1) ?
7138 WNI_CFG_RTS_THRESHOLD_STAMAX :
7139 wiphy->rts_threshold;
7140
7141 if ((WNI_CFG_RTS_THRESHOLD_STAMIN > rts_threshold) ||
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307142 (WNI_CFG_RTS_THRESHOLD_STAMAX < rts_threshold))
Jeff Johnson295189b2012-06-20 16:38:30 -07007143 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307144 hddLog(VOS_TRACE_LEVEL_ERROR,
7145 "%s: Invalid RTS Threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07007146 __func__, rts_threshold);
7147 return -EINVAL;
7148 }
7149
7150 if (0 != ccmCfgSetInt(hHal, WNI_CFG_RTS_THRESHOLD,
7151 rts_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307152 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -07007153 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307154 hddLog(VOS_TRACE_LEVEL_ERROR,
7155 "%s: ccmCfgSetInt failed for rts_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07007156 __func__, rts_threshold);
7157 return -EIO;
7158 }
7159
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307160 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set rts threshold %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07007161 rts_threshold);
7162 }
7163
7164 if (changed & WIPHY_PARAM_FRAG_THRESHOLD)
7165 {
7166 u16 frag_threshold = (wiphy->frag_threshold == -1) ?
7167 WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX :
7168 wiphy->frag_threshold;
7169
7170 if ((WNI_CFG_FRAGMENTATION_THRESHOLD_STAMIN > frag_threshold)||
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307171 (WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX < frag_threshold) )
Jeff Johnson295189b2012-06-20 16:38:30 -07007172 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307173 hddLog(VOS_TRACE_LEVEL_ERROR,
7174 "%s: Invalid frag_threshold value %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07007175 frag_threshold);
7176 return -EINVAL;
7177 }
7178
7179 if (0 != ccmCfgSetInt(hHal, WNI_CFG_FRAGMENTATION_THRESHOLD,
7180 frag_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307181 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -07007182 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307183 hddLog(VOS_TRACE_LEVEL_ERROR,
7184 "%s: ccmCfgSetInt failed for frag_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07007185 __func__, frag_threshold);
7186 return -EIO;
7187 }
7188
7189 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set frag threshold %hu", __func__,
7190 frag_threshold);
7191 }
7192
7193 if ((changed & WIPHY_PARAM_RETRY_SHORT)
7194 || (changed & WIPHY_PARAM_RETRY_LONG))
7195 {
7196 u8 retry_value = (changed & WIPHY_PARAM_RETRY_SHORT) ?
7197 wiphy->retry_short :
7198 wiphy->retry_long;
7199
7200 if ((WNI_CFG_LONG_RETRY_LIMIT_STAMIN > retry_value) ||
7201 (WNI_CFG_LONG_RETRY_LIMIT_STAMAX < retry_value))
7202 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307203 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07007204 __func__, retry_value);
7205 return -EINVAL;
7206 }
7207
7208 if (changed & WIPHY_PARAM_RETRY_SHORT)
7209 {
7210 if (0 != ccmCfgSetInt(hHal, WNI_CFG_LONG_RETRY_LIMIT,
7211 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307212 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -07007213 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307214 hddLog(VOS_TRACE_LEVEL_ERROR,
7215 "%s: ccmCfgSetInt failed for long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07007216 __func__, retry_value);
7217 return -EIO;
7218 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307219 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07007220 __func__, retry_value);
7221 }
7222 else if (changed & WIPHY_PARAM_RETRY_SHORT)
7223 {
7224 if (0 != ccmCfgSetInt(hHal, WNI_CFG_SHORT_RETRY_LIMIT,
7225 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307226 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -07007227 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307228 hddLog(VOS_TRACE_LEVEL_ERROR,
7229 "%s: ccmCfgSetInt failed for short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07007230 __func__, retry_value);
7231 return -EIO;
7232 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307233 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07007234 __func__, retry_value);
7235 }
7236 }
7237
7238 return 0;
7239}
7240
7241/*
7242 * FUNCTION: wlan_hdd_cfg80211_set_txpower
7243 * This function is used to set the txpower
7244 */
7245static int wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
Yue Maf49ba872013-08-19 12:04:25 -07007246#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
7247 struct wireless_dev *wdev,
7248#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007249#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307250 enum tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -07007251#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307252 enum nl80211_tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -07007253#endif
7254 int dbm)
7255{
7256 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307257 tHalHandle hHal = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07007258 tSirMacAddr bssid = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
7259 tSirMacAddr selfMac = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307260 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07007261
7262 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307263 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7264 TRACE_CODE_HDD_CFG80211_SET_TXPOWER,
7265 NO_SESSION, type ));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307266 status = wlan_hdd_validate_context(pHddCtx);
7267
7268 if (0 != status)
7269 {
7270 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7271 "%s: HDD context is not valid", __func__);
7272 return status;
7273 }
7274
7275 hHal = pHddCtx->hHal;
7276
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307277 if (0 != ccmCfgSetInt(hHal, WNI_CFG_CURRENT_TX_POWER_LEVEL,
7278 dbm, ccmCfgSetCallback,
7279 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -07007280 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307281 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07007282 "%s: ccmCfgSetInt failed for tx power %hu", __func__, dbm);
7283 return -EIO;
7284 }
7285
7286 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set tx power level %d dbm", __func__,
7287 dbm);
7288
7289 switch(type)
7290 {
7291 case NL80211_TX_POWER_AUTOMATIC: /*automatically determine transmit power*/
7292 /* Fall through */
7293 case NL80211_TX_POWER_LIMITED: /*limit TX power by the mBm parameter*/
7294 if( sme_SetMaxTxPower(hHal, bssid, selfMac, dbm) != eHAL_STATUS_SUCCESS )
7295 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307296 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Setting maximum tx power failed",
7297 __func__);
7298 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -07007299 }
7300 break;
7301 case NL80211_TX_POWER_FIXED: /*fix TX power to the mBm parameter*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307302 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: NL80211_TX_POWER_FIXED not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -07007303 __func__);
7304 return -EOPNOTSUPP;
7305 break;
7306 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307307 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid power setting type %d",
7308 __func__, type);
Jeff Johnson295189b2012-06-20 16:38:30 -07007309 return -EIO;
7310 }
7311
7312 return 0;
7313}
7314
7315/*
7316 * FUNCTION: wlan_hdd_cfg80211_get_txpower
7317 * This function is used to read the txpower
7318 */
Yue Maf49ba872013-08-19 12:04:25 -07007319static int wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy,
7320#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
7321 struct wireless_dev *wdev,
7322#endif
7323 int *dbm)
Jeff Johnson295189b2012-06-20 16:38:30 -07007324{
7325
7326 hdd_adapter_t *pAdapter;
7327 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307328 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07007329
Jeff Johnsone7245742012-09-05 17:12:55 -07007330 ENTER();
7331
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307332 status = wlan_hdd_validate_context(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07007333
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307334 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007335 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307336 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7337 "%s: HDD context is not valid", __func__);
7338 *dbm = 0;
7339 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007340 }
7341
Jeff Johnson295189b2012-06-20 16:38:30 -07007342 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
7343 if (NULL == pAdapter)
7344 {
7345 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Not in station context " ,__func__);
7346 return -ENOENT;
7347 }
7348
7349 wlan_hdd_get_classAstats(pAdapter);
7350 *dbm = pAdapter->hdd_stats.ClassA_stat.max_pwr;
7351
Jeff Johnsone7245742012-09-05 17:12:55 -07007352 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07007353 return 0;
7354}
7355
7356static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
7357 u8* mac, struct station_info *sinfo)
7358{
7359 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
7360 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7361 int ssidlen = pHddStaCtx->conn_info.SSID.SSID.length;
7362 tANI_U8 rate_flags;
7363
7364 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
7365 hdd_config_t *pCfg = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -07007366
7367 tANI_U8 OperationalRates[CSR_DOT11_SUPPORTED_RATES_MAX];
7368 tANI_U32 ORLeng = CSR_DOT11_SUPPORTED_RATES_MAX;
7369 tANI_U8 ExtendedRates[CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX];
7370 tANI_U32 ERLeng = CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX;
7371 tANI_U8 MCSRates[SIZE_OF_BASIC_MCS_SET];
7372 tANI_U32 MCSLeng = SIZE_OF_BASIC_MCS_SET;
7373 tANI_U16 maxRate = 0;
7374 tANI_U16 myRate;
7375 tANI_U16 currentRate = 0;
7376 tANI_U8 maxSpeedMCS = 0;
7377 tANI_U8 maxMCSIdx = 0;
7378 tANI_U8 rateFlag = 1;
7379 tANI_U8 i, j, rssidx;
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07007380 tANI_U16 temp;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307381 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07007382
Leo Chang6f8870f2013-03-26 18:11:36 -07007383#ifdef WLAN_FEATURE_11AC
7384 tANI_U32 vht_mcs_map;
7385 eDataRate11ACMaxMcs vhtMaxMcs;
7386#endif /* WLAN_FEATURE_11AC */
7387
Jeff Johnsone7245742012-09-05 17:12:55 -07007388 ENTER();
7389
Jeff Johnson295189b2012-06-20 16:38:30 -07007390 if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) ||
7391 (0 == ssidlen))
7392 {
7393 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Not associated or"
7394 " Invalid ssidlen, %d", __func__, ssidlen);
7395 /*To keep GUI happy*/
7396 return 0;
7397 }
7398
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307399 status = wlan_hdd_validate_context(pHddCtx);
7400
7401 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007402 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307403 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7404 "%s: HDD context is not valid", __func__);
7405 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007406 }
7407
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -07007408 wlan_hdd_get_station_stats(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07007409 rate_flags = pAdapter->hdd_stats.ClassA_stat.tx_rate_flags;
7410
Kiet Lam3b17fc82013-09-27 05:24:08 +05307411 wlan_hdd_get_rssi(pAdapter, &sinfo->signal);
7412 sinfo->filled |= STATION_INFO_SIGNAL;
7413
Jeff Johnson295189b2012-06-20 16:38:30 -07007414 //convert to the UI units of 100kbps
7415 myRate = pAdapter->hdd_stats.ClassA_stat.tx_rate * 5;
7416
7417#ifdef LINKSPEED_DEBUG_ENABLED
Leo Chang6f8870f2013-03-26 18:11:36 -07007418 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 -07007419 sinfo->signal,
7420 pCfg->reportMaxLinkSpeed,
7421 myRate,
7422 (int) pCfg->linkSpeedRssiHigh,
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07007423 (int) pCfg->linkSpeedRssiMid,
7424 (int) pCfg->linkSpeedRssiLow,
Leo Chang6f8870f2013-03-26 18:11:36 -07007425 (int) rate_flags,
7426 (int) pAdapter->hdd_stats.ClassA_stat.mcs_index);
Jeff Johnson295189b2012-06-20 16:38:30 -07007427#endif //LINKSPEED_DEBUG_ENABLED
7428
7429 if (eHDD_LINK_SPEED_REPORT_ACTUAL != pCfg->reportMaxLinkSpeed)
7430 {
7431 // we do not want to necessarily report the current speed
7432 if (eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed)
7433 {
7434 // report the max possible speed
7435 rssidx = 0;
7436 }
7437 else if (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed)
7438 {
7439 // report the max possible speed with RSSI scaling
7440 if (sinfo->signal >= pCfg->linkSpeedRssiHigh)
7441 {
7442 // report the max possible speed
7443 rssidx = 0;
7444 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07007445 else if (sinfo->signal >= pCfg->linkSpeedRssiMid)
Jeff Johnson295189b2012-06-20 16:38:30 -07007446 {
7447 // report middle speed
7448 rssidx = 1;
7449 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07007450 else if (sinfo->signal >= pCfg->linkSpeedRssiLow)
7451 {
7452 // report middle speed
7453 rssidx = 2;
7454 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007455 else
7456 {
7457 // report actual speed
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07007458 rssidx = 3;
Jeff Johnson295189b2012-06-20 16:38:30 -07007459 }
7460 }
7461 else
7462 {
7463 // unknown, treat as eHDD_LINK_SPEED_REPORT_MAX
7464 hddLog(VOS_TRACE_LEVEL_ERROR,
7465 "%s: Invalid value for reportMaxLinkSpeed: %u",
7466 __func__, pCfg->reportMaxLinkSpeed);
7467 rssidx = 0;
7468 }
7469
7470 maxRate = 0;
7471
7472 /* Get Basic Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +05307473 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_OPERATIONAL_RATE_SET,
7474 OperationalRates, &ORLeng))
7475 {
7476 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
7477 /*To keep GUI happy*/
7478 return 0;
7479 }
7480
Jeff Johnson295189b2012-06-20 16:38:30 -07007481 for (i = 0; i < ORLeng; i++)
7482 {
Jeff Johnsone7245742012-09-05 17:12:55 -07007483 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -07007484 {
7485 /* Validate Rate Set */
7486 if (supported_data_rate[j].beacon_rate_index == (OperationalRates[i] & 0x7F))
7487 {
7488 currentRate = supported_data_rate[j].supported_rate[rssidx];
7489 break;
7490 }
7491 }
7492 /* Update MAX rate */
7493 maxRate = (currentRate > maxRate)?currentRate:maxRate;
7494 }
7495
7496 /* Get Extended Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +05307497 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET,
7498 ExtendedRates, &ERLeng))
7499 {
7500 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
7501 /*To keep GUI happy*/
7502 return 0;
7503 }
7504
Jeff Johnson295189b2012-06-20 16:38:30 -07007505 for (i = 0; i < ERLeng; i++)
7506 {
Jeff Johnsone7245742012-09-05 17:12:55 -07007507 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -07007508 {
7509 if (supported_data_rate[j].beacon_rate_index == (ExtendedRates[i] & 0x7F))
7510 {
7511 currentRate = supported_data_rate[j].supported_rate[rssidx];
7512 break;
7513 }
7514 }
7515 /* Update MAX rate */
7516 maxRate = (currentRate > maxRate)?currentRate:maxRate;
7517 }
Kiet Lamb69f8dc2013-11-15 15:34:27 +05307518 /* Get MCS Rate Set --
Kaushik, Sushantdc304d82014-01-22 10:58:37 +05307519 Only if we are always reporting max speed (or)
Kiet Lamb69f8dc2013-11-15 15:34:27 +05307520 if we have good rssi */
Kaushik, Sushantdc304d82014-01-22 10:58:37 +05307521 if ((0 == rssidx) ||
Kiet Lamb69f8dc2013-11-15 15:34:27 +05307522 (eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed))
Jeff Johnson295189b2012-06-20 16:38:30 -07007523 {
Gopichand Nakkala05ab1322013-02-15 11:28:38 +05307524 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_CURRENT_MCS_SET,
7525 MCSRates, &MCSLeng))
7526 {
7527 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
7528 /*To keep GUI happy*/
7529 return 0;
7530 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007531 rateFlag = 0;
Leo Chang6f8870f2013-03-26 18:11:36 -07007532#ifdef WLAN_FEATURE_11AC
7533 /* VHT80 rate has seperate rate table */
Gopichand Nakkala4c705372013-04-24 13:20:33 +05307534 if (rate_flags & (eHAL_TX_RATE_VHT20|eHAL_TX_RATE_VHT40|eHAL_TX_RATE_VHT80))
Jeff Johnson295189b2012-06-20 16:38:30 -07007535 {
Leo Chang6f8870f2013-03-26 18:11:36 -07007536 ccmCfgGetInt(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_VHT_TX_MCS_MAP, &vht_mcs_map);
Gopichand Nakkala4c705372013-04-24 13:20:33 +05307537 vhtMaxMcs = (eDataRate11ACMaxMcs)(vht_mcs_map & DATA_RATE_11AC_MCS_MASK );
Leo Chang6f8870f2013-03-26 18:11:36 -07007538 if (rate_flags & eHAL_TX_RATE_SGI)
Jeff Johnson295189b2012-06-20 16:38:30 -07007539 {
Leo Chang6f8870f2013-03-26 18:11:36 -07007540 rateFlag |= 1;
Jeff Johnson295189b2012-06-20 16:38:30 -07007541 }
Leo Chang6f8870f2013-03-26 18:11:36 -07007542 if (DATA_RATE_11AC_MAX_MCS_7 == vhtMaxMcs)
Jeff Johnson295189b2012-06-20 16:38:30 -07007543 {
Leo Chang6f8870f2013-03-26 18:11:36 -07007544 maxMCSIdx = 7;
7545 }
7546 else if (DATA_RATE_11AC_MAX_MCS_8 == vhtMaxMcs)
7547 {
7548 maxMCSIdx = 8;
7549 }
7550 else if (DATA_RATE_11AC_MAX_MCS_9 == vhtMaxMcs)
7551 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +05307552 //VHT20 is supporting 0~8
7553 if (rate_flags & eHAL_TX_RATE_VHT20)
7554 maxMCSIdx = 8;
7555 else
7556 maxMCSIdx = 9;
Leo Chang6f8870f2013-03-26 18:11:36 -07007557 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +05307558
7559 if (rate_flags & eHAL_TX_RATE_VHT80)
7560 {
7561 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT80_rate[rateFlag];
7562 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT80_rate[rateFlag];
7563 }
7564 else if (rate_flags & eHAL_TX_RATE_VHT40)
7565 {
7566 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT40_rate[rateFlag];
7567 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT40_rate[rateFlag];
7568 }
7569 else if (rate_flags & eHAL_TX_RATE_VHT20)
7570 {
7571 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT20_rate[rateFlag];
7572 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT20_rate[rateFlag];
7573 }
7574
Leo Chang6f8870f2013-03-26 18:11:36 -07007575 maxSpeedMCS = 1;
7576 if (currentRate > maxRate)
7577 {
7578 maxRate = currentRate;
7579 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +05307580
Leo Chang6f8870f2013-03-26 18:11:36 -07007581 }
7582 else
7583#endif /* WLAN_FEATURE_11AC */
7584 {
7585 if (rate_flags & eHAL_TX_RATE_HT40)
7586 {
7587 rateFlag |= 1;
7588 }
7589 if (rate_flags & eHAL_TX_RATE_SGI)
7590 {
7591 rateFlag |= 2;
7592 }
7593
7594 for (i = 0; i < MCSLeng; i++)
7595 {
7596 temp = sizeof(supported_mcs_rate) / sizeof(supported_mcs_rate[0]);
7597 for (j = 0; j < temp; j++)
7598 {
7599 if (supported_mcs_rate[j].beacon_rate_index == MCSRates[i])
7600 {
7601 currentRate = supported_mcs_rate[j].supported_rate[rateFlag];
7602 break;
7603 }
7604 }
7605 if ((j < temp) && (currentRate > maxRate))
7606 {
7607 maxRate = currentRate;
7608 maxSpeedMCS = 1;
7609 maxMCSIdx = supported_mcs_rate[j].beacon_rate_index;
7610 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007611 }
7612 }
7613 }
7614
Gopichand Nakkala4c705372013-04-24 13:20:33 +05307615 else if (!(rate_flags & eHAL_TX_RATE_LEGACY))
7616 {
7617 maxRate = myRate;
7618 maxSpeedMCS = 1;
7619 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
7620 }
7621
Jeff Johnson295189b2012-06-20 16:38:30 -07007622 // make sure we report a value at least as big as our current rate
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07007623 if (((maxRate < myRate) && (0 == rssidx)) ||
7624 (0 == maxRate))
Jeff Johnson295189b2012-06-20 16:38:30 -07007625 {
7626 maxRate = myRate;
7627 if (rate_flags & eHAL_TX_RATE_LEGACY)
7628 {
7629 maxSpeedMCS = 0;
7630 }
7631 else
7632 {
7633 maxSpeedMCS = 1;
7634 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
7635 }
7636 }
7637
Gopichand Nakkala4c705372013-04-24 13:20:33 +05307638 if (rate_flags & eHAL_TX_RATE_LEGACY)
Jeff Johnson295189b2012-06-20 16:38:30 -07007639 {
7640 sinfo->txrate.legacy = maxRate;
7641#ifdef LINKSPEED_DEBUG_ENABLED
7642 pr_info("Reporting legacy rate %d\n", sinfo->txrate.legacy);
7643#endif //LINKSPEED_DEBUG_ENABLED
7644 }
7645 else
7646 {
7647 sinfo->txrate.mcs = maxMCSIdx;
Leo Chang6f8870f2013-03-26 18:11:36 -07007648#ifdef WLAN_FEATURE_11AC
7649 sinfo->txrate.nss = 1;
7650 if (rate_flags & eHAL_TX_RATE_VHT80)
7651 {
7652 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
Gopichand Nakkala4c705372013-04-24 13:20:33 +05307653 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
Leo Chang6f8870f2013-03-26 18:11:36 -07007654 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +05307655 else if (rate_flags & eHAL_TX_RATE_VHT40)
Leo Chang6f8870f2013-03-26 18:11:36 -07007656 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +05307657 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
7658 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
7659 }
7660 else if (rate_flags & eHAL_TX_RATE_VHT20)
7661 {
7662 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
7663 }
7664#endif /* WLAN_FEATURE_11AC */
7665 if (rate_flags & (eHAL_TX_RATE_HT20 | eHAL_TX_RATE_HT40))
7666 {
7667 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
7668 if (rate_flags & eHAL_TX_RATE_HT40)
7669 {
7670 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
7671 }
Leo Chang6f8870f2013-03-26 18:11:36 -07007672 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007673 if (rate_flags & eHAL_TX_RATE_SGI)
7674 {
7675 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
7676 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +05307677
Jeff Johnson295189b2012-06-20 16:38:30 -07007678#ifdef LINKSPEED_DEBUG_ENABLED
7679 pr_info("Reporting MCS rate %d flags %x\n",
7680 sinfo->txrate.mcs,
7681 sinfo->txrate.flags );
7682#endif //LINKSPEED_DEBUG_ENABLED
7683 }
7684 }
7685 else
7686 {
7687 // report current rate instead of max rate
7688
7689 if (rate_flags & eHAL_TX_RATE_LEGACY)
7690 {
7691 //provide to the UI in units of 100kbps
7692 sinfo->txrate.legacy = myRate;
7693#ifdef LINKSPEED_DEBUG_ENABLED
7694 pr_info("Reporting actual legacy rate %d\n", sinfo->txrate.legacy);
7695#endif //LINKSPEED_DEBUG_ENABLED
7696 }
7697 else
7698 {
7699 //must be MCS
7700 sinfo->txrate.mcs = pAdapter->hdd_stats.ClassA_stat.mcs_index;
Leo Chang6f8870f2013-03-26 18:11:36 -07007701#ifdef WLAN_FEATURE_11AC
7702 sinfo->txrate.nss = 1;
7703 if (rate_flags & eHAL_TX_RATE_VHT80)
7704 {
7705 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
7706 }
7707 else
7708#endif /* WLAN_FEATURE_11AC */
7709 {
7710 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
7711 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007712 if (rate_flags & eHAL_TX_RATE_SGI)
7713 {
7714 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
7715 }
7716 if (rate_flags & eHAL_TX_RATE_HT40)
7717 {
7718 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
7719 }
Leo Chang6f8870f2013-03-26 18:11:36 -07007720#ifdef WLAN_FEATURE_11AC
7721 else if (rate_flags & eHAL_TX_RATE_VHT80)
7722 {
7723 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
7724 }
7725#endif /* WLAN_FEATURE_11AC */
Jeff Johnson295189b2012-06-20 16:38:30 -07007726#ifdef LINKSPEED_DEBUG_ENABLED
7727 pr_info("Reporting actual MCS rate %d flags %x\n",
7728 sinfo->txrate.mcs,
7729 sinfo->txrate.flags );
7730#endif //LINKSPEED_DEBUG_ENABLED
7731 }
7732 }
7733 sinfo->filled |= STATION_INFO_TX_BITRATE;
7734
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -07007735 sinfo->tx_packets =
7736 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[0] +
7737 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[1] +
7738 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[2] +
7739 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[3];
7740
7741 sinfo->tx_retries =
7742 pAdapter->hdd_stats.summary_stat.retry_cnt[0] +
7743 pAdapter->hdd_stats.summary_stat.retry_cnt[1] +
7744 pAdapter->hdd_stats.summary_stat.retry_cnt[2] +
7745 pAdapter->hdd_stats.summary_stat.retry_cnt[3];
7746
7747 sinfo->tx_failed =
7748 pAdapter->hdd_stats.summary_stat.fail_cnt[0] +
7749 pAdapter->hdd_stats.summary_stat.fail_cnt[1] +
7750 pAdapter->hdd_stats.summary_stat.fail_cnt[2] +
7751 pAdapter->hdd_stats.summary_stat.fail_cnt[3];
7752
7753 sinfo->filled |=
7754 STATION_INFO_TX_PACKETS |
7755 STATION_INFO_TX_RETRIES |
7756 STATION_INFO_TX_FAILED;
7757
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307758 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7759 TRACE_CODE_HDD_CFG80211_GET_STA,
7760 pAdapter->sessionId, maxRate));
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -07007761 EXIT();
7762 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07007763}
7764
7765static int wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
Sameer Thalappilc9f26e92013-06-07 10:11:06 -07007766 struct net_device *dev, bool mode, int timeout)
Jeff Johnson295189b2012-06-20 16:38:30 -07007767{
7768 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +05307769 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07007770 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307771 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07007772
Jeff Johnsone7245742012-09-05 17:12:55 -07007773 ENTER();
7774
Jeff Johnson295189b2012-06-20 16:38:30 -07007775 if (NULL == pAdapter)
7776 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08007777 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007778 return -ENODEV;
7779 }
7780
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307781 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7782 TRACE_CODE_HDD_CFG80211_SET_POWER_MGMT,
7783 pAdapter->sessionId, timeout));
7784
Gopichand Nakkala20c4c042013-04-19 22:08:55 +05307785 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307786 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +05307787
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307788 if (0 != status)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307789 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307790 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7791 "%s: HDD context is not valid", __func__);
7792 return status;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307793 }
7794
Gopichand Nakkala20c4c042013-04-19 22:08:55 +05307795 if ((DRIVER_POWER_MODE_AUTO == !mode) &&
7796 (TRUE == pHddCtx->hdd_wlan_suspended) &&
7797 (pHddCtx->cfg_ini->fhostArpOffload) &&
7798 (eConnectionState_Associated ==
7799 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
7800 {
Amar Singhald53568e2013-09-26 11:03:45 -07007801
7802 hddLog(VOS_TRACE_LEVEL_INFO,
7803 "offload: in cfg80211_set_power_mgmt, calling arp offload");
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05307804 vos_status = hdd_conf_arp_offload(pAdapter, TRUE);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +05307805 if (!VOS_IS_STATUS_SUCCESS(vos_status))
7806 {
7807 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007808 "%s:Failed to enable ARPOFFLOAD Feature %d",
Gopichand Nakkala20c4c042013-04-19 22:08:55 +05307809 __func__, vos_status);
7810 }
7811 }
7812
Jeff Johnson295189b2012-06-20 16:38:30 -07007813 /**The get power cmd from the supplicant gets updated by the nl only
7814 *on successful execution of the function call
7815 *we are oppositely mapped w.r.t mode in the driver
7816 **/
7817 vos_status = wlan_hdd_enter_bmps(pAdapter, !mode);
7818
Jeff Johnsone7245742012-09-05 17:12:55 -07007819 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07007820 if (VOS_STATUS_E_FAILURE == vos_status)
7821 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307822 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7823 "%s: failed to enter bmps mode", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007824 return -EINVAL;
7825 }
7826 return 0;
7827}
7828
7829
7830#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
7831static int wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
7832 struct net_device *netdev,
7833 u8 key_index)
7834{
Jeff Johnsone7245742012-09-05 17:12:55 -07007835 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07007836 return 0;
7837}
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307838#endif //LINUX_VERSION_CODE
Jeff Johnson295189b2012-06-20 16:38:30 -07007839
7840#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
7841static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
7842 struct net_device *dev,
7843 struct ieee80211_txq_params *params)
7844{
Jeff Johnsone7245742012-09-05 17:12:55 -07007845 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07007846 return 0;
7847}
7848#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
7849static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
7850 struct ieee80211_txq_params *params)
7851{
Jeff Johnsone7245742012-09-05 17:12:55 -07007852 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07007853 return 0;
7854}
7855#endif //LINUX_VERSION_CODE
7856
7857static int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
7858 struct net_device *dev, u8 *mac)
7859{
7860 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307861 hdd_context_t *pHddCtx;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08007862 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307863 int status;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08007864 v_U8_t staId;
Jeff Johnson295189b2012-06-20 16:38:30 -07007865
Jeff Johnsone7245742012-09-05 17:12:55 -07007866 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307867
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307868 if ( NULL == pAdapter )
Jeff Johnson295189b2012-06-20 16:38:30 -07007869 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307870 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007871 return -EINVAL;
7872 }
7873
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307874 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7875 TRACE_CODE_HDD_CFG80211_DEL_STA,
7876 pAdapter->sessionId, pAdapter->device_mode));
7877
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307878 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7879 status = wlan_hdd_validate_context(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07007880
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307881 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007882 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307883 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7884 "%s: HDD context is not valid", __func__);
7885 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007886 }
7887
Jeff Johnson295189b2012-06-20 16:38:30 -07007888 if ( (WLAN_HDD_SOFTAP == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -07007889 || (WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -07007890 )
7891 {
7892 if( NULL == mac )
7893 {
7894 v_U16_t i;
7895 for(i = 0; i < WLAN_MAX_STA_COUNT; i++)
7896 {
Rajesh Chauhan18488fc2013-08-22 10:15:03 -07007897 if ((pAdapter->aStaInfo[i].isUsed) &&
7898 (!pAdapter->aStaInfo[i].isDeauthInProgress))
Jeff Johnson295189b2012-06-20 16:38:30 -07007899 {
7900 u8 *macAddr = pAdapter->aStaInfo[i].macAddrSTA.bytes;
7901 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -08007902 "%s: Delete STA with MAC::"
7903 MAC_ADDRESS_STR,
7904 __func__, MAC_ADDR_ARRAY(macAddr));
Rajesh Chauhan18488fc2013-08-22 10:15:03 -07007905 vos_status = hdd_softap_sta_deauth(pAdapter, macAddr);
7906 if (VOS_IS_STATUS_SUCCESS(vos_status))
7907 pAdapter->aStaInfo[i].isDeauthInProgress = TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -07007908 }
7909 }
7910 }
7911 else
7912 {
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08007913
7914 vos_status = hdd_softap_GetStaId(pAdapter,(v_MACADDR_t *)mac, &staId);
7915 if (!VOS_IS_STATUS_SUCCESS(vos_status))
7916 {
7917 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -08007918 "%s: Skip this DEL STA as this is not used::"
7919 MAC_ADDRESS_STR,
7920 __func__, MAC_ADDR_ARRAY(mac));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08007921 return -ENOENT;
7922 }
7923
7924 if( pAdapter->aStaInfo[staId].isDeauthInProgress == TRUE)
7925 {
7926 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -08007927 "%s: Skip this DEL STA as deauth is in progress::"
7928 MAC_ADDRESS_STR,
7929 __func__, MAC_ADDR_ARRAY(mac));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08007930 return -ENOENT;
7931 }
7932
7933 pAdapter->aStaInfo[staId].isDeauthInProgress = TRUE;
7934
Jeff Johnson295189b2012-06-20 16:38:30 -07007935 hddLog(VOS_TRACE_LEVEL_INFO,
7936 "%s: Delete STA with MAC::"
Arif Hussain24bafea2013-11-15 15:10:03 -08007937 MAC_ADDRESS_STR,
Jeff Johnson295189b2012-06-20 16:38:30 -07007938 __func__,
Arif Hussain24bafea2013-11-15 15:10:03 -08007939 MAC_ADDR_ARRAY(mac));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08007940
7941 vos_status = hdd_softap_sta_deauth(pAdapter, mac);
7942 if (!VOS_IS_STATUS_SUCCESS(vos_status))
7943 {
7944 pAdapter->aStaInfo[staId].isDeauthInProgress = FALSE;
7945 hddLog(VOS_TRACE_LEVEL_INFO,
7946 "%s: STA removal failed for ::"
Arif Hussain24bafea2013-11-15 15:10:03 -08007947 MAC_ADDRESS_STR,
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08007948 __func__,
Arif Hussain24bafea2013-11-15 15:10:03 -08007949 MAC_ADDR_ARRAY(mac));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08007950 return -ENOENT;
7951 }
7952
Jeff Johnson295189b2012-06-20 16:38:30 -07007953 }
7954 }
7955
7956 EXIT();
7957
7958 return 0;
7959}
7960
Hoonki Lee11f7dda2013-02-14 16:55:44 -08007961static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
7962 struct net_device *dev, u8 *mac, struct station_parameters *params)
7963{
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307964 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkalab977a972013-02-18 19:15:09 -08007965 int status = -EPERM;
Hoonki Lee11f7dda2013-02-14 16:55:44 -08007966#ifdef FEATURE_WLAN_TDLS
7967 u32 mask, set;
Hoonki Lee11f7dda2013-02-14 16:55:44 -08007968 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307969
7970 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7971 TRACE_CODE_HDD_CFG80211_ADD_STA,
7972 pAdapter->sessionId, params->listen_interval));
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007973 mask = params->sta_flags_mask;
7974
7975 set = params->sta_flags_set;
7976
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007977#ifdef WLAN_FEATURE_TDLS_DEBUG
7978 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7979 "%s: mask 0x%x set 0x%x " MAC_ADDRESS_STR,
7980 __func__, mask, set, MAC_ADDR_ARRAY(mac));
7981#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007982
7983 if (mask & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
7984 if (set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007985 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 0, NULL);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007986 }
7987 }
7988#endif
Gopichand Nakkalab977a972013-02-18 19:15:09 -08007989 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -07007990}
7991
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007992
7993#ifdef FEATURE_WLAN_LFR
Wilson Yang6507c4e2013-10-01 20:11:19 -07007994#define MAX_PMKSAIDS_IN_CACHE 8
7995
7996static tPmkidCacheInfo PMKIDCache[MAX_PMKSAIDS_IN_CACHE]; // HDD local cache
7997static tANI_U32 PMKIDCacheIndex; // HDD local Cache index
7998
7999
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008000static int wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
Jeff Johnsond13512a2012-07-17 11:42:19 -07008001 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008002{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308003 tANI_U32 j=0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008004 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
8005 tHalHandle halHandle;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308006 eHalStatus result;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308007 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008008 tANI_U8 BSSIDMatched = 0;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308009 hdd_context_t *pHddCtx;
Jeff Johnson0299d0a2013-10-30 12:37:43 -07008010 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: set PMKSA for " MAC_ADDRESS_STR,
8011 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
Jeff Johnsone7245742012-09-05 17:12:55 -07008012
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308013 // Validate pAdapter
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308014 if ( NULL == pAdapter )
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008015 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308016 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008017 return -EINVAL;
8018 }
8019
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308020 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8021 status = wlan_hdd_validate_context(pHddCtx);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008022
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308023 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008024 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308025 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8026 "%s: HDD context is not valid", __func__);
8027 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008028 }
8029
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308030 // Retrieve halHandle
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008031 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
8032
Wilson Yang6507c4e2013-10-01 20:11:19 -07008033 for (j = 0; j < PMKIDCacheIndex; j++)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008034 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308035 if(vos_mem_compare(PMKIDCache[j].BSSID,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008036 pmksa->bssid, WNI_CFG_BSSID_LEN))
8037 {
8038 /* BSSID matched previous entry. Overwrite it. */
8039 BSSIDMatched = 1;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308040 vos_mem_copy(PMKIDCache[j].BSSID,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008041 pmksa->bssid, WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308042 vos_mem_copy(PMKIDCache[j].PMKID,
8043 pmksa->pmkid,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008044 CSR_RSN_PMKID_SIZE);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308045 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Reusing cache entry %d.",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008046 __func__, j );
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008047 dump_bssid(pmksa->bssid);
8048 dump_pmkid(halHandle, pmksa->pmkid);
8049 break;
8050 }
8051 }
8052
Madan Mohan Koyyalamudic4b317d2012-10-18 19:43:08 -07008053 /* Check we compared all entries,if then take the first slot now */
Wilson Yang6507c4e2013-10-01 20:11:19 -07008054 if(j == MAX_PMKSAIDS_IN_CACHE) PMKIDCacheIndex=0;
Madan Mohan Koyyalamudic4b317d2012-10-18 19:43:08 -07008055
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008056 if (!BSSIDMatched)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308057 {
8058 // Now, we DON'T have a BSSID match, so take a new entry in the cache.
Wilson Yang6507c4e2013-10-01 20:11:19 -07008059 vos_mem_copy(PMKIDCache[PMKIDCacheIndex].BSSID,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308060 pmksa->bssid, ETHER_ADDR_LEN);
Wilson Yang6507c4e2013-10-01 20:11:19 -07008061 vos_mem_copy(PMKIDCache[PMKIDCacheIndex].PMKID,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308062 pmksa->pmkid,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008063 CSR_RSN_PMKID_SIZE);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308064 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Adding a new cache entry %d.",
Wilson Yang6507c4e2013-10-01 20:11:19 -07008065 __func__, PMKIDCacheIndex );
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008066 dump_bssid(pmksa->bssid);
8067 dump_pmkid(halHandle, pmksa->pmkid);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308068 // Increment the HDD Local Cache index
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008069 // The "i=0" doesn't work for the call to sme_RoamSetPMKIDCache() - LFR FIXME
Wilson Yang6507c4e2013-10-01 20:11:19 -07008070 if (PMKIDCacheIndex <= (MAX_PMKSAIDS_IN_CACHE-1)) PMKIDCacheIndex++; else PMKIDCacheIndex = 0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008071 }
8072
8073
8074 // Calling csrRoamSetPMKIDCache to configure the PMKIDs into the cache
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308075 //hddLog(LOG1, FL("%s: Calling csrRoamSetPMKIDCache with %d cache entries."),
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008076 // __func__, i );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308077 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Calling csrRoamSetPMKIDCache with %d cache entries.",
Wilson Yang6507c4e2013-10-01 20:11:19 -07008078 __func__, PMKIDCacheIndex );
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008079 // Finally set the PMKSA ID Cache in CSR
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308080 result = sme_RoamSetPMKIDCache(halHandle,pAdapter->sessionId,
8081 PMKIDCache,
Wilson Yang6507c4e2013-10-01 20:11:19 -07008082 PMKIDCacheIndex);
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308083 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
8084 TRACE_CODE_HDD_CFG80211_SET_PMKSA,
8085 pAdapter->sessionId, result));
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008086 return 0;
8087}
8088
8089
Wilson Yang6507c4e2013-10-01 20:11:19 -07008090
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008091static int wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
Wilson Yang6507c4e2013-10-01 20:11:19 -07008092 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008093{
Wilson Yang6507c4e2013-10-01 20:11:19 -07008094 tANI_U32 j=0;
8095 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
8096 tHalHandle halHandle;
Wilson Yang6507c4e2013-10-01 20:11:19 -07008097 tANI_U8 BSSIDMatched = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -07008098 hdd_context_t *pHddCtx;
Wilson Yangef657d32014-01-15 19:19:23 -08008099 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -07008100
Jeff Johnson0299d0a2013-10-30 12:37:43 -07008101 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: deleting PMKSA for " MAC_ADDRESS_STR,
8102 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
Wilson Yang6507c4e2013-10-01 20:11:19 -07008103
8104 /* Validate pAdapter */
8105 if (NULL == pAdapter)
8106 {
8107 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
8108 return -EINVAL;
8109 }
8110
8111 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8112 status = wlan_hdd_validate_context(pHddCtx);
8113
8114 if (0 != status)
8115 {
8116 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8117 "%s: HDD context is not valid", __func__);
8118 return status;
8119 }
8120
8121 /*Retrieve halHandle*/
8122 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
8123
8124 /*in case index is 0,no entry to delete*/
8125 if (0 == PMKIDCacheIndex)
8126 {
8127 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid entry to delete" ,
8128 __func__);
8129 return -EINVAL;
8130 }
8131
8132 /*find the matching PMKSA entry from j=0 to (index-1),
8133 * and delete the matched one
8134 */
8135 for (j = 0; j<PMKIDCacheIndex; j++)
8136 {
8137 if (vos_mem_compare(PMKIDCache[j].BSSID,
8138 pmksa->bssid,
8139 WNI_CFG_BSSID_LEN))
8140 {
8141 /* BSSID matched entry */
8142 BSSIDMatched = 1;
8143
8144 if (j<PMKIDCacheIndex-1)
8145 {
8146 /*replace the matching entry with the last entry in HDD local cache*/
8147 vos_mem_copy(PMKIDCache[j].BSSID,
8148 PMKIDCache[PMKIDCacheIndex-1].BSSID,
8149 WNI_CFG_BSSID_LEN);
8150 vos_mem_copy(PMKIDCache[j].PMKID,
8151 PMKIDCache[PMKIDCacheIndex-1].PMKID,
8152 CSR_RSN_PMKID_SIZE);
8153 }
8154
8155 /*clear the last entry in HDD cache ---[index-1]*/
Wilson Yang6507c4e2013-10-01 20:11:19 -07008156 vos_mem_zero(PMKIDCache[PMKIDCacheIndex-1].BSSID, WNI_CFG_BSSID_LEN);
8157 vos_mem_zero(PMKIDCache[PMKIDCacheIndex-1].PMKID, CSR_RSN_PMKID_SIZE);
8158
8159 /*reduce the PMKID array index*/
8160 PMKIDCacheIndex--;
8161
8162 /*delete the last PMKID cache in CSR*/
Wilson Yangef657d32014-01-15 19:19:23 -08008163 if (eHAL_STATUS_SUCCESS !=
8164 sme_RoamDelPMKIDfromCache(halHandle, pAdapter->sessionId, pmksa->bssid))
Wilson Yang6507c4e2013-10-01 20:11:19 -07008165 {
8166 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: cannot delete PMKSA %d CONTENT.",
8167 __func__,PMKIDCacheIndex);
Wilson Yangef657d32014-01-15 19:19:23 -08008168 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -07008169 }
8170
8171 dump_bssid(pmksa->bssid);
8172 dump_pmkid(halHandle,pmksa->pmkid);
8173
8174 break;
8175 }
8176 }
8177
8178 /* we compare all entries,but cannot find matching entry */
8179 if (j == MAX_PMKSAIDS_IN_CACHE && !BSSIDMatched)
8180 {
Jeff Johnson0299d0a2013-10-30 12:37:43 -07008181 hddLog(VOS_TRACE_LEVEL_FATAL,
8182 "%s: No such PMKSA entry existed " MAC_ADDRESS_STR,
8183 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
Wilson Yang6507c4e2013-10-01 20:11:19 -07008184 dump_bssid(pmksa->bssid);
8185 dump_pmkid(halHandle, pmksa->pmkid);
8186 return -EINVAL;
8187 }
Wilson Yangef657d32014-01-15 19:19:23 -08008188 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008189}
8190
Wilson Yang6507c4e2013-10-01 20:11:19 -07008191
8192
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008193static int wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
8194{
Wilson Yang6507c4e2013-10-01 20:11:19 -07008195 tANI_U32 j=0;
8196 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
8197 tHalHandle halHandle;
8198 hdd_context_t *pHddCtx;
8199 tANI_U8 *pBSSId;
Wilson Yangef657d32014-01-15 19:19:23 -08008200 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -07008201
8202 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: flushing PMKSA ",__func__);
8203
8204 /* Validate pAdapter */
8205 if (NULL == pAdapter)
8206 {
8207 hddLog(VOS_TRACE_LEVEL_ERROR,
8208 "%s: Invalid Adapter" ,__func__);
8209 return -EINVAL;
8210 }
8211
8212 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8213 status = wlan_hdd_validate_context(pHddCtx);
8214
8215 if (0 != status)
8216 {
8217 hddLog(VOS_TRACE_LEVEL_ERROR,
8218 "%s: HDD context is not valid", __func__);
8219 return status;
8220 }
8221
8222 /*Retrieve halHandle*/
8223 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
8224
8225 /*in case index is 0,no entry to delete*/
8226 if (0 == PMKIDCacheIndex)
8227 {
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +05308228 hddLog(VOS_TRACE_LEVEL_ERROR, FL("No entries to flush"));
Wilson Yang6507c4e2013-10-01 20:11:19 -07008229 return -EINVAL;
8230 }
8231
8232 /*delete all the PMKSA one by one */
8233 for (j = 0; j<PMKIDCacheIndex; j++)
8234 {
Wilson Yang6507c4e2013-10-01 20:11:19 -07008235 pBSSId =(tANI_U8 *)(PMKIDCache[j].BSSID);
Wilson Yang6507c4e2013-10-01 20:11:19 -07008236
8237 /*delete the PMKID in CSR*/
Wilson Yangef657d32014-01-15 19:19:23 -08008238 if (eHAL_STATUS_SUCCESS !=
8239 sme_RoamDelPMKIDfromCache(halHandle, pAdapter->sessionId, pBSSId))
Wilson Yang6507c4e2013-10-01 20:11:19 -07008240 {
8241 hddLog(VOS_TRACE_LEVEL_ERROR ,"%s cannot flush PMKIDCache %d.",
8242 __func__,j);
Wilson Yangef657d32014-01-15 19:19:23 -08008243 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -07008244 }
Kiet Lam8d21d5b2013-10-31 17:18:29 +05308245 /*clear the entry in HDD cache 0--index-1 */
8246 vos_mem_zero(PMKIDCache[j].BSSID, WNI_CFG_BSSID_LEN);
8247 vos_mem_zero(PMKIDCache[j].PMKID, CSR_RSN_PMKID_SIZE);
Wilson Yang6507c4e2013-10-01 20:11:19 -07008248 }
8249
8250 PMKIDCacheIndex = 0;
Wilson Yangef657d32014-01-15 19:19:23 -08008251 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008252}
8253#endif
8254
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07008255#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308256static int wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07008257 struct net_device *dev, struct cfg80211_update_ft_ies_params *ftie)
8258{
8259 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
8260 hdd_station_ctx_t *pHddStaCtx;
8261
8262 if (NULL == pAdapter)
8263 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08008264 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07008265 return -ENODEV;
8266 }
8267
8268 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
8269
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308270 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
8271 TRACE_CODE_HDD_CFG80211_UPDATE_FT_IES,
8272 pAdapter->sessionId, pHddStaCtx->conn_info.connState));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07008273 // Added for debug on reception of Re-assoc Req.
8274 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
8275 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08008276 hddLog(LOGE, FL("Called with Ie of length = %zu when not associated"),
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07008277 ftie->ie_len);
Arif Hussain6d2a3322013-11-17 19:50:10 -08008278 hddLog(LOGE, FL("Should be Re-assoc Req IEs"));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07008279 }
8280
8281#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG
Arif Hussain6d2a3322013-11-17 19:50:10 -08008282 hddLog(LOGE, FL("%s called with Ie of length = %zu"), __func__,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07008283 ftie->ie_len);
8284#endif
8285
8286 // Pass the received FT IEs to SME
Gopichand Nakkala356fb102013-03-06 12:34:04 +05308287 sme_SetFTIEs( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
8288 (const u8 *)ftie->ie,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07008289 ftie->ie_len);
8290 return 0;
8291}
8292#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008293
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308294#ifdef FEATURE_WLAN_SCAN_PNO
8295
8296void hdd_cfg80211_sched_scan_done_callback(void *callbackContext,
8297 tSirPrefNetworkFoundInd *pPrefNetworkFoundInd)
8298{
8299 int ret;
8300 hdd_adapter_t* pAdapter = (hdd_adapter_t*)callbackContext;
8301 hdd_context_t *pHddCtx;
8302
Nirav Shah80830bf2013-12-31 16:35:12 +05308303 ENTER();
8304
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308305 if (NULL == pAdapter)
8306 {
Agarwal Ashish971c2882013-10-30 20:11:12 +05308307 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308308 "%s: HDD adapter is Null", __func__);
8309 return ;
8310 }
8311
8312 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8313 if (NULL == pHddCtx)
8314 {
8315 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8316 "%s: HDD context is Null!!!", __func__);
8317 return ;
8318 }
8319
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05308320 spin_lock(&pHddCtx->schedScan_lock);
8321 if (TRUE == pHddCtx->isWiphySuspended)
8322 {
8323 pHddCtx->isSchedScanUpdatePending = TRUE;
8324 spin_unlock(&pHddCtx->schedScan_lock);
8325 hddLog(VOS_TRACE_LEVEL_INFO,
8326 "%s: Update cfg80211 scan database after it resume", __func__);
8327 return ;
8328 }
8329 spin_unlock(&pHddCtx->schedScan_lock);
8330
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308331 ret = wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter);
8332
8333 if (0 > ret)
8334 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
8335
8336 cfg80211_sched_scan_results(pHddCtx->wiphy);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05308337 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8338 "%s: cfg80211 scan result database updated", __func__);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308339}
8340
8341/*
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +05308342 * FUNCTION: wlan_hdd_is_pno_allowed
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +05308343 * Disallow pno if any session is active
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +05308344 */
8345static eHalStatus wlan_hdd_is_pno_allowed(hdd_adapter_t *pAdapter)
8346{
8347 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
8348 hdd_adapter_t *pTempAdapter = NULL;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +05308349 hdd_station_ctx_t *pStaCtx;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +05308350 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8351 int status = 0;
8352 status = hdd_get_front_adapter(pHddCtx, &pAdapterNode);
8353
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +05308354 /* The current firmware design does not allow PNO during any
8355 * active sessions. Hence, determine the active sessions
8356 * and return a failure.
8357 */
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +05308358 while ((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status))
8359 {
8360 pTempAdapter = pAdapterNode->pAdapter;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +05308361 pStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pTempAdapter);
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +05308362
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +05308363 if (((WLAN_HDD_INFRA_STATION == pTempAdapter->device_mode)
8364 && (eConnectionState_NotConnected != pStaCtx->conn_info.connState))
8365 || (WLAN_HDD_P2P_CLIENT == pTempAdapter->device_mode)
8366 || (WLAN_HDD_P2P_GO == pTempAdapter->device_mode)
8367 || (WLAN_HDD_SOFTAP == pTempAdapter->device_mode)
8368 )
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +05308369 {
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +05308370 return eHAL_STATUS_FAILURE;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +05308371 }
8372 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
8373 pAdapterNode = pNext;
8374 }
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +05308375 return eHAL_STATUS_SUCCESS;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +05308376}
8377
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +05308378void hdd_cfg80211_sched_scan_start_status_cb(void *callbackContext, VOS_STATUS status)
8379{
8380 hdd_adapter_t *pAdapter = callbackContext;
8381 hdd_context_t *pHddCtx;
8382
8383 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
8384 {
8385 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8386 FL("Invalid adapter or adapter has invalid magic"));
8387 return;
8388 }
8389
8390 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8391 if (0 != wlan_hdd_validate_context(pHddCtx))
8392 {
8393 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8394 FL("HDD context is not valid"));
8395 return;
8396 }
8397
8398 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8399 FL("PNO enable response status = %d"), status);
8400
8401 pAdapter->pno_req_status = (status == VOS_STATUS_SUCCESS) ? 0 : -EBUSY;
8402 complete(&pAdapter->pno_comp_var);
8403}
8404
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +05308405/*
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308406 * FUNCTION: wlan_hdd_cfg80211_sched_scan_start
8407 * NL interface to enable PNO
8408 */
8409static int wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
8410 struct net_device *dev, struct cfg80211_sched_scan_request *request)
8411{
8412 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
8413 tpSirPNOScanReq pPnoRequest = NULL;
8414 hdd_context_t *pHddCtx;
8415 tHalHandle hHal;
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +05308416 v_U32_t i, indx, num_ch, tempInterval;
Sushant Kaushikd62d9782014-02-19 15:39:40 +05308417 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
8418 u8 channels_allowed[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308419 v_U32_t num_channels_allowed = WNI_CFG_VALID_CHANNEL_LIST_LEN;
8420 eHalStatus status = eHAL_STATUS_FAILURE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308421 int ret = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308422
8423 if (NULL == pAdapter)
8424 {
8425 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
8426 "%s: HDD adapter is Null", __func__);
8427 return -ENODEV;
8428 }
8429
8430 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05308431 ret = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308432
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05308433 if (0 != ret)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308434 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05308435 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8436 "%s: HDD context is not valid", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308437 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308438 }
8439
8440 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
8441 if (NULL == hHal)
8442 {
8443 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8444 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05308445 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308446 }
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +05308447
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +05308448 if (eHAL_STATUS_SUCCESS != wlan_hdd_is_pno_allowed(pAdapter))
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +05308449 {
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +05308450 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +05308451 FL("Cannot handle sched_scan"));
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +05308452 return -EBUSY;
8453 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308454
c_hpothu37f21312014-04-09 21:49:54 +05308455 if (TRUE == pHddCtx->isPnoEnable)
8456 {
8457 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
8458 FL("already PNO is enabled"));
8459 return -EBUSY;
8460 }
8461 pHddCtx->isPnoEnable = TRUE;
8462
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308463 pPnoRequest = (tpSirPNOScanReq) vos_mem_malloc(sizeof (tSirPNOScanReq));
8464 if (NULL == pPnoRequest)
8465 {
8466 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
8467 "%s: vos_mem_malloc failed", __func__);
c_hpothu37f21312014-04-09 21:49:54 +05308468 pHddCtx->isPnoEnable = FALSE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308469 return -ENOMEM;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308470 }
8471
Madan Mohan Koyyalamudic3f04352013-09-26 19:21:48 +05308472 memset(pPnoRequest, 0, sizeof (tSirPNOScanReq));
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308473 pPnoRequest->enable = 1; /*Enable PNO */
8474 pPnoRequest->ucNetworksCount = request->n_match_sets;
8475
8476 if (( !pPnoRequest->ucNetworksCount ) ||
8477 ( pPnoRequest->ucNetworksCount > SIR_PNO_MAX_SUPP_NETWORKS ))
8478 {
8479 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +05308480 "%s: Network input is not correct %d",
8481 __func__, pPnoRequest->ucNetworksCount);
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308482 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308483 goto error;
8484 }
8485
8486 if ( SIR_PNO_MAX_NETW_CHANNELS_EX < request->n_channels )
8487 {
8488 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +05308489 "%s: Incorrect number of channels %d",
8490 __func__, request->n_channels);
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308491 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308492 goto error;
8493 }
8494
8495 /* Framework provides one set of channels(all)
8496 * common for all saved profile */
8497 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
8498 channels_allowed, &num_channels_allowed))
8499 {
8500 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8501 "%s: failed to get valid channel list", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308502 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308503 goto error;
8504 }
8505 /* Checking each channel against allowed channel list */
8506 num_ch = 0;
Nirav Shah80830bf2013-12-31 16:35:12 +05308507 if (request->n_channels)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308508 {
Nirav Shah80830bf2013-12-31 16:35:12 +05308509 char chList [(request->n_channels*5)+1];
8510 int len;
8511 for (i = 0, len = 0; i < request->n_channels; i++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308512 {
Nirav Shah80830bf2013-12-31 16:35:12 +05308513 for (indx = 0; indx < num_channels_allowed; indx++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308514 {
Nirav Shah80830bf2013-12-31 16:35:12 +05308515 if (request->channels[i]->hw_value == channels_allowed[indx])
8516 {
8517 valid_ch[num_ch++] = request->channels[i]->hw_value;
8518 len += snprintf(chList+len, 5, "%d ",
8519 request->channels[i]->hw_value);
8520 break ;
8521 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308522 }
8523 }
Nirav Shah80830bf2013-12-31 16:35:12 +05308524 hddLog(VOS_TRACE_LEVEL_INFO,"Channel-List: %s ", chList);
8525 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308526
8527 /* Filling per profile params */
8528 for (i = 0; i < pPnoRequest->ucNetworksCount; i++)
8529 {
8530 pPnoRequest->aNetworks[i].ssId.length =
8531 request->match_sets[i].ssid.ssid_len;
8532
8533 if (( 0 == pPnoRequest->aNetworks[i].ssId.length ) ||
8534 ( pPnoRequest->aNetworks[i].ssId.length > 32 ) )
8535 {
8536 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +05308537 "%s: SSID Len %d is not correct for network %d",
8538 __func__, pPnoRequest->aNetworks[i].ssId.length, i);
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308539 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308540 goto error;
8541 }
8542
8543 memcpy(pPnoRequest->aNetworks[i].ssId.ssId,
8544 request->match_sets[i].ssid.ssid,
8545 request->match_sets[i].ssid.ssid_len);
8546 pPnoRequest->aNetworks[i].authentication = 0; /*eAUTH_TYPE_ANY*/
8547 pPnoRequest->aNetworks[i].encryption = 0; /*eED_ANY*/
8548 pPnoRequest->aNetworks[i].bcastNetwType = 0; /*eBCAST_UNKNOWN*/
8549
8550 /*Copying list of valid channel into request */
8551 memcpy(pPnoRequest->aNetworks[i].aChannels, valid_ch, num_ch);
8552 pPnoRequest->aNetworks[i].ucChannelCount = num_ch;
8553
8554 pPnoRequest->aNetworks[i].rssiThreshold = 0; //Default value
8555 }
8556
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +05308557 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnson59a121e2013-11-30 09:46:08 -08008558 "request->ie_len = %zu", request->ie_len);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +05308559 if ((0 < request->ie_len) && (NULL != request->ie))
8560 {
8561 pPnoRequest->us24GProbeTemplateLen = request->ie_len;
8562 memcpy(&pPnoRequest->p24GProbeTemplate, request->ie,
8563 pPnoRequest->us24GProbeTemplateLen);
8564
8565 pPnoRequest->us5GProbeTemplateLen = request->ie_len;
8566 memcpy(&pPnoRequest->p5GProbeTemplate, request->ie,
8567 pPnoRequest->us5GProbeTemplateLen);
8568 }
8569
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +05308570 /* Driver gets only one time interval which is hardcoded in
8571 * supplicant for 10000ms. Taking power consumption into account 6 timers
8572 * will be used, Timervalue is increased exponentially i.e 10,20,40,
8573 * 80,160,320 secs. And number of scan cycle for each timer
8574 * is configurable through INI param gPNOScanTimerRepeatValue.
8575 * If it is set to 0 only one timer will be used and PNO scan cycle
8576 * will be repeated after each interval specified by supplicant
8577 * till PNO is disabled.
8578 */
8579 if (0 == pHddCtx->cfg_ini->configPNOScanTimerRepeatValue)
8580 pPnoRequest->scanTimers.ucScanTimersCount = HDD_PNO_SCAN_TIMERS_SET_ONE;
8581 else
8582 pPnoRequest->scanTimers.ucScanTimersCount =
8583 HDD_PNO_SCAN_TIMERS_SET_MULTIPLE;
8584
8585 tempInterval = (request->interval)/1000;
8586 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8587 "Base scan interval = %d PNOScanTimerRepeatValue = %d",
8588 tempInterval, pHddCtx->cfg_ini->configPNOScanTimerRepeatValue);
8589 for ( i = 0; i < pPnoRequest->scanTimers.ucScanTimersCount; i++)
8590 {
8591 pPnoRequest->scanTimers.aTimerValues[i].uTimerRepeat =
8592 pHddCtx->cfg_ini->configPNOScanTimerRepeatValue;
8593 pPnoRequest->scanTimers.aTimerValues[i].uTimerValue = tempInterval;
8594 tempInterval *= 2;
8595 }
8596 //Repeat last timer until pno disabled.
8597 pPnoRequest->scanTimers.aTimerValues[i-1].uTimerRepeat = 0;
8598
Madan Mohan Koyyalamudid206c7b2013-09-26 22:54:51 +05308599 pPnoRequest->modePNO = SIR_PNO_MODE_IMMEDIATE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308600
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +05308601 INIT_COMPLETION(pAdapter->pno_comp_var);
8602 pPnoRequest->statusCallback = hdd_cfg80211_sched_scan_start_status_cb;
8603 pPnoRequest->callbackContext = pAdapter;
8604 pAdapter->pno_req_status = 0;
8605
Nirav Shah80830bf2013-12-31 16:35:12 +05308606 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8607 "SessionId %d, enable %d, modePNO %d, ucScanTimersCount %d",
8608 pAdapter->sessionId, pPnoRequest->enable, pPnoRequest->modePNO,
8609 pPnoRequest->scanTimers.ucScanTimersCount);
8610
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308611 status = sme_SetPreferredNetworkList(WLAN_HDD_GET_HAL_CTX(pAdapter),
8612 pPnoRequest, pAdapter->sessionId,
8613 hdd_cfg80211_sched_scan_done_callback, pAdapter);
8614 if (eHAL_STATUS_SUCCESS != status)
8615 {
8616 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +05308617 "%s: Failed to enable PNO", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308618 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308619 goto error;
8620 }
8621
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +05308622 ret = wait_for_completion_timeout(
8623 &pAdapter->pno_comp_var,
8624 msecs_to_jiffies(WLAN_WAIT_TIME_PNO));
8625 if (0 >= ret)
8626 {
8627 // Did not receive the response for PNO enable in time.
8628 // Assuming the PNO enable was success.
8629 // Returning error from here, because we timeout, results
8630 // in side effect of Wifi (Wifi Setting) not to work.
8631 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8632 FL("Timed out waiting for PNO to be Enabled"));
8633 ret = 0;
8634 goto error;
8635 }
8636
8637 ret = pAdapter->pno_req_status;
c_hpothu37f21312014-04-09 21:49:54 +05308638 return ret;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05308639
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308640error:
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +05308641 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8642 FL("PNO scanRequest offloaded ret = %d"), ret);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308643 vos_mem_free(pPnoRequest);
c_hpothu37f21312014-04-09 21:49:54 +05308644 pHddCtx->isPnoEnable = FALSE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308645 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308646}
8647
8648/*
8649 * FUNCTION: wlan_hdd_cfg80211_sched_scan_stop
8650 * NL interface to disable PNO
8651 */
8652static int wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
8653 struct net_device *dev)
8654{
8655 eHalStatus status = eHAL_STATUS_FAILURE;
8656 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
8657 hdd_context_t *pHddCtx;
8658 tHalHandle hHal;
8659 tpSirPNOScanReq pPnoRequest = NULL;
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308660 int ret = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308661
8662 ENTER();
8663
8664 if (NULL == pAdapter)
8665 {
8666 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
8667 "%s: HDD adapter is Null", __func__);
8668 return -ENODEV;
8669 }
8670
8671 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308672
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308673 if (NULL == pHddCtx)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308674 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05308675 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308676 "%s: HDD context is Null", __func__);
8677 return -ENODEV;
8678 }
8679
8680 /* The return 0 is intentional when isLogpInProgress and
8681 * isLoadUnloadInProgress. We did observe a crash due to a return of
8682 * failure in sched_scan_stop , especially for a case where the unload
8683 * of the happens at the same time. The function __cfg80211_stop_sched_scan
8684 * was clearing rdev->sched_scan_req only when the sched_scan_stop returns
8685 * success. If it returns a failure , then its next invocation due to the
8686 * clean up of the second interface will have the dev pointer corresponding
8687 * to the first one leading to a crash.
8688 */
8689 if (pHddCtx->isLogpInProgress)
8690 {
8691 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8692 "%s: LOGP in Progress. Ignore!!!", __func__);
8693 return ret;
8694 }
8695
Mihir Shete18156292014-03-11 15:38:30 +05308696 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308697 {
8698 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8699 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
8700 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308701 }
8702
8703 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
8704 if (NULL == hHal)
8705 {
8706 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8707 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05308708 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308709 }
8710
8711 pPnoRequest = (tpSirPNOScanReq) vos_mem_malloc(sizeof (tSirPNOScanReq));
8712 if (NULL == pPnoRequest)
8713 {
8714 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
8715 "%s: vos_mem_malloc failed", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308716 return -ENOMEM;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308717 }
8718
8719 memset(pPnoRequest, 0, sizeof (tSirPNOScanReq));
8720 pPnoRequest->enable = 0; /* Disable PNO */
8721 pPnoRequest->ucNetworksCount = 0;
8722
8723 status = sme_SetPreferredNetworkList(hHal, pPnoRequest,
8724 pAdapter->sessionId,
8725 NULL, pAdapter);
8726 if (eHAL_STATUS_SUCCESS != status)
8727 {
8728 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8729 "Failed to disabled PNO");
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308730 ret = -EINVAL;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +05308731 goto error;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308732 }
c_hpothu37f21312014-04-09 21:49:54 +05308733 pHddCtx->isPnoEnable = FALSE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308734
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +05308735error:
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05308736 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +05308737 FL("PNO scan disabled ret = %d"), ret);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308738 vos_mem_free(pPnoRequest);
8739
8740 EXIT();
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308741 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308742}
8743
8744#endif /*FEATURE_WLAN_SCAN_PNO*/
8745
8746
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008747#ifdef FEATURE_WLAN_TDLS
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +05308748#if TDLS_MGMT_VERSION2
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008749static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
8750 u8 *peer, u8 action_code, u8 dialog_token,
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +05308751 u16 status_code, u32 peer_capability, const u8 *buf, size_t len)
8752#else
8753static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
8754 u8 *peer, u8 action_code, u8 dialog_token,
8755 u16 status_code, const u8 *buf, size_t len)
8756#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008757{
8758
8759 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
8760 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008761 u8 peerMac[6];
8762 VOS_STATUS status;
Gopichand Nakkala05922802013-03-14 12:23:19 -07008763 int max_sta_failed = 0;
Hoonki Leea34dd892013-02-05 22:56:02 -08008764 int responder;
Hoonki Leed37cbb32013-04-20 00:31:14 -07008765 long rc;
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +05308766#if !(TDLS_MGMT_VERSION2)
8767 u32 peer_capability = 0;
8768#endif
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05308769 tANI_U16 numCurrTdlsPeers;
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008770
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308771 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
8772 TRACE_CODE_HDD_CFG80211_TDLS_MGMT,
8773 pAdapter->sessionId, action_code));
Hoonki Lee11f7dda2013-02-14 16:55:44 -08008774 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008775 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308776 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008777 "Invalid arguments");
8778 return -EINVAL;
8779 }
8780
Sameer Thalappil75ea31a2013-02-21 19:38:16 -08008781 if (pHddCtx->isLogpInProgress)
8782 {
8783 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8784 "%s:LOGP in Progress. Ignore!!!", __func__);
Gopichand Nakkala05922802013-03-14 12:23:19 -07008785 wlan_hdd_tdls_set_link_status(pAdapter, peer, eTDLS_LINK_IDLE);
Sameer Thalappil75ea31a2013-02-21 19:38:16 -08008786 return -EBUSY;
8787 }
8788
Hoonki Lee27511902013-03-14 18:19:06 -07008789 if (eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode)
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008790 {
Hoonki Lee27511902013-03-14 18:19:06 -07008791 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
8792 "%s: TDLS mode is disabled OR not enabled in FW."
8793 MAC_ADDRESS_STR " action %d declined.",
8794 __func__, MAC_ADDR_ARRAY(peer), action_code);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008795 return -ENOTSUPP;
8796 }
Lee Hoonkic1262f22013-01-24 21:59:00 -08008797
Hoonki Lee27511902013-03-14 18:19:06 -07008798 /* other than teardown frame, other mgmt frames are not sent if disabled */
8799 if (SIR_MAC_TDLS_TEARDOWN != action_code)
8800 {
8801 /* if tdls_mode is disabled to respond to peer's request */
8802 if (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode)
8803 {
8804 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
8805 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07008806 " TDLS mode is disabled. action %d declined.",
8807 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee27511902013-03-14 18:19:06 -07008808
8809 return -ENOTSUPP;
8810 }
8811 }
8812
Gopichand Nakkalab977a972013-02-18 19:15:09 -08008813 if (WLAN_IS_TDLS_SETUP_ACTION(action_code))
8814 {
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308815 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, peer, TRUE))
Gopichand Nakkalab977a972013-02-18 19:15:09 -08008816 {
8817 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07008818 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07008819 " TDLS setup is ongoing. action %d declined.",
8820 __func__, MAC_ADDR_ARRAY(peer), action_code);
8821 return -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -08008822 }
8823 }
8824
Hoonki Lee11f7dda2013-02-14 16:55:44 -08008825 if (SIR_MAC_TDLS_SETUP_REQ == action_code ||
8826 SIR_MAC_TDLS_SETUP_RSP == action_code )
Lee Hoonkic1262f22013-01-24 21:59:00 -08008827 {
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05308828 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
8829 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Lee Hoonkic1262f22013-01-24 21:59:00 -08008830 {
8831 /* supplicant still sends tdls_mgmt(SETUP_REQ) even after
8832 we return error code at 'add_station()'. Hence we have this
8833 check again in addtion to add_station().
8834 Anyway, there is no hard to double-check. */
Hoonki Lee11f7dda2013-02-14 16:55:44 -08008835 if (SIR_MAC_TDLS_SETUP_REQ == action_code)
Lee Hoonkic1262f22013-01-24 21:59:00 -08008836 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07008837 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8838 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05308839 " TDLS Max peer already connected. action (%d) declined. Num of peers (%d), Max allowed (%d).",
8840 __func__, MAC_ADDR_ARRAY(peer), action_code,
8841 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Sunil Dutt388ac8f2013-11-28 18:06:52 +05308842 return -EINVAL;
Lee Hoonkic1262f22013-01-24 21:59:00 -08008843 }
8844 else
8845 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -08008846 /* maximum reached. tweak to send error code to peer and return
8847 error code to supplicant */
Lee Hoonkic1262f22013-01-24 21:59:00 -08008848 status_code = eSIR_MAC_UNSPEC_FAILURE_STATUS;
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07008849 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8850 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05308851 " TDLS Max peer already connected, send response status (%d). Num of peers (%d), Max allowed (%d).",
8852 __func__, MAC_ADDR_ARRAY(peer), status_code,
8853 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -07008854 max_sta_failed = -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -08008855 /* fall through to send setup resp with failure status
8856 code */
Lee Hoonkic1262f22013-01-24 21:59:00 -08008857 }
8858 }
Hoonki Lee11f7dda2013-02-14 16:55:44 -08008859 else
8860 {
8861 hddTdlsPeer_t *pTdlsPeer;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308862 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008863 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Hoonki Lee11f7dda2013-02-14 16:55:44 -08008864 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07008865 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07008866 "%s:" MAC_ADDRESS_STR " already connected. action %d declined.",
8867 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee11f7dda2013-02-14 16:55:44 -08008868 return -EPERM;
8869 }
8870 }
Lee Hoonkic1262f22013-01-24 21:59:00 -08008871 }
Hoonki Lee11f7dda2013-02-14 16:55:44 -08008872 vos_mem_copy(peerMac, peer, 6);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008873
Hoonki Lee1090c6a2013-01-16 17:40:54 -08008874#ifdef WLAN_FEATURE_TDLS_DEBUG
8875 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +05308876 "%s: " MAC_ADDRESS_STR " action %d, dialog_token %d status %d, len = %zu",
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07008877 "tdls_mgmt", MAC_ADDR_ARRAY(peer),
8878 action_code, dialog_token, status_code, len);
Hoonki Lee1090c6a2013-01-16 17:40:54 -08008879#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008880
Hoonki Leea34dd892013-02-05 22:56:02 -08008881 /*Except teardown responder will not be used so just make 0*/
8882 responder = 0;
Hoonki Lee11f7dda2013-02-14 16:55:44 -08008883 if (SIR_MAC_TDLS_TEARDOWN == action_code)
Hoonki Leea34dd892013-02-05 22:56:02 -08008884 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -07008885
8886 hddTdlsPeer_t *pTdlsPeer;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308887 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peerMac, TRUE);
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -07008888
8889 if(pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
8890 responder = pTdlsPeer->is_responder;
8891 else
Hoonki Leea34dd892013-02-05 22:56:02 -08008892 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -07008893 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +05308894 "%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 -07008895 __func__, MAC_ADDR_ARRAY(peer), (NULL == pTdlsPeer) ? -1 : pTdlsPeer->link_status,
8896 dialog_token, status_code, len);
8897 return -EPERM;
Hoonki Leea34dd892013-02-05 22:56:02 -08008898 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008899 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008900
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +05308901 /* For explicit trigger of DIS_REQ come out of BMPS for
8902 successfully receiving DIS_RSP from peer. */
Hoonki Lee14621352013-04-16 17:51:19 -07008903 if ((SIR_MAC_TDLS_SETUP_RSP == action_code) ||
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +05308904 (SIR_MAC_TDLS_DIS_RSP == action_code) ||
8905 (SIR_MAC_TDLS_DIS_REQ == action_code))
Hoonki Lee14621352013-04-16 17:51:19 -07008906 {
8907 if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter)))
8908 {
8909 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +05308910 "%s: Sending frame action_code %u.Disable BMPS", __func__, action_code);
Hoonki Lee14621352013-04-16 17:51:19 -07008911 hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
8912 }
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +05308913 if (SIR_MAC_TDLS_DIS_REQ != action_code)
8914 wlan_hdd_tdls_set_cap(pAdapter, peerMac, eTDLS_CAP_SUPPORTED);
Hoonki Lee14621352013-04-16 17:51:19 -07008915 }
8916
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008917 /* make sure doesn't call send_mgmt() while it is pending */
8918 if (TDLS_CTX_MAGIC == pAdapter->mgmtTxCompletionStatus)
8919 {
8920 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008921 "%s: " MAC_ADDRESS_STR " action %d couldn't sent, as one is pending. return EBUSY",
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008922 __func__, MAC_ADDR_ARRAY(peer), action_code);
8923 return -EBUSY;
8924 }
8925
8926 pAdapter->mgmtTxCompletionStatus = TDLS_CTX_MAGIC;
Gopichand Nakkalab977a972013-02-18 19:15:09 -08008927 INIT_COMPLETION(pAdapter->tdls_mgmt_comp);
8928
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008929 status = sme_SendTdlsMgmtFrame(WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
Pradeep Reddy POTTETIca171f82014-03-21 14:17:35 +05308930 peerMac, action_code, dialog_token, status_code, peer_capability, (tANI_U8 *)buf, len, responder);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008931
Gopichand Nakkalab977a972013-02-18 19:15:09 -08008932 if (VOS_STATUS_SUCCESS != status)
8933 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008934 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8935 "%s: sme_SendTdlsMgmtFrame failed!", __func__);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008936 pAdapter->mgmtTxCompletionStatus = FALSE;
Hoonki Lee14621352013-04-16 17:51:19 -07008937 wlan_hdd_tdls_check_bmps(pAdapter);
Sunil Dutt388ac8f2013-11-28 18:06:52 +05308938 return -EINVAL;
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008939 }
8940
Hoonki Leed37cbb32013-04-20 00:31:14 -07008941 rc = wait_for_completion_interruptible_timeout(&pAdapter->tdls_mgmt_comp,
8942 msecs_to_jiffies(WAIT_TIME_TDLS_MGMT));
8943
8944 if ((rc <= 0) || (TRUE != pAdapter->mgmtTxCompletionStatus))
Gopichand Nakkalab977a972013-02-18 19:15:09 -08008945 {
Hoonki Leed37cbb32013-04-20 00:31:14 -07008946 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07008947 "%s: Mgmt Tx Completion failed status %ld TxCompletion %u",
Hoonki Leed37cbb32013-04-20 00:31:14 -07008948 __func__, rc, pAdapter->mgmtTxCompletionStatus);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008949 pAdapter->mgmtTxCompletionStatus = FALSE;
Yue Ma4f55ef32014-01-23 16:45:33 -08008950
8951 if (pHddCtx->isLogpInProgress)
8952 {
8953 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8954 "%s: LOGP in Progress. Ignore!!!", __func__);
8955 return -EAGAIN;
8956 }
8957
Hoonki Leed37cbb32013-04-20 00:31:14 -07008958 wlan_hdd_tdls_check_bmps(pAdapter);
Sunil Dutt388ac8f2013-11-28 18:06:52 +05308959 return -EINVAL;
Gopichand Nakkalab977a972013-02-18 19:15:09 -08008960 }
8961
Gopichand Nakkala05922802013-03-14 12:23:19 -07008962 if (max_sta_failed)
Hoonki Lee14621352013-04-16 17:51:19 -07008963 {
8964 wlan_hdd_tdls_check_bmps(pAdapter);
Gopichand Nakkala05922802013-03-14 12:23:19 -07008965 return max_sta_failed;
Hoonki Lee14621352013-04-16 17:51:19 -07008966 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -08008967
Hoonki Leea34dd892013-02-05 22:56:02 -08008968 if (SIR_MAC_TDLS_SETUP_RSP == action_code)
8969 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -08008970 wlan_hdd_tdls_set_responder(pAdapter, peerMac, TRUE);
Hoonki Leea34dd892013-02-05 22:56:02 -08008971 }
8972 else if (SIR_MAC_TDLS_SETUP_CNF == action_code)
8973 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -08008974 wlan_hdd_tdls_set_responder(pAdapter, peerMac, FALSE);
Hoonki Leea34dd892013-02-05 22:56:02 -08008975 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008976
8977 return 0;
8978}
8979
8980static int wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
8981 u8 *peer, enum nl80211_tdls_operation oper)
8982{
8983 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
8984 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308985 int status;
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008986 hddTdlsPeer_t *pTdlsPeer;
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008987
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308988 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
8989 TRACE_CODE_HDD_CFG80211_TDLS_OPER,
8990 pAdapter->sessionId, oper));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308991 if ( NULL == peer )
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008992 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -08008993 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chilam Ngc4244af2013-04-01 15:37:32 -07008994 "%s: Invalid arguments", __func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008995 return -EINVAL;
8996 }
Hoonki Lee1090c6a2013-01-16 17:40:54 -08008997
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308998 status = wlan_hdd_validate_context(pHddCtx);
8999
9000 if (0 != status)
Sameer Thalappil75ea31a2013-02-21 19:38:16 -08009001 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309002 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9003 "%s: HDD context is not valid", __func__);
9004 return status;
Sameer Thalappil75ea31a2013-02-21 19:38:16 -08009005 }
9006
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009007
9008 if( FALSE == pHddCtx->cfg_ini->fEnableTDLSSupport ||
Hoonki Lee1090c6a2013-01-16 17:40:54 -08009009 FALSE == sme_IsFeatureSupportedByFW(TDLS))
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009010 {
Hoonki Lee1090c6a2013-01-16 17:40:54 -08009011 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chilam Ngc4244af2013-04-01 15:37:32 -07009012 "TDLS Disabled in INI OR not enabled in FW. "
9013 "Cannot process TDLS commands");
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009014 return -ENOTSUPP;
9015 }
9016
9017 switch (oper) {
9018 case NL80211_TDLS_ENABLE_LINK:
9019 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009020 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309021 long ret;
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05309022 tCsrTdlsLinkEstablishParams tdlsLinkEstablishParams;
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009023
Sunil Dutt41de4e22013-11-14 18:09:02 +05309024 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
9025
9026 if ( NULL == pTdlsPeer ) {
9027 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
9028 " (oper %d) not exsting. ignored",
9029 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
9030 return -EINVAL;
9031 }
9032
9033 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9034 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
9035 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
9036 "NL80211_TDLS_ENABLE_LINK");
9037
Gopichand Nakkala2f4a2822013-04-17 11:22:01 -07009038 if (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
9039 {
9040 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Staion Index %u "
9041 MAC_ADDRESS_STR " failed",
9042 __func__, pTdlsPeer->staId, MAC_ADDR_ARRAY(peer));
9043 return -EINVAL;
9044 }
9045
Hoonki Lee5305c3a2013-04-29 23:28:59 -07009046 if (eTDLS_LINK_CONNECTED != pTdlsPeer->link_status)
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07009047 {
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +05309048 if (IS_ADVANCE_TDLS_ENABLE) {
Gopichand Nakkala24be5312013-07-02 16:47:12 +05309049
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +05309050 if (0 != wlan_hdd_tdls_get_link_establish_params(
9051 pAdapter, peer,&tdlsLinkEstablishParams)) {
9052 return -EINVAL;
9053 }
9054 INIT_COMPLETION(pAdapter->tdls_link_establish_req_comp);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05309055
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +05309056 sme_SendTdlsLinkEstablishParams(WLAN_HDD_GET_HAL_CTX(pAdapter),
9057 pAdapter->sessionId, peer, &tdlsLinkEstablishParams);
9058 /* Send TDLS peer UAPSD capabilities to the firmware and
9059 * register with the TL on after the response for this operation
9060 * is received .
9061 */
9062 ret = wait_for_completion_interruptible_timeout(
9063 &pAdapter->tdls_link_establish_req_comp,
9064 msecs_to_jiffies(WAIT_TIME_TDLS_LINK_ESTABLISH_REQ));
9065 if (ret <= 0)
9066 {
9067 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9068 "%s: Link Establish Request Faled Status %ld",
9069 __func__, ret);
9070 return -EINVAL;
9071 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05309072 }
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -07009073 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer, eTDLS_LINK_CONNECTED);
Gopichand Nakkala471708b2013-06-04 20:03:01 +05309074 /* Mark TDLS client Authenticated .*/
9075 status = WLANTL_ChangeSTAState( pHddCtx->pvosContext,
9076 pTdlsPeer->staId,
9077 WLANTL_STA_AUTHENTICATED);
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -07009078 if (VOS_STATUS_SUCCESS == status)
9079 {
Hoonki Lee14621352013-04-16 17:51:19 -07009080 if (pTdlsPeer->is_responder == 0)
9081 {
9082 v_U8_t staId = (v_U8_t)pTdlsPeer->staId;
9083
9084 wlan_hdd_tdls_timer_restart(pAdapter,
9085 &pTdlsPeer->initiatorWaitTimeoutTimer,
9086 WAIT_TIME_TDLS_INITIATOR);
9087 /* suspend initiator TX until it receives direct packet from the
9088 reponder or WAIT_TIME_TDLS_INITIATOR timer expires */
9089 WLANTL_SuspendDataTx( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
9090 &staId, NULL);
9091 }
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -07009092 wlan_hdd_tdls_increment_peer_count(pAdapter);
9093 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07009094 wlan_hdd_tdls_check_bmps(pAdapter);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05309095
9096 /* Update TL about the UAPSD masks , to route the packets to firmware */
Gopichand Nakkala574f6d12013-06-27 19:38:43 +05309097 if ((TRUE == pHddCtx->cfg_ini->fEnableTDLSBufferSta)
9098 || pHddCtx->cfg_ini->fTDLSUapsdMask )
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05309099 {
Gopichand Nakkala574f6d12013-06-27 19:38:43 +05309100 int ac;
9101 uint8 ucAc[4] = { WLANTL_AC_VO,
9102 WLANTL_AC_VI,
9103 WLANTL_AC_BK,
9104 WLANTL_AC_BE };
9105 uint8 tlTid[4] = { 7, 5, 2, 3 } ;
9106 for(ac=0; ac < 4; ac++)
9107 {
9108 status = WLANTL_EnableUAPSDForAC( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
9109 pTdlsPeer->staId, ucAc[ac],
9110 tlTid[ac], tlTid[ac], 0, 0,
9111 WLANTL_BI_DIR );
9112 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05309113 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07009114 }
9115
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009116 }
9117 break;
9118 case NL80211_TDLS_DISABLE_LINK:
Lee Hoonkic1262f22013-01-24 21:59:00 -08009119 {
Sunil Dutt41de4e22013-11-14 18:09:02 +05309120 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
9121
9122 if ( NULL == pTdlsPeer ) {
9123 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
9124 " (oper %d) not exsting. ignored",
9125 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
9126 return -EINVAL;
9127 }
9128
9129 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9130 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
9131 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
9132 "NL80211_TDLS_DISABLE_LINK");
9133
Hoonki Lee5305c3a2013-04-29 23:28:59 -07009134 if(TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
Lee Hoonkic1262f22013-01-24 21:59:00 -08009135 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009136 long status;
9137
9138 INIT_COMPLETION(pAdapter->tdls_del_station_comp);
9139
Lee Hoonkic1262f22013-01-24 21:59:00 -08009140 sme_DeleteTdlsPeerSta( WLAN_HDD_GET_HAL_CTX(pAdapter),
9141 pAdapter->sessionId, peer );
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009142
9143 status = wait_for_completion_interruptible_timeout(&pAdapter->tdls_del_station_comp,
9144 msecs_to_jiffies(WAIT_TIME_TDLS_DEL_STA));
9145 if (status <= 0)
9146 {
Hoonki Lee5305c3a2013-04-29 23:28:59 -07009147 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer, eTDLS_LINK_IDLE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009148 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9149 "%s: Del station failed status %ld",
9150 __func__, status);
9151 return -EPERM;
9152 }
Hoonki Lee5305c3a2013-04-29 23:28:59 -07009153 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer, eTDLS_LINK_IDLE);
Lee Hoonkic1262f22013-01-24 21:59:00 -08009154 }
9155 else
9156 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07009157 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9158 "%s: TDLS Peer Station doesn't exist.", __func__);
Lee Hoonkic1262f22013-01-24 21:59:00 -08009159 }
Lee Hoonkic1262f22013-01-24 21:59:00 -08009160 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07009161 break;
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009162 case NL80211_TDLS_TEARDOWN:
Sunil Dutt41de4e22013-11-14 18:09:02 +05309163 {
9164 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9165 " %s : NL80211_TDLS_TEARDOWN for " MAC_ADDRESS_STR,
9166 __func__, MAC_ADDR_ARRAY(peer));
9167
9168 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
9169 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
9170
9171 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9172 " %s TDLS External control and Implicit Trigger not enabled ",
9173 __func__);
9174 return -ENOTSUPP;
9175 }
9176
Sunil Dutt41de4e22013-11-14 18:09:02 +05309177
9178 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
9179
9180 if ( NULL == pTdlsPeer ) {
9181 hddLog(VOS_TRACE_LEVEL_INFO, "%s: " MAC_ADDRESS_STR
9182 " peer not exsting",
9183 __func__, MAC_ADDR_ARRAY(peer));
Naresh Jayaram937abdf2013-11-26 19:50:25 +05309184 return -EINVAL;
Sunil Dutt41de4e22013-11-14 18:09:02 +05309185 }
9186 else {
9187 wlan_hdd_tdls_indicate_teardown(pAdapter, pTdlsPeer,
9188 eSIR_MAC_TDLS_TEARDOWN_UNSPEC_REASON);
9189 }
Naresh Jayaram937abdf2013-11-26 19:50:25 +05309190
9191 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, FALSE) )
9192 return -EINVAL;
Sunil Dutt41de4e22013-11-14 18:09:02 +05309193 break;
9194 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009195 case NL80211_TDLS_SETUP:
Sunil Dutt41de4e22013-11-14 18:09:02 +05309196 {
Naresh Jayaramdb4514b2013-11-25 18:08:10 +05309197 hddTdlsPeer_t *pTdlsPeer;
Sunil Dutt41de4e22013-11-14 18:09:02 +05309198 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9199 " %s : NL80211_TDLS_SETUP for " MAC_ADDRESS_STR,
9200 __func__, MAC_ADDR_ARRAY(peer));
9201
9202 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
9203 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
9204
9205 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9206 " %s TDLS External control and Implicit Trigger not enabled ",
9207 __func__);
9208 return -ENOTSUPP;
9209 }
9210
Naresh Jayaramdb4514b2013-11-25 18:08:10 +05309211 /* To cater the requirement of establishing the TDLS link
9212 * irrespective of the data traffic , get an entry of TDLS peer.
9213 */
9214 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, peer);
9215 if (pTdlsPeer == NULL) {
9216 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9217 "%s: peer " MAC_ADDRESS_STR " not existing",
9218 __func__, MAC_ADDR_ARRAY(peer));
9219 return -EINVAL;
9220 }
Naresh Jayaram937abdf2013-11-26 19:50:25 +05309221
9222 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, TRUE) ) {
9223
9224 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9225 " %s TDLS Add Force Peer Failed",
9226 __func__);
9227 return -EINVAL;
9228 }
Naresh Jayaramdb4514b2013-11-25 18:08:10 +05309229 break;
Sunil Dutt41de4e22013-11-14 18:09:02 +05309230 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009231 case NL80211_TDLS_DISCOVERY_REQ:
9232 /* We don't support in-driver setup/teardown/discovery */
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309233 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
9234 "%s: We don't support in-driver setup/teardown/discovery "
9235 ,__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009236 return -ENOTSUPP;
9237 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309238 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9239 "%s: unsupported event",__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009240 return -ENOTSUPP;
9241 }
9242 return 0;
9243}
Chilam NG571c65a2013-01-19 12:27:36 +05309244
9245int wlan_hdd_cfg80211_send_tdls_discover_req(struct wiphy *wiphy,
9246 struct net_device *dev, u8 *peer)
9247{
Arif Hussaina7c8e412013-11-20 11:06:42 -08009248 hddLog(VOS_TRACE_LEVEL_INFO,
9249 "tdls send discover req: "MAC_ADDRESS_STR,
9250 MAC_ADDR_ARRAY(peer));
Chilam NG571c65a2013-01-19 12:27:36 +05309251
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +05309252#if TDLS_MGMT_VERSION2
9253 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
9254 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
9255#else
Chilam NG571c65a2013-01-19 12:27:36 +05309256 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
9257 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, NULL, 0);
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +05309258#endif
Chilam NG571c65a2013-01-19 12:27:36 +05309259}
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009260#endif
9261
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309262#ifdef WLAN_FEATURE_GTK_OFFLOAD
9263/*
9264 * FUNCTION: wlan_hdd_cfg80211_update_replayCounterCallback
9265 * Callback rountine called upon receiving response for
9266 * get offload info
9267 */
9268void wlan_hdd_cfg80211_update_replayCounterCallback(void *callbackContext,
9269 tpSirGtkOffloadGetInfoRspParams pGtkOffloadGetInfoRsp)
9270{
9271
9272 hdd_adapter_t *pAdapter = (hdd_adapter_t *)callbackContext;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05309273 tANI_U8 tempReplayCounter[8];
9274 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309275
9276 ENTER();
9277
9278 if (NULL == pAdapter)
9279 {
Agarwal Ashish971c2882013-10-30 20:11:12 +05309280 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309281 "%s: HDD adapter is Null", __func__);
9282 return ;
9283 }
9284
9285 if (NULL == pGtkOffloadGetInfoRsp)
9286 {
9287 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9288 "%s: pGtkOffloadGetInfoRsp is Null", __func__);
9289 return ;
9290 }
9291
9292 if (VOS_STATUS_SUCCESS != pGtkOffloadGetInfoRsp->ulStatus)
9293 {
9294 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9295 "%s: wlan Failed to get replay counter value",
9296 __func__);
9297 return ;
9298 }
9299
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05309300 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9301 /* Update replay counter */
9302 pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter =
9303 pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
9304
9305 {
9306 /* changing from little to big endian since supplicant
9307 * works on big endian format
9308 */
9309 int i;
9310 tANI_U8 *p = (tANI_U8 *)&pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
9311
9312 for (i = 0; i < 8; i++)
9313 {
9314 tempReplayCounter[7-i] = (tANI_U8)p[i];
9315 }
9316 }
9317
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309318 /* Update replay counter to NL */
9319 cfg80211_gtk_rekey_notify(pAdapter->dev, pGtkOffloadGetInfoRsp->bssId,
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05309320 tempReplayCounter, GFP_KERNEL);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309321}
9322
9323/*
9324 * FUNCTION: wlan_hdd_cfg80211_set_rekey_data
9325 * This function is used to offload GTK rekeying job to the firmware.
9326 */
9327int wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
9328 struct cfg80211_gtk_rekey_data *data)
9329{
9330 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
9331 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
9332 hdd_station_ctx_t *pHddStaCtx;
9333 tHalHandle hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309334 int result;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05309335 tSirGtkOffloadParams hddGtkOffloadReqParams;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309336 eHalStatus status = eHAL_STATUS_FAILURE;
9337
9338 ENTER();
9339
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309340
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309341 if (NULL == pAdapter)
9342 {
9343 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
9344 "%s: HDD adapter is Null", __func__);
9345 return -ENODEV;
9346 }
9347
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309348 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
9349 TRACE_CODE_HDD_CFG80211_SET_REKEY_DATA,
9350 pAdapter->sessionId, pAdapter->device_mode));
9351
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309352 result = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309353
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309354 if (0 != result)
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309355 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309356 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9357 "%s: HDD context is not valid", __func__);
9358 return result;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309359 }
9360
9361 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9362 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
9363 if (NULL == hHal)
9364 {
9365 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9366 "%s: HAL context is Null!!!", __func__);
9367 return -EAGAIN;
9368 }
9369
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05309370 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_ENABLE;
9371 memcpy(pHddStaCtx->gtkOffloadReqParams.aKCK, data->kck, NL80211_KCK_LEN);
9372 memcpy(pHddStaCtx->gtkOffloadReqParams.aKEK, data->kek, NL80211_KEK_LEN);
9373 memcpy(pHddStaCtx->gtkOffloadReqParams.bssId, &pHddStaCtx->conn_info.bssId,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309374 WNI_CFG_BSSID_LEN);
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05309375 {
9376 /* changing from big to little endian since driver
9377 * works on little endian format
9378 */
9379 tANI_U8 *p =
9380 (tANI_U8 *)&pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter;
9381 int i;
9382
9383 for (i = 0; i < 8; i++)
9384 {
9385 p[7-i] = data->replay_ctr[i];
9386 }
9387 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309388
9389 if (TRUE == pHddCtx->hdd_wlan_suspended)
9390 {
9391 /* if wlan is suspended, enable GTK offload directly from here */
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05309392 memcpy(&hddGtkOffloadReqParams, &pHddStaCtx->gtkOffloadReqParams,
9393 sizeof (tSirGtkOffloadParams));
9394 status = sme_SetGTKOffload(hHal, &hddGtkOffloadReqParams,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309395 pAdapter->sessionId);
9396
9397 if (eHAL_STATUS_SUCCESS != status)
9398 {
9399 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9400 "%s: sme_SetGTKOffload failed, returned %d",
9401 __func__, status);
9402 return status;
9403 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309404 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9405 "%s: sme_SetGTKOffload successfull", __func__);
9406 }
9407 else
9408 {
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309409 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9410 "%s: wlan not suspended GTKOffload request is stored",
9411 __func__);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309412 }
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05309413
9414 return eHAL_STATUS_SUCCESS;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309415}
9416#endif /*WLAN_FEATURE_GTK_OFFLOAD*/
9417
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05309418/*
9419 * FUNCTION: wlan_hdd_cfg80211_set_mac_acl
9420 * This function is used to set access control policy
9421 */
9422static int wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy,
9423 struct net_device *dev, const struct cfg80211_acl_data *params)
9424{
9425 int i;
9426 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
9427 hdd_hostapd_state_t *pHostapdState;
9428 tsap_Config_t *pConfig;
9429 v_CONTEXT_t pVosContext = NULL;
9430 hdd_context_t *pHddCtx;
9431 int status;
9432
9433 ENTER();
9434
9435 if (NULL == pAdapter)
9436 {
9437 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
9438 "%s: HDD adapter is Null", __func__);
9439 return -ENODEV;
9440 }
9441
9442 if (NULL == params)
9443 {
9444 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
9445 "%s: params is Null", __func__);
9446 return -EINVAL;
9447 }
9448
9449 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9450 status = wlan_hdd_validate_context(pHddCtx);
9451
9452 if (0 != status)
9453 {
9454 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9455 "%s: HDD context is not valid", __func__);
9456 return status;
9457 }
9458
9459 pVosContext = pHddCtx->pvosContext;
9460 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
9461
9462 if (NULL == pHostapdState)
9463 {
9464 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
9465 "%s: pHostapdState is Null", __func__);
9466 return -EINVAL;
9467 }
9468
9469 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"acl policy: = %d"
9470 "no acl entries = %d", params->acl_policy, params->n_acl_entries);
9471
9472 if (WLAN_HDD_SOFTAP == pAdapter->device_mode)
9473 {
9474 pConfig = &pAdapter->sessionCtx.ap.sapConfig;
9475
9476 /* default value */
9477 pConfig->num_accept_mac = 0;
9478 pConfig->num_deny_mac = 0;
9479
9480 /**
9481 * access control policy
9482 * @NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED: Deny stations which are
9483 * listed in hostapd.deny file.
9484 * @NL80211_ACL_POLICY_DENY_UNLESS_LISTED: Allow stations which are
9485 * listed in hostapd.accept file.
9486 */
9487 if (NL80211_ACL_POLICY_DENY_UNLESS_LISTED == params->acl_policy)
9488 {
9489 pConfig->SapMacaddr_acl = eSAP_DENY_UNLESS_ACCEPTED;
9490 }
9491 else if (NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED == params->acl_policy)
9492 {
9493 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
9494 }
9495 else
9496 {
9497 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9498 "%s:Acl Policy : %d is not supported",
9499 __func__, params->acl_policy);
9500 return -ENOTSUPP;
9501 }
9502
9503 if (eSAP_DENY_UNLESS_ACCEPTED == pConfig->SapMacaddr_acl)
9504 {
9505 pConfig->num_accept_mac = params->n_acl_entries;
9506 for (i = 0; i < params->n_acl_entries; i++)
9507 {
9508 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9509 "** Add ACL MAC entry %i in WhiletList :"
9510 MAC_ADDRESS_STR, i,
9511 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
9512
9513 vos_mem_copy(&pConfig->accept_mac[i], params->mac_addrs[i].addr,
9514 sizeof(qcmacaddr));
9515 }
9516 }
9517 else if (eSAP_ACCEPT_UNLESS_DENIED == pConfig->SapMacaddr_acl)
9518 {
9519 pConfig->num_deny_mac = params->n_acl_entries;
9520 for (i = 0; i < params->n_acl_entries; i++)
9521 {
9522 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9523 "** Add ACL MAC entry %i in BlackList :"
9524 MAC_ADDRESS_STR, i,
9525 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
9526
9527 vos_mem_copy(&pConfig->deny_mac[i], params->mac_addrs[i].addr,
9528 sizeof(qcmacaddr));
9529 }
9530 }
9531
9532 if (VOS_STATUS_SUCCESS != WLANSAP_SetMacACL(pVosContext, pConfig))
9533 {
9534 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9535 "%s: SAP Set Mac Acl fail", __func__);
9536 return -EINVAL;
9537 }
9538 }
9539 else
9540 {
9541 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9542 "%s: Invalid device_mode = %d",
9543 __func__, pAdapter->device_mode);
9544 return -EINVAL;
9545 }
9546
9547 return 0;
9548}
9549
Leo Chang9056f462013-08-01 19:21:11 -07009550#ifdef WLAN_NL80211_TESTMODE
9551#ifdef FEATURE_WLAN_LPHB
Leo Changd9df8aa2013-09-26 13:32:26 -07009552void wlan_hdd_cfg80211_lphb_ind_handler
Leo Chang9056f462013-08-01 19:21:11 -07009553(
9554 void *pAdapter,
9555 void *indCont
9556)
9557{
Leo Changd9df8aa2013-09-26 13:32:26 -07009558 tSirLPHBInd *lphbInd;
9559 struct sk_buff *skb;
Leo Chang9056f462013-08-01 19:21:11 -07009560
9561 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -07009562 "LPHB indication arrived");
Leo Chang9056f462013-08-01 19:21:11 -07009563
9564 if (NULL == indCont)
9565 {
9566 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -07009567 "LPHB IND, invalid argument");
Leo Chang9056f462013-08-01 19:21:11 -07009568 return;
9569 }
9570
Leo Changd9df8aa2013-09-26 13:32:26 -07009571 lphbInd = (tSirLPHBInd *)indCont;
Leo Chang9056f462013-08-01 19:21:11 -07009572 skb = cfg80211_testmode_alloc_event_skb(
9573 ((hdd_adapter_t *)pAdapter)->wdev.wiphy,
Leo Changd9df8aa2013-09-26 13:32:26 -07009574 sizeof(tSirLPHBInd),
Leo Chang9056f462013-08-01 19:21:11 -07009575 GFP_ATOMIC);
9576 if (!skb)
9577 {
9578 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9579 "LPHB timeout, NL buffer alloc fail");
9580 return;
9581 }
9582
Leo Changac3ba772013-10-07 09:47:04 -07009583 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_CMD, WLAN_HDD_TM_CMD_WLAN_HB))
Leo Changd9df8aa2013-09-26 13:32:26 -07009584 {
9585 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9586 "WLAN_HDD_TM_ATTR_CMD put fail");
9587 goto nla_put_failure;
9588 }
Leo Changac3ba772013-10-07 09:47:04 -07009589 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_TYPE, lphbInd->protocolType))
Leo Changd9df8aa2013-09-26 13:32:26 -07009590 {
9591 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9592 "WLAN_HDD_TM_ATTR_TYPE put fail");
9593 goto nla_put_failure;
9594 }
Leo Changac3ba772013-10-07 09:47:04 -07009595 if(nla_put(skb, WLAN_HDD_TM_ATTR_DATA,
Leo Changd9df8aa2013-09-26 13:32:26 -07009596 sizeof(tSirLPHBInd), lphbInd))
9597 {
9598 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9599 "WLAN_HDD_TM_ATTR_DATA put fail");
9600 goto nla_put_failure;
9601 }
Leo Chang9056f462013-08-01 19:21:11 -07009602 cfg80211_testmode_event(skb, GFP_ATOMIC);
9603 return;
9604
9605nla_put_failure:
9606 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9607 "NLA Put fail");
9608 kfree_skb(skb);
9609
9610 return;
9611}
9612#endif /* FEATURE_WLAN_LPHB */
9613
9614static int wlan_hdd_cfg80211_testmode(struct wiphy *wiphy, void *data, int len)
9615{
9616 struct nlattr *tb[WLAN_HDD_TM_ATTR_MAX + 1];
9617 int err = 0;
9618#ifdef FEATURE_WLAN_LPHB
9619 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Leo Changd9df8aa2013-09-26 13:32:26 -07009620 eHalStatus smeStatus;
Leo Chang9056f462013-08-01 19:21:11 -07009621#endif /* FEATURE_WLAN_LPHB */
9622
9623 err = nla_parse(tb, WLAN_HDD_TM_ATTR_MAX, data, len, wlan_hdd_tm_policy);
9624 if (err)
9625 {
9626 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9627 "%s Testmode INV ATTR", __func__);
9628 return err;
9629 }
9630
9631 if (!tb[WLAN_HDD_TM_ATTR_CMD])
9632 {
9633 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9634 "%s Testmode INV CMD", __func__);
9635 return -EINVAL;
9636 }
9637
9638 switch (nla_get_u32(tb[WLAN_HDD_TM_ATTR_CMD]))
9639 {
9640#ifdef FEATURE_WLAN_LPHB
9641 /* Low Power Heartbeat configuration request */
9642 case WLAN_HDD_TM_CMD_WLAN_HB:
9643 {
9644 int buf_len;
9645 void *buf;
9646 tSirLPHBReq *hb_params = NULL;
Amar Singhal05852702014-02-04 14:40:00 -08009647 tSirLPHBReq *hb_params_temp = NULL;
Leo Chang9056f462013-08-01 19:21:11 -07009648
9649 if (!tb[WLAN_HDD_TM_ATTR_DATA])
9650 {
9651 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9652 "%s Testmode INV DATA", __func__);
9653 return -EINVAL;
9654 }
9655
9656 buf = nla_data(tb[WLAN_HDD_TM_ATTR_DATA]);
9657 buf_len = nla_len(tb[WLAN_HDD_TM_ATTR_DATA]);
Amar Singhal05852702014-02-04 14:40:00 -08009658
9659 hb_params_temp =(tSirLPHBReq *)buf;
9660 if ((hb_params_temp->cmd == LPHB_SET_TCP_PARAMS_INDID) &&
9661 (hb_params_temp->params.lphbTcpParamReq.timePeriodSec == 0))
9662 return -EINVAL;
9663
Leo Chang9056f462013-08-01 19:21:11 -07009664 hb_params = (tSirLPHBReq *)vos_mem_malloc(sizeof(tSirLPHBReq));
9665 if (NULL == hb_params)
9666 {
9667 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9668 "%s Request Buffer Alloc Fail", __func__);
9669 return -EINVAL;
9670 }
9671
9672 vos_mem_copy(hb_params, buf, buf_len);
Leo Changd9df8aa2013-09-26 13:32:26 -07009673 smeStatus = sme_LPHBConfigReq((tHalHandle)(pHddCtx->hHal),
9674 hb_params,
9675 wlan_hdd_cfg80211_lphb_ind_handler);
9676 if (eHAL_STATUS_SUCCESS != smeStatus)
Leo Chang9056f462013-08-01 19:21:11 -07009677 {
Leo Changd9df8aa2013-09-26 13:32:26 -07009678 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9679 "LPHB Config Fail, disable");
Leo Chang9056f462013-08-01 19:21:11 -07009680 vos_mem_free(hb_params);
9681 }
Leo Chang9056f462013-08-01 19:21:11 -07009682 return 0;
9683 }
9684#endif /* FEATURE_WLAN_LPHB */
9685 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309686 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9687 "%s: unsupported event",__func__);
Leo Chang9056f462013-08-01 19:21:11 -07009688 return -EOPNOTSUPP;
9689 }
9690
9691 return err;
9692}
9693#endif /* CONFIG_NL80211_TESTMODE */
9694
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +05309695static int wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
9696 struct net_device *dev,
9697 int idx, struct survey_info *survey)
9698{
9699 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
9700 hdd_context_t *pHddCtx;
Mihir Sheted9072e02013-08-21 17:02:29 +05309701 hdd_station_ctx_t *pHddStaCtx;
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +05309702 tHalHandle halHandle;
Mihir Sheted9072e02013-08-21 17:02:29 +05309703 v_U32_t channel = 0, freq = 0; /* Initialization Required */
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +05309704 v_S7_t snr,rssi;
9705 int status, i, j, filled = 0;
9706
9707 ENTER();
9708
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +05309709 if (NULL == pAdapter)
9710 {
9711 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
9712 "%s: HDD adapter is Null", __func__);
9713 return -ENODEV;
9714 }
9715
9716 if (NULL == wiphy)
9717 {
9718 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
9719 "%s: wiphy is Null", __func__);
9720 return -ENODEV;
9721 }
9722
9723 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9724 status = wlan_hdd_validate_context(pHddCtx);
9725
9726 if (0 != status)
9727 {
9728 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9729 "%s: HDD context is not valid", __func__);
9730 return status;
9731 }
9732
Mihir Sheted9072e02013-08-21 17:02:29 +05309733 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9734
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +05309735 if (0 == pHddCtx->cfg_ini->fEnableSNRMonitoring ||
Mihir Sheted9072e02013-08-21 17:02:29 +05309736 0 != pAdapter->survey_idx ||
9737 eConnectionState_Associated != pHddStaCtx->conn_info.connState)
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +05309738 {
9739 /* The survey dump ops when implemented completely is expected to
9740 * return a survey of all channels and the ops is called by the
9741 * kernel with incremental values of the argument 'idx' till it
9742 * returns -ENONET. But we can only support the survey for the
9743 * operating channel for now. survey_idx is used to track
9744 * that the ops is called only once and then return -ENONET for
9745 * the next iteration
9746 */
9747 pAdapter->survey_idx = 0;
9748 return -ENONET;
9749 }
9750
9751 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
9752
9753 wlan_hdd_get_snr(pAdapter, &snr);
9754 wlan_hdd_get_rssi(pAdapter, &rssi);
9755
9756 sme_GetOperationChannel(halHandle, &channel, pAdapter->sessionId);
9757 hdd_wlan_get_freq(channel, &freq);
9758
9759
9760 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
9761 {
9762 if (NULL == wiphy->bands[i])
9763 {
9764 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
9765 "%s: wiphy->bands[i] is NULL, i = %d", __func__, i);
9766 continue;
9767 }
9768
9769 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
9770 {
9771 struct ieee80211_supported_band *band = wiphy->bands[i];
9772
9773 if (band->channels[j].center_freq == (v_U16_t)freq)
9774 {
9775 survey->channel = &band->channels[j];
9776 /* The Rx BDs contain SNR values in dB for the received frames
9777 * while the supplicant expects noise. So we calculate and
9778 * return the value of noise (dBm)
9779 * SNR (dB) = RSSI (dBm) - NOISE (dBm)
9780 */
9781 survey->noise = rssi - snr;
9782 survey->filled = SURVEY_INFO_NOISE_DBM;
9783 filled = 1;
9784 }
9785 }
9786 }
9787
9788 if (filled)
9789 pAdapter->survey_idx = 1;
9790 else
9791 {
9792 pAdapter->survey_idx = 0;
9793 return -ENONET;
9794 }
9795
9796 return 0;
9797}
9798
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05309799/*
9800 * FUNCTION: wlan_hdd_cfg80211_resume_wlan
9801 * this is called when cfg80211 driver resume
9802 * driver updates latest sched_scan scan result(if any) to cfg80211 database
9803 */
9804int wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
9805{
9806 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
9807 hdd_adapter_t *pAdapter;
9808 hdd_adapter_list_node_t *pAdapterNode, *pNext;
9809 VOS_STATUS status = VOS_STATUS_SUCCESS;
9810
9811 ENTER();
9812
9813 if ( NULL == pHddCtx )
9814 {
9815 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
9816 "%s: HddCtx validation failed", __func__);
9817 return 0;
9818 }
9819
9820 if (pHddCtx->isLogpInProgress)
9821 {
9822 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9823 "%s: LOGP in Progress. Ignore!!!", __func__);
9824 return 0;
9825 }
9826
Mihir Shete18156292014-03-11 15:38:30 +05309827 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05309828 {
9829 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9830 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
9831 return 0;
9832 }
9833
9834 spin_lock(&pHddCtx->schedScan_lock);
9835 pHddCtx->isWiphySuspended = FALSE;
9836 if (TRUE != pHddCtx->isSchedScanUpdatePending)
9837 {
9838 spin_unlock(&pHddCtx->schedScan_lock);
9839 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9840 "%s: Return resume is not due to PNO indication", __func__);
9841 return 0;
9842 }
9843 // Reset flag to avoid updatating cfg80211 data old results again
9844 pHddCtx->isSchedScanUpdatePending = FALSE;
9845 spin_unlock(&pHddCtx->schedScan_lock);
9846
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +05309847
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05309848 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
9849
9850 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
9851 {
9852 pAdapter = pAdapterNode->pAdapter;
9853 if ( (NULL != pAdapter) &&
9854 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) )
9855 {
9856 if (0 != wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter))
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +05309857 {
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05309858 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
9859 "%s: NO SCAN result", __func__);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +05309860 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05309861 else
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +05309862 {
9863 /* Acquire wakelock to handle the case where APP's tries to
9864 * suspend immediately after updating the scan results. Whis
9865 * results in app's is in suspended state and not able to
9866 * process the connect request to AP
9867 */
9868 hdd_prevent_suspend_timeout(2000);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05309869 cfg80211_sched_scan_results(pHddCtx->wiphy);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +05309870 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05309871
9872 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9873 "%s : cfg80211 scan result database updated", __func__);
9874
9875 return 0;
9876
9877 }
9878 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
9879 pAdapterNode = pNext;
9880 }
9881
9882 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9883 "%s: Failed to find Adapter", __func__);
9884 return 0;
9885}
9886
9887/*
9888 * FUNCTION: wlan_hdd_cfg80211_suspend_wlan
9889 * this is called when cfg80211 driver suspends
9890 */
9891int wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
9892 struct cfg80211_wowlan *wow)
9893{
9894 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
9895
9896 ENTER();
9897 if (NULL == pHddCtx)
9898 {
9899 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
9900 "%s: HddCtx validation failed", __func__);
9901 return 0;
9902 }
9903
9904 pHddCtx->isWiphySuspended = TRUE;
9905
9906 EXIT();
9907
9908 return 0;
9909}
9910
Jeff Johnson295189b2012-06-20 16:38:30 -07009911/* cfg80211_ops */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309912static struct cfg80211_ops wlan_hdd_cfg80211_ops =
Jeff Johnson295189b2012-06-20 16:38:30 -07009913{
9914 .add_virtual_intf = wlan_hdd_add_virtual_intf,
9915 .del_virtual_intf = wlan_hdd_del_virtual_intf,
9916 .change_virtual_intf = wlan_hdd_cfg80211_change_iface,
9917 .change_station = wlan_hdd_change_station,
9918#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
9919 .add_beacon = wlan_hdd_cfg80211_add_beacon,
9920 .del_beacon = wlan_hdd_cfg80211_del_beacon,
9921 .set_beacon = wlan_hdd_cfg80211_set_beacon,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009922#else
9923 .start_ap = wlan_hdd_cfg80211_start_ap,
9924 .change_beacon = wlan_hdd_cfg80211_change_beacon,
9925 .stop_ap = wlan_hdd_cfg80211_stop_ap,
Jeff Johnson295189b2012-06-20 16:38:30 -07009926#endif
9927 .change_bss = wlan_hdd_cfg80211_change_bss,
9928 .add_key = wlan_hdd_cfg80211_add_key,
9929 .get_key = wlan_hdd_cfg80211_get_key,
9930 .del_key = wlan_hdd_cfg80211_del_key,
9931 .set_default_key = wlan_hdd_cfg80211_set_default_key,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -08009932#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07009933 .set_channel = wlan_hdd_cfg80211_set_channel,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -08009934#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009935 .scan = wlan_hdd_cfg80211_scan,
9936 .connect = wlan_hdd_cfg80211_connect,
9937 .disconnect = wlan_hdd_cfg80211_disconnect,
9938 .join_ibss = wlan_hdd_cfg80211_join_ibss,
9939 .leave_ibss = wlan_hdd_cfg80211_leave_ibss,
9940 .set_wiphy_params = wlan_hdd_cfg80211_set_wiphy_params,
9941 .set_tx_power = wlan_hdd_cfg80211_set_txpower,
9942 .get_tx_power = wlan_hdd_cfg80211_get_txpower,
Jeff Johnson295189b2012-06-20 16:38:30 -07009943 .remain_on_channel = wlan_hdd_cfg80211_remain_on_channel,
9944 .cancel_remain_on_channel = wlan_hdd_cfg80211_cancel_remain_on_channel,
DARAM SUDHA39eede62014-02-12 11:16:40 +05309945 .mgmt_tx = wlan_hdd_mgmt_tx,
Jeff Johnson295189b2012-06-20 16:38:30 -07009946#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
9947 .mgmt_tx_cancel_wait = wlan_hdd_cfg80211_mgmt_tx_cancel_wait,
9948 .set_default_mgmt_key = wlan_hdd_set_default_mgmt_key,
9949 .set_txq_params = wlan_hdd_set_txq_params,
9950#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009951 .get_station = wlan_hdd_cfg80211_get_station,
9952 .set_power_mgmt = wlan_hdd_cfg80211_set_power_mgmt,
9953 .del_station = wlan_hdd_cfg80211_del_station,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009954 .add_station = wlan_hdd_cfg80211_add_station,
9955#ifdef FEATURE_WLAN_LFR
9956 .set_pmksa = wlan_hdd_cfg80211_set_pmksa,
9957 .del_pmksa = wlan_hdd_cfg80211_del_pmksa,
9958 .flush_pmksa = wlan_hdd_cfg80211_flush_pmksa,
9959#endif
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07009960#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
9961 .update_ft_ies = wlan_hdd_cfg80211_update_ft_ies,
9962#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009963#ifdef FEATURE_WLAN_TDLS
9964 .tdls_mgmt = wlan_hdd_cfg80211_tdls_mgmt,
9965 .tdls_oper = wlan_hdd_cfg80211_tdls_oper,
9966#endif
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309967#ifdef WLAN_FEATURE_GTK_OFFLOAD
9968 .set_rekey_data = wlan_hdd_cfg80211_set_rekey_data,
9969#endif /* WLAN_FEATURE_GTK_OFFLOAD */
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05309970#ifdef FEATURE_WLAN_SCAN_PNO
9971 .sched_scan_start = wlan_hdd_cfg80211_sched_scan_start,
9972 .sched_scan_stop = wlan_hdd_cfg80211_sched_scan_stop,
9973#endif /*FEATURE_WLAN_SCAN_PNO */
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05309974 .resume = wlan_hdd_cfg80211_resume_wlan,
9975 .suspend = wlan_hdd_cfg80211_suspend_wlan,
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05309976 .set_mac_acl = wlan_hdd_cfg80211_set_mac_acl,
Leo Chang9056f462013-08-01 19:21:11 -07009977#ifdef WLAN_NL80211_TESTMODE
9978 .testmode_cmd = wlan_hdd_cfg80211_testmode,
9979#endif
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +05309980 .dump_survey = wlan_hdd_cfg80211_dump_survey,
Jeff Johnson295189b2012-06-20 16:38:30 -07009981};
9982