blob: 7db1f9525344e34865bf8d5b8bb455eaf184419e [file] [log] [blame]
Jeff Johnson295189b2012-06-20 16:38:30 -07001/*
Kiet Lam842dad02014-02-18 18:44:02 -08002 * Copyright (c) 2012-2014 The Linux Foundation. All rights reserved.
3 *
4 * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
5 *
6 *
7 * Permission to use, copy, modify, and/or distribute this software for
8 * any purpose with or without fee is hereby granted, provided that the
9 * above copyright notice and this permission notice appear in all
10 * copies.
11 *
12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
13 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
14 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
15 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
16 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
17 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
18 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
19 * PERFORMANCE OF THIS SOFTWARE.
20 */
21
22/*
Kiet Lamaa8e15a2014-02-11 23:30:06 -080023 * Copyright (c) 2012-2014 Qualcomm Atheros, Inc.
24 * All Rights Reserved.
25 * Qualcomm Atheros Confidential and Proprietary.
Kiet Lam842dad02014-02-18 18:44:02 -080026 *
Kiet Lamaa8e15a2014-02-11 23:30:06 -080027 */
Kiet Lam842dad02014-02-18 18:44:02 -080028
29
Jeff Johnson295189b2012-06-20 16:38:30 -070030/**========================================================================
31
32 \file wlan_hdd_cfg80211.c
33
34 \brief WLAN Host Device Driver implementation
35
Jeff Johnson295189b2012-06-20 16:38:30 -070036 ========================================================================*/
37
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070038/**=========================================================================
Jeff Johnson295189b2012-06-20 16:38:30 -070039
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070040 EDIT HISTORY FOR FILE
Jeff Johnson295189b2012-06-20 16:38:30 -070041
42
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070043 This section contains comments describing changes made to the module.
44 Notice that changes are listed in reverse chronological order.
Jeff Johnson295189b2012-06-20 16:38:30 -070045
46
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070047 $Header:$ $DateTime: $ $Author: $
Jeff Johnson295189b2012-06-20 16:38:30 -070048
49
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070050 when who what, where, why
Jeff Johnson295189b2012-06-20 16:38:30 -070051 -------- --- --------------------------------------------------------
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070052 21/12/09 Ashwani Created module.
Jeff Johnson295189b2012-06-20 16:38:30 -070053
54 07/06/10 Kumar Deepak Implemented cfg80211 callbacks for ANDROID
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070055 Ganesh K
Jeff Johnson295189b2012-06-20 16:38:30 -070056 ==========================================================================*/
57
Jeff Johnson295189b2012-06-20 16:38:30 -070058
59#include <linux/version.h>
60#include <linux/module.h>
61#include <linux/kernel.h>
62#include <linux/init.h>
63#include <linux/wireless.h>
64#include <wlan_hdd_includes.h>
65#include <net/arp.h>
66#include <net/cfg80211.h>
67#include <linux/wireless.h>
68#include <wlan_hdd_wowl.h>
69#include <aniGlobal.h>
70#include "ccmApi.h"
71#include "sirParams.h"
72#include "dot11f.h"
73#include "wlan_hdd_assoc.h"
74#include "wlan_hdd_wext.h"
75#include "sme_Api.h"
76#include "wlan_hdd_p2p.h"
77#include "wlan_hdd_cfg80211.h"
78#include "wlan_hdd_hostapd.h"
79#include "sapInternal.h"
80#include "wlan_hdd_softap_tx_rx.h"
81#include "wlan_hdd_main.h"
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053082#include "wlan_hdd_assoc.h"
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053083#include "wlan_hdd_power.h"
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053084#include "wlan_hdd_trace.h"
85#include "vos_types.h"
86#include "vos_trace.h"
Jeff Johnson295189b2012-06-20 16:38:30 -070087#ifdef WLAN_BTAMP_FEATURE
88#include "bap_hdd_misc.h"
89#endif
90#include <qc_sap_ioctl.h>
Mohit Khanna698ba2a2012-12-04 15:08:18 -080091#ifdef FEATURE_WLAN_TDLS
92#include "wlan_hdd_tdls.h"
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053093#include "wlan_hdd_wmm.h"
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053094#include "wlan_qct_wda.h"
Mohit Khanna698ba2a2012-12-04 15:08:18 -080095#endif
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +053096#include "wlan_nv.h"
Leo Chang6fe1f922013-06-07 19:21:24 -070097#include "wlan_hdd_dev_pwr.h"
Jeff Johnson295189b2012-06-20 16:38:30 -070098
99#define g_mode_rates_size (12)
100#define a_mode_rates_size (8)
101#define FREQ_BASE_80211G (2407)
102#define FREQ_BAND_DIFF_80211G (5)
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700103#define MAX_SCAN_SSID 9
Kiet Lamac06e2c2013-10-23 16:25:07 +0530104#define MAX_PENDING_LOG 5
Jeff Johnson295189b2012-06-20 16:38:30 -0700105#define GET_IE_LEN_IN_BSS_DESC(lenInBss) ( lenInBss + sizeof(lenInBss) - \
krunal soni2a6a9062014-02-11 14:14:23 -0800106 ((uintptr_t)OFFSET_OF( tSirBssDescription, ieFields)))
Jeff Johnson295189b2012-06-20 16:38:30 -0700107
108#define HDD2GHZCHAN(freq, chan, flag) { \
109 .band = IEEE80211_BAND_2GHZ, \
110 .center_freq = (freq), \
111 .hw_value = (chan),\
112 .flags = (flag), \
113 .max_antenna_gain = 0 ,\
114 .max_power = 30, \
115}
116
117#define HDD5GHZCHAN(freq, chan, flag) { \
118 .band = IEEE80211_BAND_5GHZ, \
119 .center_freq = (freq), \
120 .hw_value = (chan),\
121 .flags = (flag), \
122 .max_antenna_gain = 0 ,\
123 .max_power = 30, \
124}
125
126#define HDD_G_MODE_RATETAB(rate, rate_id, flag)\
127{\
128 .bitrate = rate, \
129 .hw_value = rate_id, \
130 .flags = flag, \
131}
132
Lee Hoonkic1262f22013-01-24 21:59:00 -0800133#ifndef WLAN_FEATURE_TDLS_DEBUG
134#define TDLS_LOG_LEVEL VOS_TRACE_LEVEL_INFO
135#else
136#define TDLS_LOG_LEVEL VOS_TRACE_LEVEL_ERROR
137#endif
138
Gopichand Nakkala356fb102013-03-06 12:34:04 +0530139#ifdef WLAN_FEATURE_VOWIFI_11R
140#define WLAN_AKM_SUITE_FT_8021X 0x000FAC03
141#define WLAN_AKM_SUITE_FT_PSK 0x000FAC04
142#endif
143
Naresh Jayaram3180aa42014-02-12 21:47:26 +0530144#define HDD_CHANNEL_14 14
145
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530146static const u32 hdd_cipher_suites[] =
Jeff Johnson295189b2012-06-20 16:38:30 -0700147{
148 WLAN_CIPHER_SUITE_WEP40,
149 WLAN_CIPHER_SUITE_WEP104,
150 WLAN_CIPHER_SUITE_TKIP,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800151#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -0700152#define WLAN_CIPHER_SUITE_KRK 0x004096ff /* use for KRK */
153 WLAN_CIPHER_SUITE_KRK,
154 WLAN_CIPHER_SUITE_CCMP,
155#else
156 WLAN_CIPHER_SUITE_CCMP,
157#endif
158#ifdef FEATURE_WLAN_WAPI
159 WLAN_CIPHER_SUITE_SMS4,
160#endif
Chet Lanctot186b5732013-03-18 10:26:30 -0700161#ifdef WLAN_FEATURE_11W
162 WLAN_CIPHER_SUITE_AES_CMAC,
163#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700164};
165
166static inline int is_broadcast_ether_addr(const u8 *addr)
167{
168 return ((addr[0] == 0xff) && (addr[1] == 0xff) && (addr[2] == 0xff) &&
169 (addr[3] == 0xff) && (addr[4] == 0xff) && (addr[5] == 0xff));
170}
171
172static struct ieee80211_channel hdd_channels_2_4_GHZ[] =
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530173{
Jeff Johnson295189b2012-06-20 16:38:30 -0700174 HDD2GHZCHAN(2412, 1, 0) ,
175 HDD2GHZCHAN(2417, 2, 0) ,
176 HDD2GHZCHAN(2422, 3, 0) ,
177 HDD2GHZCHAN(2427, 4, 0) ,
178 HDD2GHZCHAN(2432, 5, 0) ,
179 HDD2GHZCHAN(2437, 6, 0) ,
180 HDD2GHZCHAN(2442, 7, 0) ,
181 HDD2GHZCHAN(2447, 8, 0) ,
182 HDD2GHZCHAN(2452, 9, 0) ,
183 HDD2GHZCHAN(2457, 10, 0) ,
184 HDD2GHZCHAN(2462, 11, 0) ,
185 HDD2GHZCHAN(2467, 12, 0) ,
186 HDD2GHZCHAN(2472, 13, 0) ,
187 HDD2GHZCHAN(2484, 14, 0) ,
188};
189
Jeff Johnson295189b2012-06-20 16:38:30 -0700190static struct ieee80211_channel hdd_social_channels_2_4_GHZ[] =
191{
192 HDD2GHZCHAN(2412, 1, 0) ,
193 HDD2GHZCHAN(2437, 6, 0) ,
194 HDD2GHZCHAN(2462, 11, 0) ,
195};
Jeff Johnson295189b2012-06-20 16:38:30 -0700196
197static struct ieee80211_channel hdd_channels_5_GHZ[] =
198{
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -0700199 HDD5GHZCHAN(4920, 240, 0) ,
200 HDD5GHZCHAN(4940, 244, 0) ,
201 HDD5GHZCHAN(4960, 248, 0) ,
202 HDD5GHZCHAN(4980, 252, 0) ,
203 HDD5GHZCHAN(5040, 208, 0) ,
204 HDD5GHZCHAN(5060, 212, 0) ,
205 HDD5GHZCHAN(5080, 216, 0) ,
Jeff Johnson295189b2012-06-20 16:38:30 -0700206 HDD5GHZCHAN(5180, 36, 0) ,
207 HDD5GHZCHAN(5200, 40, 0) ,
208 HDD5GHZCHAN(5220, 44, 0) ,
209 HDD5GHZCHAN(5240, 48, 0) ,
210 HDD5GHZCHAN(5260, 52, 0) ,
211 HDD5GHZCHAN(5280, 56, 0) ,
212 HDD5GHZCHAN(5300, 60, 0) ,
213 HDD5GHZCHAN(5320, 64, 0) ,
214 HDD5GHZCHAN(5500,100, 0) ,
215 HDD5GHZCHAN(5520,104, 0) ,
216 HDD5GHZCHAN(5540,108, 0) ,
217 HDD5GHZCHAN(5560,112, 0) ,
218 HDD5GHZCHAN(5580,116, 0) ,
219 HDD5GHZCHAN(5600,120, 0) ,
220 HDD5GHZCHAN(5620,124, 0) ,
221 HDD5GHZCHAN(5640,128, 0) ,
222 HDD5GHZCHAN(5660,132, 0) ,
223 HDD5GHZCHAN(5680,136, 0) ,
224 HDD5GHZCHAN(5700,140, 0) ,
Leo Chang80de3c22013-11-26 10:52:12 -0800225#ifdef FEATURE_WLAN_CH144
226 HDD5GHZCHAN(5720,144, 0) ,
227#endif /* FEATURE_WLAN_CH144 */
Jeff Johnson295189b2012-06-20 16:38:30 -0700228 HDD5GHZCHAN(5745,149, 0) ,
229 HDD5GHZCHAN(5765,153, 0) ,
230 HDD5GHZCHAN(5785,157, 0) ,
231 HDD5GHZCHAN(5805,161, 0) ,
232 HDD5GHZCHAN(5825,165, 0) ,
233};
234
235static struct ieee80211_rate g_mode_rates[] =
236{
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530237 HDD_G_MODE_RATETAB(10, 0x1, 0),
238 HDD_G_MODE_RATETAB(20, 0x2, 0),
239 HDD_G_MODE_RATETAB(55, 0x4, 0),
240 HDD_G_MODE_RATETAB(110, 0x8, 0),
241 HDD_G_MODE_RATETAB(60, 0x10, 0),
242 HDD_G_MODE_RATETAB(90, 0x20, 0),
243 HDD_G_MODE_RATETAB(120, 0x40, 0),
244 HDD_G_MODE_RATETAB(180, 0x80, 0),
245 HDD_G_MODE_RATETAB(240, 0x100, 0),
246 HDD_G_MODE_RATETAB(360, 0x200, 0),
247 HDD_G_MODE_RATETAB(480, 0x400, 0),
Jeff Johnson295189b2012-06-20 16:38:30 -0700248 HDD_G_MODE_RATETAB(540, 0x800, 0),
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530249};
Jeff Johnson295189b2012-06-20 16:38:30 -0700250
251static struct ieee80211_rate a_mode_rates[] =
252{
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530253 HDD_G_MODE_RATETAB(60, 0x10, 0),
254 HDD_G_MODE_RATETAB(90, 0x20, 0),
255 HDD_G_MODE_RATETAB(120, 0x40, 0),
256 HDD_G_MODE_RATETAB(180, 0x80, 0),
257 HDD_G_MODE_RATETAB(240, 0x100, 0),
258 HDD_G_MODE_RATETAB(360, 0x200, 0),
259 HDD_G_MODE_RATETAB(480, 0x400, 0),
Jeff Johnson295189b2012-06-20 16:38:30 -0700260 HDD_G_MODE_RATETAB(540, 0x800, 0),
261};
262
263static struct ieee80211_supported_band wlan_hdd_band_2_4_GHZ =
264{
265 .channels = hdd_channels_2_4_GHZ,
266 .n_channels = ARRAY_SIZE(hdd_channels_2_4_GHZ),
267 .band = IEEE80211_BAND_2GHZ,
268 .bitrates = g_mode_rates,
269 .n_bitrates = g_mode_rates_size,
270 .ht_cap.ht_supported = 1,
271 .ht_cap.cap = IEEE80211_HT_CAP_SGI_20
272 | IEEE80211_HT_CAP_GRN_FLD
273 | IEEE80211_HT_CAP_DSSSCCK40
274 | IEEE80211_HT_CAP_LSIG_TXOP_PROT,
275 .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
276 .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
277 .ht_cap.mcs.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
278 .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ),
279 .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
280};
281
Jeff Johnson295189b2012-06-20 16:38:30 -0700282static struct ieee80211_supported_band wlan_hdd_band_p2p_2_4_GHZ =
283{
284 .channels = hdd_social_channels_2_4_GHZ,
285 .n_channels = ARRAY_SIZE(hdd_social_channels_2_4_GHZ),
286 .band = IEEE80211_BAND_2GHZ,
287 .bitrates = g_mode_rates,
288 .n_bitrates = g_mode_rates_size,
289 .ht_cap.ht_supported = 1,
290 .ht_cap.cap = IEEE80211_HT_CAP_SGI_20
291 | IEEE80211_HT_CAP_GRN_FLD
292 | IEEE80211_HT_CAP_DSSSCCK40
293 | IEEE80211_HT_CAP_LSIG_TXOP_PROT,
294 .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
295 .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
296 .ht_cap.mcs.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
297 .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ),
298 .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
299};
Jeff Johnson295189b2012-06-20 16:38:30 -0700300
301static struct ieee80211_supported_band wlan_hdd_band_5_GHZ =
302{
303 .channels = hdd_channels_5_GHZ,
304 .n_channels = ARRAY_SIZE(hdd_channels_5_GHZ),
305 .band = IEEE80211_BAND_5GHZ,
306 .bitrates = a_mode_rates,
307 .n_bitrates = a_mode_rates_size,
308 .ht_cap.ht_supported = 1,
309 .ht_cap.cap = IEEE80211_HT_CAP_SGI_20
310 | IEEE80211_HT_CAP_GRN_FLD
311 | IEEE80211_HT_CAP_DSSSCCK40
312 | IEEE80211_HT_CAP_LSIG_TXOP_PROT
313 | IEEE80211_HT_CAP_SGI_40
314 | IEEE80211_HT_CAP_SUP_WIDTH_20_40,
315 .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
316 .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
317 .ht_cap.mcs.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
318 .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ),
319 .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
320};
321
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530322/* This structure contain information what kind of frame are expected in
Jeff Johnson295189b2012-06-20 16:38:30 -0700323 TX/RX direction for each kind of interface */
324static const struct ieee80211_txrx_stypes
325wlan_hdd_txrx_stypes[NUM_NL80211_IFTYPES] = {
326 [NL80211_IFTYPE_STATION] = {
327 .tx = 0xffff,
328 .rx = BIT(SIR_MAC_MGMT_ACTION) |
329 BIT(SIR_MAC_MGMT_PROBE_REQ),
330 },
331 [NL80211_IFTYPE_AP] = {
332 .tx = 0xffff,
333 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
334 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
335 BIT(SIR_MAC_MGMT_PROBE_REQ) |
336 BIT(SIR_MAC_MGMT_DISASSOC) |
337 BIT(SIR_MAC_MGMT_AUTH) |
338 BIT(SIR_MAC_MGMT_DEAUTH) |
339 BIT(SIR_MAC_MGMT_ACTION),
340 },
Jeff Johnsonbc006202013-04-29 14:05:30 -0700341 [NL80211_IFTYPE_ADHOC] = {
342 .tx = 0xffff,
343 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
344 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
345 BIT(SIR_MAC_MGMT_PROBE_REQ) |
346 BIT(SIR_MAC_MGMT_DISASSOC) |
347 BIT(SIR_MAC_MGMT_AUTH) |
348 BIT(SIR_MAC_MGMT_DEAUTH) |
349 BIT(SIR_MAC_MGMT_ACTION),
350 },
Jeff Johnson295189b2012-06-20 16:38:30 -0700351 [NL80211_IFTYPE_P2P_CLIENT] = {
352 .tx = 0xffff,
353 .rx = BIT(SIR_MAC_MGMT_ACTION) |
354 BIT(SIR_MAC_MGMT_PROBE_REQ),
355 },
356 [NL80211_IFTYPE_P2P_GO] = {
357 /* This is also same as for SoftAP */
358 .tx = 0xffff,
359 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
360 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
361 BIT(SIR_MAC_MGMT_PROBE_REQ) |
362 BIT(SIR_MAC_MGMT_DISASSOC) |
363 BIT(SIR_MAC_MGMT_AUTH) |
364 BIT(SIR_MAC_MGMT_DEAUTH) |
365 BIT(SIR_MAC_MGMT_ACTION),
366 },
Jeff Johnson295189b2012-06-20 16:38:30 -0700367};
368
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800369#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800370static const struct ieee80211_iface_limit
371wlan_hdd_iface_limit[] = {
372 {
Sunil Ravia72c3992013-01-31 06:12:22 -0800373 /* max = 3 ; Our driver create two interfaces during driver init
374 * wlan0 and p2p0 interfaces. p2p0 is considered as station
375 * interface until a group is formed. In JB architecture, once the
376 * group is formed, interface type of p2p0 is changed to P2P GO or
377 * Client.
378 * When supplicant remove the group, it first issue a set interface
379 * cmd to change the mode back to Station. In JB this works fine as
380 * we advertize two station type interface during driver init.
381 * Some vendors create separate interface for P2P GO/Client,
382 * after group formation(Third one). But while group remove
383 * supplicant first tries to change the mode(3rd interface) to STATION
384 * But as we advertized only two sta type interfaces nl80211 was
385 * returning error for the third one which was leading to failure in
386 * delete interface. Ideally while removing the group, supplicant
387 * should not try to change the 3rd interface mode to Station type.
388 * Till we get a fix in wpa_supplicant, we advertize max STA
389 * interface type to 3
390 */
391 .max = 3,
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800392 .types = BIT(NL80211_IFTYPE_STATION),
393 },
394 {
395 .max = 1,
Jeff Johnsonbc006202013-04-29 14:05:30 -0700396 .types = BIT(NL80211_IFTYPE_ADHOC) | BIT(NL80211_IFTYPE_AP),
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800397 },
398 {
399 .max = 1,
400 .types = BIT(NL80211_IFTYPE_P2P_GO) |
401 BIT(NL80211_IFTYPE_P2P_CLIENT),
402 },
403};
404
405/* By default, only single channel concurrency is allowed */
406static struct ieee80211_iface_combination
407wlan_hdd_iface_combination = {
408 .limits = wlan_hdd_iface_limit,
409 .num_different_channels = 1,
Sunil Ravia72c3992013-01-31 06:12:22 -0800410 /*
411 * max = WLAN_MAX_INTERFACES ; JellyBean architecture creates wlan0
412 * and p2p0 interfaces during driver init
413 * Some vendors create separate interface for P2P operations.
414 * wlan0: STA interface
415 * p2p0: P2P Device interface, action frames goes
416 * through this interface.
417 * p2p-xx: P2P interface, After GO negotiation this interface is
418 * created for p2p operations(GO/CLIENT interface).
419 */
420 .max_interfaces = WLAN_MAX_INTERFACES,
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800421 .n_limits = ARRAY_SIZE(wlan_hdd_iface_limit),
422 .beacon_int_infra_match = false,
423};
424#endif
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800425
Jeff Johnson295189b2012-06-20 16:38:30 -0700426static struct cfg80211_ops wlan_hdd_cfg80211_ops;
427
428/* Data rate 100KBPS based on IE Index */
429struct index_data_rate_type
430{
431 v_U8_t beacon_rate_index;
432 v_U16_t supported_rate[4];
433};
434
435/* 11B, 11G Rate table include Basic rate and Extended rate
436 The IDX field is the rate index
437 The HI field is the rate when RSSI is strong or being ignored
438 (in this case we report actual rate)
439 The MID field is the rate when RSSI is moderate
440 (in this case we cap 11b rates at 5.5 and 11g rates at 24)
441 The LO field is the rate when RSSI is low
442 (in this case we don't report rates, actual current rate used)
443 */
444static const struct
445{
446 v_U8_t beacon_rate_index;
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -0700447 v_U16_t supported_rate[4];
Jeff Johnson295189b2012-06-20 16:38:30 -0700448} supported_data_rate[] =
449{
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -0700450/* IDX HI HM LM LO (RSSI-based index */
451 {2, { 10, 10, 10, 0}},
452 {4, { 20, 20, 10, 0}},
453 {11, { 55, 20, 10, 0}},
454 {12, { 60, 55, 20, 0}},
455 {18, { 90, 55, 20, 0}},
456 {22, {110, 55, 20, 0}},
457 {24, {120, 90, 60, 0}},
458 {36, {180, 120, 60, 0}},
459 {44, {220, 180, 60, 0}},
460 {48, {240, 180, 90, 0}},
461 {66, {330, 180, 90, 0}},
462 {72, {360, 240, 90, 0}},
463 {96, {480, 240, 120, 0}},
464 {108, {540, 240, 120, 0}}
Jeff Johnson295189b2012-06-20 16:38:30 -0700465};
466
467/* MCS Based rate table */
468static struct index_data_rate_type supported_mcs_rate[] =
469{
470/* MCS L20 L40 S20 S40 */
471 {0, {65, 135, 72, 150}},
472 {1, {130, 270, 144, 300}},
473 {2, {195, 405, 217, 450}},
474 {3, {260, 540, 289, 600}},
475 {4, {390, 810, 433, 900}},
476 {5, {520, 1080, 578, 1200}},
477 {6, {585, 1215, 650, 1350}},
478 {7, {650, 1350, 722, 1500}}
479};
480
Leo Chang6f8870f2013-03-26 18:11:36 -0700481#ifdef WLAN_FEATURE_11AC
482
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530483#define DATA_RATE_11AC_MCS_MASK 0x03
Leo Chang6f8870f2013-03-26 18:11:36 -0700484
485struct index_vht_data_rate_type
486{
487 v_U8_t beacon_rate_index;
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530488 v_U16_t supported_VHT80_rate[2];
489 v_U16_t supported_VHT40_rate[2];
490 v_U16_t supported_VHT20_rate[2];
Leo Chang6f8870f2013-03-26 18:11:36 -0700491};
492
493typedef enum
494{
495 DATA_RATE_11AC_MAX_MCS_7,
496 DATA_RATE_11AC_MAX_MCS_8,
497 DATA_RATE_11AC_MAX_MCS_9,
498 DATA_RATE_11AC_MAX_MCS_NA
499} eDataRate11ACMaxMcs;
500
501/* MCS Based VHT rate table */
502static struct index_vht_data_rate_type supported_vht_mcs_rate[] =
503{
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530504/* MCS L80 S80 L40 S40 L20 S40*/
505 {0, {293, 325}, {135, 150}, {65, 72}},
506 {1, {585, 650}, {270, 300}, {130, 144}},
507 {2, {878, 975}, {405, 450}, {195, 217}},
508 {3, {1170, 1300}, {540, 600}, {260, 289}},
509 {4, {1755, 1950}, {810, 900}, {390, 433}},
510 {5, {2340, 2600}, {1080, 1200}, {520, 578}},
511 {6, {2633, 2925}, {1215, 1350}, {585, 650}},
512 {7, {2925, 3250}, {1350, 1500}, {650, 722}},
513 {8, {3510, 3900}, {1620, 1800}, {780, 867}},
514 {9, {3900, 4333}, {1800, 2000}, {780, 867}}
Leo Chang6f8870f2013-03-26 18:11:36 -0700515};
516#endif /* WLAN_FEATURE_11AC */
517
Jeff Johnson295189b2012-06-20 16:38:30 -0700518extern struct net_device_ops net_ops_struct;
519
Leo Chang9056f462013-08-01 19:21:11 -0700520#ifdef WLAN_NL80211_TESTMODE
521enum wlan_hdd_tm_attr
522{
523 WLAN_HDD_TM_ATTR_INVALID = 0,
524 WLAN_HDD_TM_ATTR_CMD = 1,
525 WLAN_HDD_TM_ATTR_DATA = 2,
526 WLAN_HDD_TM_ATTR_TYPE = 3,
527 /* keep last */
528 WLAN_HDD_TM_ATTR_AFTER_LAST,
529 WLAN_HDD_TM_ATTR_MAX = WLAN_HDD_TM_ATTR_AFTER_LAST - 1,
530};
531
532enum wlan_hdd_tm_cmd
533{
534 WLAN_HDD_TM_CMD_WLAN_HB = 1,
535};
536
537#define WLAN_HDD_TM_DATA_MAX_LEN 5000
538
539static const struct nla_policy wlan_hdd_tm_policy[WLAN_HDD_TM_ATTR_MAX + 1] =
540{
541 [WLAN_HDD_TM_ATTR_CMD] = { .type = NLA_U32 },
542 [WLAN_HDD_TM_ATTR_DATA] = { .type = NLA_BINARY,
543 .len = WLAN_HDD_TM_DATA_MAX_LEN },
544};
545#endif /* WLAN_NL80211_TESTMODE */
546
Rajesh Chauhan98a31f82014-01-06 20:15:25 -0800547#ifdef FEATURE_WLAN_CH_AVOID
548/*
549 * FUNCTION: wlan_hdd_send_avoid_freq_event
550 * This is called when wlan driver needs to send vendor specific
551 * avoid frequency range event to userspace
552 */
553int wlan_hdd_send_avoid_freq_event(hdd_context_t *pHddCtx,
554 tHddAvoidFreqList *pAvoidFreqList)
555{
556 struct sk_buff *vendor_event;
557
558 ENTER();
559
560 if (!pHddCtx)
561 {
562 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
563 "%s: HDD context is null", __func__);
564 return -1;
565 }
566
567 if (!pAvoidFreqList)
568 {
569 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
570 "%s: pAvoidFreqList is null", __func__);
571 return -1;
572 }
573
574 vendor_event = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
575 sizeof(tHddAvoidFreqList),
576 QCOM_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY_INDEX,
577 GFP_KERNEL);
578 if (!vendor_event)
579 {
580 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
581 "%s: cfg80211_vendor_event_alloc failed", __func__);
582 return -1;
583 }
584
585 memcpy(skb_put(vendor_event, sizeof(tHddAvoidFreqList)),
586 (void *)pAvoidFreqList, sizeof(tHddAvoidFreqList));
587
588 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
589
590 EXIT();
591 return 0;
592}
593#endif /* FEATURE_WLAN_CH_AVOID */
594
595/* vendor specific events */
596static const struct nl80211_vendor_cmd_info wlan_hdd_cfg80211_vendor_events[] =
597{
598#ifdef FEATURE_WLAN_CH_AVOID
599 {
600 .vendor_id = QCOM_NL80211_VENDOR_ID,
601 .subcmd = QCOM_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY
602 },
603#endif /* FEATURE_WLAN_CH_AVOID */
604};
605
Jeff Johnson295189b2012-06-20 16:38:30 -0700606/*
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +0530607 * FUNCTION: wlan_hdd_cfg80211_wiphy_alloc
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530608 * This function is called by hdd_wlan_startup()
609 * during initialization.
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +0530610 * This function is used to allocate wiphy structure.
Jeff Johnson295189b2012-06-20 16:38:30 -0700611 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +0530612struct wiphy *wlan_hdd_cfg80211_wiphy_alloc(int priv_size)
Jeff Johnson295189b2012-06-20 16:38:30 -0700613{
614 struct wiphy *wiphy;
615 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530616 /*
617 * Create wiphy device
Jeff Johnson295189b2012-06-20 16:38:30 -0700618 */
619 wiphy = wiphy_new(&wlan_hdd_cfg80211_ops, priv_size);
620
621 if (!wiphy)
622 {
623 /* Print error and jump into err label and free the memory */
624 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wiphy init failed", __func__);
625 return NULL;
626 }
627
628 return wiphy;
629}
630
631/*
632 * FUNCTION: wlan_hdd_cfg80211_update_band
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530633 * This function is called from the supplicant through a
Jeff Johnson295189b2012-06-20 16:38:30 -0700634 * private ioctl to change the band value
635 */
636int wlan_hdd_cfg80211_update_band(struct wiphy *wiphy, eCsrBand eBand)
637{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +0530638 int i, j;
639 eNVChannelEnabledType channelEnabledState;
640
Jeff Johnsone7245742012-09-05 17:12:55 -0700641 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +0530642
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +0530643 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
Jeff Johnson295189b2012-06-20 16:38:30 -0700644 {
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +0530645
646 if (NULL == wiphy->bands[i])
647 {
648 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[i] is NULL, i = %d",
649 __func__, i);
650 continue;
651 }
652
653 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
654 {
655 struct ieee80211_supported_band *band = wiphy->bands[i];
656
657 channelEnabledState = vos_nv_getChannelEnabledState(
658 band->channels[j].hw_value);
659
660 if (IEEE80211_BAND_2GHZ == i && eCSR_BAND_5G == eBand) // 5G only
661 {
662 // Enable Social channels for P2P
663 if (WLAN_HDD_IS_SOCIAL_CHANNEL(band->channels[j].center_freq) &&
664 NV_CHANNEL_ENABLE == channelEnabledState)
665 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
666 else
667 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
668 continue;
669 }
670 else if (IEEE80211_BAND_5GHZ == i && eCSR_BAND_24 == eBand) // 2G only
671 {
672 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
673 continue;
674 }
675
676 if (NV_CHANNEL_DISABLE == channelEnabledState ||
677 NV_CHANNEL_INVALID == channelEnabledState)
678 {
679 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
680 }
681 else if (NV_CHANNEL_DFS == channelEnabledState)
682 {
683 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
684 band->channels[j].flags |= IEEE80211_CHAN_RADAR;
685 }
686 else
687 {
688 band->channels[j].flags &= ~(IEEE80211_CHAN_DISABLED
689 |IEEE80211_CHAN_RADAR);
690 }
691 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700692 }
693 return 0;
694}
695/*
696 * FUNCTION: wlan_hdd_cfg80211_init
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530697 * This function is called by hdd_wlan_startup()
698 * during initialization.
Jeff Johnson295189b2012-06-20 16:38:30 -0700699 * This function is used to initialize and register wiphy structure.
700 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +0530701int wlan_hdd_cfg80211_init(struct device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -0700702 struct wiphy *wiphy,
703 hdd_config_t *pCfg
704 )
705{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +0530706 int i, j;
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +0530707 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
708
Jeff Johnsone7245742012-09-05 17:12:55 -0700709 ENTER();
710
Jeff Johnson295189b2012-06-20 16:38:30 -0700711 /* Now bind the underlying wlan device with wiphy */
712 set_wiphy_dev(wiphy, dev);
713
714 wiphy->mgmt_stypes = wlan_hdd_txrx_stypes;
Amar Singhalfddc28c2013-09-05 13:03:40 -0700715
Kiet Lam6c583332013-10-14 05:37:09 +0530716#ifndef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -0700717 /* the flag for the other case would be initialzed in
718 vos_init_wiphy_from_nv_bin */
Amar Singhal0a402232013-10-11 20:57:16 -0700719 wiphy->flags |= WIPHY_FLAG_STRICT_REGULATORY;
Kiet Lam6c583332013-10-14 05:37:09 +0530720#endif
Amar Singhala49cbc52013-10-08 18:37:44 -0700721
Amar Singhalfddc28c2013-09-05 13:03:40 -0700722 /* This will disable updating of NL channels from passive to
723 * active if a beacon is received on passive channel. */
724 wiphy->flags |= WIPHY_FLAG_DISABLE_BEACON_HINTS;
Amar Singhalf0073192013-09-20 12:34:56 -0700725
Amar Singhalfddc28c2013-09-05 13:03:40 -0700726
Amar Singhala49cbc52013-10-08 18:37:44 -0700727
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700728#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -0700729 wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME
730 | WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD
731 | WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL
Jeff Johnsone7245742012-09-05 17:12:55 -0700732 | WIPHY_FLAG_OFFCHAN_TX;
Kiet Lam6c583332013-10-14 05:37:09 +0530733 wiphy->country_ie_pref = NL80211_COUNTRY_IE_IGNORE_CORE;
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700734#endif
Amar Singhala49cbc52013-10-08 18:37:44 -0700735
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800736#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowda640728a2013-03-28 12:21:54 -0700737 if (pCfg->isFastTransitionEnabled
James Zmuda77fb5ae2013-01-29 08:00:17 -0800738#ifdef FEATURE_WLAN_LFR
Srinivas Girigowda640728a2013-03-28 12:21:54 -0700739 || pCfg->isFastRoamIniFeatureEnabled
740#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800741#ifdef FEATURE_WLAN_ESE
742 || pCfg->isEseIniFeatureEnabled
Srinivas Girigowda640728a2013-03-28 12:21:54 -0700743#endif
744 )
745 {
746 wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM;
747 }
James Zmuda77fb5ae2013-01-29 08:00:17 -0800748#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -0800749#ifdef FEATURE_WLAN_TDLS
750 wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS
751 | WIPHY_FLAG_TDLS_EXTERNAL_SETUP;
752#endif
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +0530753#ifdef FEATURE_WLAN_SCAN_PNO
Hardik Kantilal Patel3dfd8792013-11-13 20:34:57 +0530754 if (pCfg->configPNOScanSupport)
755 {
756 wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN;
757 wiphy->max_sched_scan_ssids = SIR_PNO_MAX_SUPP_NETWORKS;
758 wiphy->max_match_sets = SIR_PNO_MAX_SUPP_NETWORKS;
759 wiphy->max_sched_scan_ie_len = SIR_MAC_MAX_IE_LENGTH;
760 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +0530761#endif/*FEATURE_WLAN_SCAN_PNO*/
Mohit Khanna698ba2a2012-12-04 15:08:18 -0800762
Amar Singhalfddc28c2013-09-05 13:03:40 -0700763#ifdef CONFIG_ENABLE_LINUX_REG
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -0700764 /* even with WIPHY_FLAG_CUSTOM_REGULATORY,
765 driver can still register regulatory callback and
Amar Singhalfddc28c2013-09-05 13:03:40 -0700766 it will get regulatory settings in wiphy->band[], but
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -0700767 driver need to determine what to do with both
768 regulatory settings */
Amar Singhalfddc28c2013-09-05 13:03:40 -0700769
770 wiphy->reg_notifier = wlan_hdd_linux_reg_notifier;
Amar Singhala49cbc52013-10-08 18:37:44 -0700771#else
772 wiphy->reg_notifier = wlan_hdd_crda_reg_notifier;
Amar Singhalfddc28c2013-09-05 13:03:40 -0700773#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700774
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530775 wiphy->max_scan_ssids = MAX_SCAN_SSID;
776
Madan Mohan Koyyalamudi6815b162013-07-19 17:17:46 +0530777 wiphy->max_scan_ie_len = SIR_MAC_MAX_IE_LENGTH;
Jeff Johnson295189b2012-06-20 16:38:30 -0700778
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +0530779 wiphy->max_acl_mac_addrs = MAX_ACL_MAC_ADDRESS;
780
Jeff Johnson295189b2012-06-20 16:38:30 -0700781 /* Supports STATION & AD-HOC modes right now */
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530782 wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -0700783 | BIT(NL80211_IFTYPE_ADHOC)
Jeff Johnson295189b2012-06-20 16:38:30 -0700784 | BIT(NL80211_IFTYPE_P2P_CLIENT)
785 | BIT(NL80211_IFTYPE_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -0700786 | BIT(NL80211_IFTYPE_AP);
787
Rashmi Ramannabd3feb72014-02-25 16:14:48 +0530788 if( pCfg->advertiseConcurrentOperation )
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800789 {
Rashmi Ramannabd3feb72014-02-25 16:14:48 +0530790#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
791 if( pCfg->enableMCC )
792 {
793 /* Currently, supports up to two channels */
794 wlan_hdd_iface_combination.num_different_channels = 2;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800795
Rashmi Ramannabd3feb72014-02-25 16:14:48 +0530796 if( !pCfg->allowMCCGODiffBI )
797 wlan_hdd_iface_combination.beacon_int_infra_match = true;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800798
Rashmi Ramannabd3feb72014-02-25 16:14:48 +0530799 }
800 wiphy->iface_combinations = &wlan_hdd_iface_combination;
801 wiphy->n_iface_combinations = 1;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800802#endif
Rashmi Ramannabd3feb72014-02-25 16:14:48 +0530803 }
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800804
Jeff Johnson295189b2012-06-20 16:38:30 -0700805 /* Before registering we need to update the ht capabilitied based
806 * on ini values*/
807 if( !pCfg->ShortGI20MhzEnable )
808 {
809 wlan_hdd_band_2_4_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
810 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
811 wlan_hdd_band_p2p_2_4_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
812 }
813
814 if( !pCfg->ShortGI40MhzEnable )
815 {
816 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_40;
817 }
818
819 if( !pCfg->nChannelBondingMode5GHz )
820 {
821 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
822 }
823
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +0530824 wiphy->bands[IEEE80211_BAND_2GHZ] = &wlan_hdd_band_2_4_GHZ;
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +0530825 if (true == hdd_is_5g_supported(pHddCtx))
826 {
827 wiphy->bands[IEEE80211_BAND_5GHZ] = &wlan_hdd_band_5_GHZ;
828 }
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +0530829
830 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
831 {
832
833 if (NULL == wiphy->bands[i])
834 {
835 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[i] is NULL, i = %d",
836 __func__, i);
837 continue;
838 }
839
840 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
841 {
842 struct ieee80211_supported_band *band = wiphy->bands[i];
843
844 if (IEEE80211_BAND_2GHZ == i && eCSR_BAND_5G == pCfg->nBandCapability) // 5G only
845 {
846 // Enable social channels for P2P
847 if (WLAN_HDD_IS_SOCIAL_CHANNEL(band->channels[j].center_freq))
848 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
849 else
850 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
851 continue;
852 }
853 else if (IEEE80211_BAND_5GHZ == i && eCSR_BAND_24 == pCfg->nBandCapability) // 2G only
854 {
855 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
856 continue;
857 }
858 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700859 }
860 /*Initialise the supported cipher suite details*/
861 wiphy->cipher_suites = hdd_cipher_suites;
862 wiphy->n_cipher_suites = ARRAY_SIZE(hdd_cipher_suites);
863
864 /*signal strength in mBm (100*dBm) */
865 wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
866
867#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Jeff Johnson295189b2012-06-20 16:38:30 -0700868 wiphy->max_remain_on_channel_duration = 1000;
869#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700870
Rajesh Chauhan98a31f82014-01-06 20:15:25 -0800871 wiphy->n_vendor_commands = 0;
872 wiphy->vendor_events = wlan_hdd_cfg80211_vendor_events;
873 wiphy->n_vendor_events = ARRAY_SIZE(wlan_hdd_cfg80211_vendor_events);
874
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +0530875 EXIT();
876 return 0;
877}
878
879/* In this function we are registering wiphy. */
880int wlan_hdd_cfg80211_register(struct wiphy *wiphy)
881{
882 ENTER();
883 /* Register our wiphy dev with cfg80211 */
Jeff Johnson295189b2012-06-20 16:38:30 -0700884 if (0 > wiphy_register(wiphy))
885 {
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +0530886 /* print error */
Jeff Johnson295189b2012-06-20 16:38:30 -0700887 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
888 return -EIO;
889 }
890
891 EXIT();
892 return 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530893}
Jeff Johnson295189b2012-06-20 16:38:30 -0700894
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +0530895/* In this function we are updating channel list when,
896 regulatory domain is FCC and country code is US.
897 Here In FCC standard 5GHz UNII-1 Bands are indoor only.
898 As per FCC smart phone is not a indoor device.
899 GO should not opeate on indoor channels */
900void wlan_hdd_cfg80211_update_reg_info(struct wiphy *wiphy)
901{
902 int j;
903 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
904 tANI_U8 defaultCountryCode[3] = SME_INVALID_COUNTRY_CODE;
905 //Default counrtycode from NV at the time of wiphy initialization.
906 if (eHAL_STATUS_SUCCESS != sme_GetDefaultCountryCodeFrmNv(pHddCtx->hHal,
907 &defaultCountryCode[0]))
908 {
Jeff Johnson0299d0a2013-10-30 12:37:43 -0700909 hddLog(LOGE, FL("Failed to get default country code from NV"));
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +0530910 }
911 if ((defaultCountryCode[0]== 'U') && (defaultCountryCode[1]=='S'))
912 {
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +0530913 if (NULL == wiphy->bands[IEEE80211_BAND_5GHZ])
914 {
915 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[IEEE80211_BAND_5GHZ] is NULL",__func__ );
916 return;
917 }
918 for (j = 0; j < wiphy->bands[IEEE80211_BAND_5GHZ]->n_channels; j++)
919 {
920 struct ieee80211_supported_band *band = wiphy->bands[IEEE80211_BAND_5GHZ];
921 // Mark UNII -1 band channel as passive
922 if (WLAN_HDD_CHANNEL_IN_UNII_1_BAND(band->channels[j].center_freq))
923 band->channels[j].flags |= IEEE80211_CHAN_PASSIVE_SCAN;
924 }
925 }
926}
927
Jeff Johnson295189b2012-06-20 16:38:30 -0700928/* In this function we will do all post VOS start initialization.
929 In this function we will register for all frame in which supplicant
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530930 is interested.
Jeff Johnson295189b2012-06-20 16:38:30 -0700931*/
932void wlan_hdd_cfg80211_post_voss_start(hdd_adapter_t* pAdapter)
933{
Jeff Johnson295189b2012-06-20 16:38:30 -0700934 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
935 /* Register for all P2P action, public action etc frames */
936 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
937
Jeff Johnsone7245742012-09-05 17:12:55 -0700938 ENTER();
939
Jeff Johnson295189b2012-06-20 16:38:30 -0700940 /* Right now we are registering these frame when driver is getting
941 initialized. Once we will move to 2.6.37 kernel, in which we have
942 frame register ops, we will move this code as a part of that */
943 /* GAS Initial Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530944 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Jeff Johnson295189b2012-06-20 16:38:30 -0700945 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
946
947 /* GAS Initial Response */
948 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
949 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530950
Jeff Johnson295189b2012-06-20 16:38:30 -0700951 /* GAS Comeback Request */
952 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
953 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
954
955 /* GAS Comeback Response */
956 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
957 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
958
959 /* P2P Public Action */
960 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530961 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -0700962 P2P_PUBLIC_ACTION_FRAME_SIZE );
963
964 /* P2P Action */
965 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
966 (v_U8_t*)P2P_ACTION_FRAME,
967 P2P_ACTION_FRAME_SIZE );
Chet Lanctot186b5732013-03-18 10:26:30 -0700968
Gopichand Nakkalae3d56e72013-04-21 23:33:32 +0530969 /* WNM BSS Transition Request frame */
970 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
971 (v_U8_t*)WNM_BSS_ACTION_FRAME,
972 WNM_BSS_ACTION_FRAME_SIZE );
Leela Venkata Kiran Kumar Reddy Chiralae8e62c82013-10-29 18:23:26 -0700973
974 /* WNM-Notification */
975 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
976 (v_U8_t*)WNM_NOTIFICATION_FRAME,
977 WNM_NOTIFICATION_FRAME_SIZE );
978
Leela Venkata Kiran Kumar Reddy Chiralae8e62c82013-10-29 18:23:26 -0700979#ifdef WLAN_FEATURE_11W
980 /* SA Query Response Action Frame */
981 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
982 (v_U8_t*)SA_QUERY_FRAME_RSP,
983 SA_QUERY_FRAME_RSP_SIZE );
984#endif /* WLAN_FEATURE_11W */
Jeff Johnson295189b2012-06-20 16:38:30 -0700985}
986
987void wlan_hdd_cfg80211_pre_voss_stop(hdd_adapter_t* pAdapter)
988{
Jeff Johnson295189b2012-06-20 16:38:30 -0700989 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
990 /* Register for all P2P action, public action etc frames */
991 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
992
Jeff Johnsone7245742012-09-05 17:12:55 -0700993 ENTER();
994
Jeff Johnson295189b2012-06-20 16:38:30 -0700995 /* Right now we are registering these frame when driver is getting
996 initialized. Once we will move to 2.6.37 kernel, in which we have
997 frame register ops, we will move this code as a part of that */
998 /* GAS Initial Request */
999
1000 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
1001 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
1002
1003 /* GAS Initial Response */
1004 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
1005 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301006
Jeff Johnson295189b2012-06-20 16:38:30 -07001007 /* GAS Comeback Request */
1008 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
1009 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
1010
1011 /* GAS Comeback Response */
1012 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
1013 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
1014
1015 /* P2P Public Action */
1016 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301017 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -07001018 P2P_PUBLIC_ACTION_FRAME_SIZE );
1019
1020 /* P2P Action */
1021 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
1022 (v_U8_t*)P2P_ACTION_FRAME,
1023 P2P_ACTION_FRAME_SIZE );
Leela Venkata Kiran Kumar Reddy Chiralae8e62c82013-10-29 18:23:26 -07001024 /* WNM-Notification */
1025 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
1026 (v_U8_t*)WNM_NOTIFICATION_FRAME,
1027 WNM_NOTIFICATION_FRAME_SIZE );
1028
Chet Lanctot186b5732013-03-18 10:26:30 -07001029#ifdef WLAN_FEATURE_11W
1030 /* SA Query Response Action Frame */
1031 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
1032 (v_U8_t*)SA_QUERY_FRAME_RSP,
1033 SA_QUERY_FRAME_RSP_SIZE );
1034#endif /* WLAN_FEATURE_11W */
Jeff Johnson295189b2012-06-20 16:38:30 -07001035}
1036
1037#ifdef FEATURE_WLAN_WAPI
1038void wlan_hdd_cfg80211_set_key_wapi(hdd_adapter_t* pAdapter, u8 key_index,
1039 const u8 *mac_addr, u8 *key , int key_Len)
1040{
1041 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
1042 tCsrRoamSetKey setKey;
1043 v_BOOL_t isConnected = TRUE;
1044 int status = 0;
1045 v_U32_t roamId= 0xFF;
1046 tANI_U8 *pKeyPtr = NULL;
1047 int n = 0;
1048
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05301049 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s(%d)",
1050 __func__, hdd_device_modetoString(pAdapter->device_mode),
1051 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07001052
Gopichand Nakkalae7480202013-02-11 15:24:22 +05301053 vos_mem_zero(&setKey, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -07001054 setKey.keyId = key_index; // Store Key ID
1055 setKey.encType = eCSR_ENCRYPT_TYPE_WPI; // SET WAPI Encryption
1056 setKey.keyDirection = eSIR_TX_RX; // Key Directionn both TX and RX
1057 setKey.paeRole = 0 ; // the PAE role
1058 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
1059 {
1060 vos_set_macaddr_broadcast( (v_MACADDR_t *)setKey.peerMac );
1061 }
1062 else
1063 {
1064 isConnected = hdd_connIsConnected(pHddStaCtx);
1065 vos_mem_copy(setKey.peerMac,&pHddStaCtx->conn_info.bssId,WNI_CFG_BSSID_LEN);
1066 }
1067 setKey.keyLength = key_Len;
1068 pKeyPtr = setKey.Key;
1069 memcpy( pKeyPtr, key, key_Len);
1070
Arif Hussain6d2a3322013-11-17 19:50:10 -08001071 hddLog(VOS_TRACE_LEVEL_INFO,"%s: WAPI KEY LENGTH:0x%04x",
Jeff Johnson295189b2012-06-20 16:38:30 -07001072 __func__, key_Len);
1073 for (n = 0 ; n < key_Len; n++)
1074 hddLog(VOS_TRACE_LEVEL_INFO, "%s WAPI KEY Data[%d]:%02x ",
1075 __func__,n,setKey.Key[n]);
1076
1077 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
1078 if ( isConnected )
1079 {
1080 status= sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
1081 pAdapter->sessionId, &setKey, &roamId );
1082 }
1083 if ( status != 0 )
1084 {
1085 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1086 "[%4d] sme_RoamSetKey returned ERROR status= %d",
1087 __LINE__, status );
1088 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
1089 }
1090}
1091#endif /* FEATURE_WLAN_WAPI*/
1092
1093#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301094int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07001095 beacon_data_t **ppBeacon,
1096 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001097#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301098int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001099 beacon_data_t **ppBeacon,
1100 struct cfg80211_beacon_data *params,
1101 int dtim_period)
1102#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301103{
Jeff Johnson295189b2012-06-20 16:38:30 -07001104 int size;
1105 beacon_data_t *beacon = NULL;
1106 beacon_data_t *old = NULL;
1107 int head_len,tail_len;
1108
Jeff Johnsone7245742012-09-05 17:12:55 -07001109 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07001110 if (params->head && !params->head_len)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05301111 {
1112 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1113 FL("head_len is NULL"));
Jeff Johnson295189b2012-06-20 16:38:30 -07001114 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05301115 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001116
1117 old = pAdapter->sessionCtx.ap.beacon;
1118
1119 if (!params->head && !old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05301120 {
1121 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1122 FL("session(%d) old and new heads points to NULL"),
1123 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07001124 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05301125 }
1126
1127 if (params->tail && !params->tail_len)
1128 {
1129 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1130 FL("tail_len is zero but tail is not NULL"));
1131 return -EINVAL;
1132 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001133
Jeff Johnson295189b2012-06-20 16:38:30 -07001134#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,38))
1135 /* Kernel 3.0 is not updating dtim_period for set beacon */
1136 if (!params->dtim_period)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05301137 {
1138 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1139 FL("dtim period is 0"));
Jeff Johnson295189b2012-06-20 16:38:30 -07001140 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05301141 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001142#endif
1143
1144 if(params->head)
1145 head_len = params->head_len;
1146 else
1147 head_len = old->head_len;
1148
1149 if(params->tail || !old)
1150 tail_len = params->tail_len;
1151 else
1152 tail_len = old->tail_len;
1153
1154 size = sizeof(beacon_data_t) + head_len + tail_len;
1155
1156 beacon = kzalloc(size, GFP_KERNEL);
1157
1158 if( beacon == NULL )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05301159 {
1160 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1161 FL("Mem allocation for beacon failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -07001162 return -ENOMEM;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05301163 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001164
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001165#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07001166 if(params->dtim_period || !old )
1167 beacon->dtim_period = params->dtim_period;
1168 else
1169 beacon->dtim_period = old->dtim_period;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001170#else
1171 if(dtim_period || !old )
1172 beacon->dtim_period = dtim_period;
1173 else
1174 beacon->dtim_period = old->dtim_period;
1175#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301176
Jeff Johnson295189b2012-06-20 16:38:30 -07001177 beacon->head = ((u8 *) beacon) + sizeof(beacon_data_t);
1178 beacon->tail = beacon->head + head_len;
1179 beacon->head_len = head_len;
1180 beacon->tail_len = tail_len;
1181
1182 if(params->head) {
1183 memcpy (beacon->head,params->head,beacon->head_len);
1184 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301185 else {
Jeff Johnson295189b2012-06-20 16:38:30 -07001186 if(old)
1187 memcpy (beacon->head,old->head,beacon->head_len);
1188 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301189
Jeff Johnson295189b2012-06-20 16:38:30 -07001190 if(params->tail) {
1191 memcpy (beacon->tail,params->tail,beacon->tail_len);
1192 }
1193 else {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301194 if(old)
Jeff Johnson295189b2012-06-20 16:38:30 -07001195 memcpy (beacon->tail,old->tail,beacon->tail_len);
1196 }
1197
1198 *ppBeacon = beacon;
1199
1200 kfree(old);
1201
1202 return 0;
1203
1204}
Jeff Johnson295189b2012-06-20 16:38:30 -07001205
1206v_U8_t* wlan_hdd_cfg80211_get_ie_ptr(v_U8_t *pIes, int length, v_U8_t eid)
1207{
1208 int left = length;
1209 v_U8_t *ptr = pIes;
1210 v_U8_t elem_id,elem_len;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301211
Jeff Johnson295189b2012-06-20 16:38:30 -07001212 while(left >= 2)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301213 {
Jeff Johnson295189b2012-06-20 16:38:30 -07001214 elem_id = ptr[0];
1215 elem_len = ptr[1];
1216 left -= 2;
1217 if(elem_len > left)
1218 {
1219 hddLog(VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07001220 FL("****Invalid IEs eid = %d elem_len=%d left=%d*****"),
Jeff Johnson295189b2012-06-20 16:38:30 -07001221 eid,elem_len,left);
1222 return NULL;
1223 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301224 if (elem_id == eid)
Jeff Johnson295189b2012-06-20 16:38:30 -07001225 {
1226 return ptr;
1227 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301228
Jeff Johnson295189b2012-06-20 16:38:30 -07001229 left -= elem_len;
1230 ptr += (elem_len + 2);
1231 }
1232 return NULL;
1233}
1234
Jeff Johnson295189b2012-06-20 16:38:30 -07001235/* Check if rate is 11g rate or not */
1236static int wlan_hdd_rate_is_11g(u8 rate)
1237{
Sanjay Devnani28322e22013-06-21 16:13:40 -07001238 static const u8 gRateArray[8] = {12, 18, 24, 36, 48, 72, 96, 108}; /* actual rate * 2 */
Jeff Johnson295189b2012-06-20 16:38:30 -07001239 u8 i;
1240 for (i = 0; i < 8; i++)
1241 {
1242 if(rate == gRateArray[i])
1243 return TRUE;
1244 }
1245 return FALSE;
1246}
1247
1248/* Check for 11g rate and set proper 11g only mode */
1249static void wlan_hdd_check_11gmode(u8 *pIe, u8* require_ht,
1250 u8* pCheckRatesfor11g, eSapPhyMode* pSapHw_mode)
1251{
1252 u8 i, num_rates = pIe[0];
1253
1254 pIe += 1;
1255 for ( i = 0; i < num_rates; i++)
1256 {
1257 if( *pCheckRatesfor11g && (TRUE == wlan_hdd_rate_is_11g(pIe[i] & RATE_MASK)))
1258 {
1259 /* If rate set have 11g rate than change the mode to 11G */
1260 *pSapHw_mode = eSAP_DOT11_MODE_11g;
1261 if (pIe[i] & BASIC_RATE_MASK)
1262 {
1263 /* If we have 11g rate as basic rate, it means mode
1264 is 11g only mode.
1265 */
1266 *pSapHw_mode = eSAP_DOT11_MODE_11g_ONLY;
1267 *pCheckRatesfor11g = FALSE;
1268 }
1269 }
1270 else if((BASIC_RATE_MASK | WLAN_BSS_MEMBERSHIP_SELECTOR_HT_PHY) == pIe[i])
1271 {
1272 *require_ht = TRUE;
1273 }
1274 }
1275 return;
1276}
1277
1278static void wlan_hdd_set_sapHwmode(hdd_adapter_t *pHostapdAdapter)
1279{
1280 tsap_Config_t *pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
1281 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
1282 struct ieee80211_mgmt *pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
1283 u8 checkRatesfor11g = TRUE;
1284 u8 require_ht = FALSE;
1285 u8 *pIe=NULL;
1286
1287 pConfig->SapHw_mode= eSAP_DOT11_MODE_11b;
1288
1289 pIe = wlan_hdd_cfg80211_get_ie_ptr(&pMgmt_frame->u.beacon.variable[0],
1290 pBeacon->head_len, WLAN_EID_SUPP_RATES);
1291 if (pIe != NULL)
1292 {
1293 pIe += 1;
1294 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
1295 &pConfig->SapHw_mode);
1296 }
1297
1298 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
1299 WLAN_EID_EXT_SUPP_RATES);
1300 if (pIe != NULL)
1301 {
1302
1303 pIe += 1;
1304 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
1305 &pConfig->SapHw_mode);
1306 }
1307
1308 if( pConfig->channel > 14 )
1309 {
1310 pConfig->SapHw_mode= eSAP_DOT11_MODE_11a;
1311 }
1312
1313 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
1314 WLAN_EID_HT_CAPABILITY);
1315
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301316 if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07001317 {
1318 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n;
1319 if(require_ht)
1320 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n_ONLY;
1321 }
1322}
1323
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05301324static int wlan_hdd_add_ie(hdd_adapter_t* pHostapdAdapter, v_U8_t *genie,
1325 v_U8_t *total_ielen, v_U8_t *oui, v_U8_t oui_size)
1326{
Arif Hussaine7f3ea52013-09-12 21:56:36 -07001327 v_U16_t ielen = 0;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05301328 v_U8_t *pIe = NULL;
1329 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
1330
1331 pIe = wlan_hdd_get_vendor_oui_ie_ptr(oui, oui_size,
1332 pBeacon->tail, pBeacon->tail_len);
1333
1334 if (pIe)
1335 {
1336 ielen = pIe[1] + 2;
1337 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
1338 {
1339 vos_mem_copy(&genie[*total_ielen], pIe, ielen);
1340 }
1341 else
1342 {
1343 hddLog( VOS_TRACE_LEVEL_ERROR, "**Ie Length is too big***");
1344 return -EINVAL;
1345 }
1346 *total_ielen += ielen;
1347 }
1348 return 0;
1349}
1350
Arif Hussaine7f3ea52013-09-12 21:56:36 -07001351static void wlan_hdd_add_hostapd_conf_vsie(hdd_adapter_t* pHostapdAdapter,
1352 v_U8_t *genie, v_U8_t *total_ielen)
1353{
1354 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
1355 int left = pBeacon->tail_len;
1356 v_U8_t *ptr = pBeacon->tail;
1357 v_U8_t elem_id, elem_len;
1358 v_U16_t ielen = 0;
1359
1360 if ( NULL == ptr || 0 == left )
1361 return;
1362
1363 while (left >= 2)
1364 {
1365 elem_id = ptr[0];
1366 elem_len = ptr[1];
1367 left -= 2;
1368 if (elem_len > left)
1369 {
1370 hddLog( VOS_TRACE_LEVEL_ERROR,
1371 "****Invalid IEs eid = %d elem_len=%d left=%d*****",
1372 elem_id, elem_len, left);
1373 return;
1374 }
1375 if (IE_EID_VENDOR == elem_id)
1376 {
1377 /* skipping the VSIE's which we don't want to include or
1378 * it will be included by existing code
1379 */
1380 if ((memcmp( &ptr[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) != 0 ) &&
1381#ifdef WLAN_FEATURE_WFD
1382 (memcmp( &ptr[2], WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE) != 0) &&
1383#endif
1384 (memcmp( &ptr[2], WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
1385 (memcmp( &ptr[2], BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
1386 (memcmp( &ptr[2], "\x00\x50\xf2\x02", WPA_OUI_TYPE_SIZE) != 0) &&
1387 (memcmp( &ptr[2], WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
1388 (memcmp( &ptr[2], P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE) != 0))
1389 {
1390 ielen = ptr[1] + 2;
1391 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
1392 {
1393 vos_mem_copy(&genie[*total_ielen], ptr, ielen);
1394 *total_ielen += ielen;
1395 }
1396 else
1397 {
1398 hddLog( VOS_TRACE_LEVEL_ERROR,
1399 "IE Length is too big "
1400 "IEs eid=%d elem_len=%d total_ie_lent=%d",
1401 elem_id, elem_len, *total_ielen);
1402 }
1403 }
1404 }
1405
1406 left -= elem_len;
1407 ptr += (elem_len + 2);
1408 }
1409 return;
1410}
1411
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001412#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07001413static int wlan_hdd_cfg80211_update_apies(hdd_adapter_t* pHostapdAdapter,
1414 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001415#else
1416static int wlan_hdd_cfg80211_update_apies(hdd_adapter_t* pHostapdAdapter,
1417 struct cfg80211_beacon_data *params)
1418#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07001419{
1420 v_U8_t *genie;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05301421 v_U8_t total_ielen = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07001422 v_U8_t addIE[1] = {0};
Jeff Johnsone7245742012-09-05 17:12:55 -07001423 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07001424
1425 genie = vos_mem_malloc(MAX_GENIE_LEN);
1426
1427 if(genie == NULL) {
1428
1429 return -ENOMEM;
1430 }
1431
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05301432 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
1433 &total_ielen, WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07001434 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05301435 hddLog(LOGE,
1436 FL("Adding WPS IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05301437 ret = -EINVAL;
1438 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001439 }
1440
1441#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05301442 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
1443 &total_ielen, WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE))
1444 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05301445 hddLog(LOGE,
1446 FL("Adding WFD IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05301447 ret = -EINVAL;
1448 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001449 }
1450#endif
1451
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05301452 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
1453 &total_ielen, P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07001454 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05301455 hddLog(LOGE,
1456 FL("Adding P2P IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05301457 ret = -EINVAL;
1458 goto done;
1459 }
1460
1461 if (WLAN_HDD_SOFTAP == pHostapdAdapter->device_mode)
1462 {
Arif Hussaine7f3ea52013-09-12 21:56:36 -07001463 wlan_hdd_add_hostapd_conf_vsie(pHostapdAdapter, genie, &total_ielen);
Jeff Johnson295189b2012-06-20 16:38:30 -07001464 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001465
1466 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1467 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, genie, total_ielen, NULL,
1468 eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
1469 {
1470 hddLog(LOGE,
1471 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001472 ret = -EINVAL;
1473 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001474 }
1475
1476 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1477 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
1478 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
1479 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
1480 ==eHAL_STATUS_FAILURE)
1481 {
1482 hddLog(LOGE,
1483 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001484 ret = -EINVAL;
1485 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001486 }
1487
1488 // Added for ProResp IE
1489 if ( (params->proberesp_ies != NULL) && (params->proberesp_ies_len != 0) )
1490 {
1491 u16 rem_probe_resp_ie_len = params->proberesp_ies_len;
1492 u8 probe_rsp_ie_len[3] = {0};
1493 u8 counter = 0;
1494 /* Check Probe Resp Length if it is greater then 255 then Store
1495 Probe Resp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1 &
1496 WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are not able
1497 Store More then 255 bytes into One Variable.
1498 */
1499 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
1500 {
1501 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
1502 {
1503 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
1504 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
1505 }
1506 else
1507 {
1508 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
1509 rem_probe_resp_ie_len = 0;
1510 }
1511 }
1512
1513 rem_probe_resp_ie_len = 0;
1514
1515 if (probe_rsp_ie_len[0] > 0)
1516 {
1517 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1518 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
1519 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
1520 probe_rsp_ie_len[0], NULL,
1521 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
1522 {
1523 hddLog(LOGE,
1524 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001525 ret = -EINVAL;
1526 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001527 }
1528 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
1529 }
1530
1531 if (probe_rsp_ie_len[1] > 0)
1532 {
1533 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1534 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
1535 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
1536 probe_rsp_ie_len[1], NULL,
1537 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
1538 {
1539 hddLog(LOGE,
1540 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001541 ret = -EINVAL;
1542 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001543 }
1544 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
1545 }
1546
1547 if (probe_rsp_ie_len[2] > 0)
1548 {
1549 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1550 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
1551 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
1552 probe_rsp_ie_len[2], NULL,
1553 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
1554 {
1555 hddLog(LOGE,
1556 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001557 ret = -EINVAL;
1558 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001559 }
1560 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
1561 }
1562
1563 if (probe_rsp_ie_len[1] == 0 )
1564 {
1565 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1566 WNI_CFG_PROBE_RSP_ADDNIE_DATA2, (tANI_U8*)addIE, 0, NULL,
1567 eANI_BOOLEAN_FALSE) )
1568 {
1569 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08001570 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07001571 }
1572 }
1573
1574 if (probe_rsp_ie_len[2] == 0 )
1575 {
1576 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1577 WNI_CFG_PROBE_RSP_ADDNIE_DATA3, (tANI_U8*)addIE, 0, NULL,
1578 eANI_BOOLEAN_FALSE) )
1579 {
1580 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08001581 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07001582 }
1583 }
1584
1585 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1586 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
1587 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
1588 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
1589 == eHAL_STATUS_FAILURE)
1590 {
1591 hddLog(LOGE,
1592 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001593 ret = -EINVAL;
1594 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001595 }
1596 }
1597 else
1598 {
1599 // Reset WNI_CFG_PROBE_RSP Flags
1600 wlan_hdd_reset_prob_rspies(pHostapdAdapter);
1601
1602 hddLog(VOS_TRACE_LEVEL_INFO,
1603 "%s: No Probe Response IE received in set beacon",
1604 __func__);
1605 }
1606
1607 // Added for AssocResp IE
1608 if ( (params->assocresp_ies != NULL) && (params->assocresp_ies_len != 0) )
1609 {
1610 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1611 WNI_CFG_ASSOC_RSP_ADDNIE_DATA, (tANI_U8*)params->assocresp_ies,
1612 params->assocresp_ies_len, NULL,
1613 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
1614 {
1615 hddLog(LOGE,
1616 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001617 ret = -EINVAL;
1618 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001619 }
1620
1621 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1622 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 1, NULL,
1623 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
1624 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
1625 == eHAL_STATUS_FAILURE)
1626 {
1627 hddLog(LOGE,
1628 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001629 ret = -EINVAL;
1630 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001631 }
1632 }
1633 else
1634 {
1635 hddLog(VOS_TRACE_LEVEL_INFO,
1636 "%s: No Assoc Response IE received in set beacon",
1637 __func__);
1638
1639 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1640 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
1641 eANI_BOOLEAN_FALSE) )
1642 {
1643 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08001644 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07001645 }
1646 }
1647
Jeff Johnsone7245742012-09-05 17:12:55 -07001648done:
Jeff Johnson295189b2012-06-20 16:38:30 -07001649 vos_mem_free(genie);
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05301650 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07001651}
Jeff Johnson295189b2012-06-20 16:38:30 -07001652
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301653/*
Jeff Johnson295189b2012-06-20 16:38:30 -07001654 * FUNCTION: wlan_hdd_validate_operation_channel
1655 * called by wlan_hdd_cfg80211_start_bss() and
1656 * wlan_hdd_cfg80211_set_channel()
1657 * This function validates whether given channel is part of valid
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301658 * channel list.
1659 */
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07001660VOS_STATUS wlan_hdd_validate_operation_channel(hdd_adapter_t *pAdapter,int channel)
Jeff Johnson295189b2012-06-20 16:38:30 -07001661{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301662
Jeff Johnson295189b2012-06-20 16:38:30 -07001663 v_U32_t num_ch = 0;
1664 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN];
1665 u32 indx = 0;
1666 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05301667 v_U8_t fValidChannel = FALSE, count = 0;
1668 hdd_config_t *hdd_pConfig_ini= (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301669
Jeff Johnson295189b2012-06-20 16:38:30 -07001670 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
1671
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05301672 if ( hdd_pConfig_ini->sapAllowAllChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -07001673 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05301674 /* Validate the channel */
1675 for (count = RF_CHAN_1 ; count <= RF_CHAN_165 ; count++)
Jeff Johnson295189b2012-06-20 16:38:30 -07001676 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05301677 if ( channel == rfChannels[count].channelNum )
1678 {
1679 fValidChannel = TRUE;
1680 break;
1681 }
1682 }
1683 if (fValidChannel != TRUE)
1684 {
1685 hddLog(VOS_TRACE_LEVEL_ERROR,
1686 "%s: Invalid Channel [%d]", __func__, channel);
1687 return VOS_STATUS_E_FAILURE;
Jeff Johnson295189b2012-06-20 16:38:30 -07001688 }
1689 }
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05301690 else
Jeff Johnson295189b2012-06-20 16:38:30 -07001691 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05301692 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
1693 valid_ch, &num_ch))
1694 {
1695 hddLog(VOS_TRACE_LEVEL_ERROR,
1696 "%s: failed to get valid channel list", __func__);
1697 return VOS_STATUS_E_FAILURE;
1698 }
1699 for (indx = 0; indx < num_ch; indx++)
1700 {
1701 if (channel == valid_ch[indx])
1702 {
1703 break;
1704 }
1705 }
1706
Rashmi Ramanna3b59e122014-04-10 14:45:13 +05301707 if (indx >= num_ch)
1708 {
1709 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
1710 {
1711 eCsrBand band;
1712 unsigned int freq;
1713
1714 sme_GetFreqBand(hHal, &band);
1715
1716 if (eCSR_BAND_5G == band)
1717 {
1718#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
1719 if (channel <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
1720 {
1721 freq = ieee80211_channel_to_frequency(channel,
1722 IEEE80211_BAND_2GHZ);
1723 }
1724 else
1725 {
1726 freq = ieee80211_channel_to_frequency(channel,
1727 IEEE80211_BAND_5GHZ);
1728 }
1729#else
1730 freq = ieee80211_channel_to_frequency(channel);
1731#endif
1732 if(WLAN_HDD_IS_SOCIAL_CHANNEL(freq))
1733 return VOS_STATUS_SUCCESS;
1734 }
1735 }
1736
1737 hddLog(VOS_TRACE_LEVEL_ERROR,
1738 "%s: Invalid Channel [%d]", __func__, channel);
1739 return VOS_STATUS_E_FAILURE;
1740 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001741 }
Rashmi Ramanna3b59e122014-04-10 14:45:13 +05301742
Jeff Johnson295189b2012-06-20 16:38:30 -07001743 return VOS_STATUS_SUCCESS;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301744
Jeff Johnson295189b2012-06-20 16:38:30 -07001745}
1746
Viral Modi3a32cc52013-02-08 11:14:52 -08001747/**
1748 * FUNCTION: wlan_hdd_cfg80211_set_channel
1749 * This function is used to set the channel number
1750 */
1751static int wlan_hdd_cfg80211_set_channel( struct wiphy *wiphy, struct net_device *dev,
1752 struct ieee80211_channel *chan,
1753 enum nl80211_channel_type channel_type
1754 )
1755{
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05301756 hdd_adapter_t *pAdapter = NULL;
Viral Modi3a32cc52013-02-08 11:14:52 -08001757 v_U32_t num_ch = 0;
Jeff Johnson4416a782013-03-25 14:17:50 -07001758 int channel = 0;
Viral Modi3a32cc52013-02-08 11:14:52 -08001759 int freq = chan->center_freq; /* freq is in MHZ */
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05301760 hdd_context_t *pHddCtx;
1761 int status;
Viral Modi3a32cc52013-02-08 11:14:52 -08001762
1763 ENTER();
1764
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05301765
Viral Modi3a32cc52013-02-08 11:14:52 -08001766 if( NULL == dev )
1767 {
1768 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08001769 "%s: Called with dev = NULL.", __func__);
Viral Modi3a32cc52013-02-08 11:14:52 -08001770 return -ENODEV;
1771 }
1772 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
1773
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05301774 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
1775 TRACE_CODE_HDD_CFG80211_SET_CHANNEL, pAdapter->sessionId,
1776 channel_type ));
Viral Modi3a32cc52013-02-08 11:14:52 -08001777 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05301778 "%s: device_mode = %s (%d) freq = %d", __func__,
1779 hdd_device_modetoString(pAdapter->device_mode),
1780 pAdapter->device_mode, chan->center_freq);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05301781
1782 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1783 status = wlan_hdd_validate_context(pHddCtx);
1784
1785 if (0 != status)
Viral Modi3a32cc52013-02-08 11:14:52 -08001786 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05301787 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1788 "%s: HDD context is not valid", __func__);
1789 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -08001790 }
1791
1792 /*
1793 * Do freq to chan conversion
1794 * TODO: for 11a
1795 */
1796
1797 channel = ieee80211_frequency_to_channel(freq);
1798
1799 /* Check freq range */
1800 if ((WNI_CFG_CURRENT_CHANNEL_STAMIN > channel) ||
1801 (WNI_CFG_CURRENT_CHANNEL_STAMAX < channel))
1802 {
1803 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08001804 "%s: Channel [%d] is outside valid range from %d to %d",
Viral Modi3a32cc52013-02-08 11:14:52 -08001805 __func__, channel, WNI_CFG_CURRENT_CHANNEL_STAMIN,
1806 WNI_CFG_CURRENT_CHANNEL_STAMAX);
1807 return -EINVAL;
1808 }
1809
1810 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
1811
Gopichand Nakkala6ab19562013-03-07 13:59:42 +05301812 if ((WLAN_HDD_SOFTAP != pAdapter->device_mode) &&
1813 (WLAN_HDD_P2P_GO != pAdapter->device_mode))
Viral Modi3a32cc52013-02-08 11:14:52 -08001814 {
1815 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pAdapter,channel))
1816 {
1817 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08001818 "%s: Invalid Channel [%d]", __func__, channel);
Viral Modi3a32cc52013-02-08 11:14:52 -08001819 return -EINVAL;
1820 }
1821 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
1822 "%s: set channel to [%d] for device mode =%d",
1823 __func__, channel,pAdapter->device_mode);
1824 }
1825 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Viral Modi3a32cc52013-02-08 11:14:52 -08001826 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Viral Modi3a32cc52013-02-08 11:14:52 -08001827 )
1828 {
1829 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
1830 tCsrRoamProfile * pRoamProfile = &pWextState->roamProfile;
1831 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
1832
1833 if (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState)
1834 {
1835 /* Link is up then return cant set channel*/
1836 hddLog( VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08001837 "%s: IBSS Associated, can't set the channel", __func__);
Viral Modi3a32cc52013-02-08 11:14:52 -08001838 return -EINVAL;
1839 }
1840
1841 num_ch = pRoamProfile->ChannelInfo.numOfChannels = 1;
1842 pHddStaCtx->conn_info.operationChannel = channel;
1843 pRoamProfile->ChannelInfo.ChannelList =
1844 &pHddStaCtx->conn_info.operationChannel;
1845 }
1846 else if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Viral Modi3a32cc52013-02-08 11:14:52 -08001847 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Viral Modi3a32cc52013-02-08 11:14:52 -08001848 )
1849 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05301850 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
1851 {
1852 if(VOS_STATUS_SUCCESS !=
1853 wlan_hdd_validate_operation_channel(pAdapter,channel))
1854 {
1855 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08001856 "%s: Invalid Channel [%d]", __func__, channel);
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05301857 return -EINVAL;
1858 }
1859 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
1860 }
1861 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
Viral Modi3a32cc52013-02-08 11:14:52 -08001862 {
1863 hdd_config_t *cfg_param = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
1864
1865 /* If auto channel selection is configured as enable/ 1 then ignore
1866 channel set by supplicant
1867 */
1868 if ( cfg_param->apAutoChannelSelection )
1869 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05301870 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel =
1871 AUTO_CHANNEL_SELECT;
Viral Modi3a32cc52013-02-08 11:14:52 -08001872 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05301873 "%s: set channel to auto channel (0) for device mode =%s (%d)",
1874 __func__, hdd_device_modetoString(pAdapter->device_mode),
1875 pAdapter->device_mode);
Viral Modi3a32cc52013-02-08 11:14:52 -08001876 }
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05301877 else
1878 {
1879 if(VOS_STATUS_SUCCESS !=
1880 wlan_hdd_validate_operation_channel(pAdapter,channel))
1881 {
1882 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08001883 "%s: Invalid Channel [%d]", __func__, channel);
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05301884 return -EINVAL;
1885 }
1886 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
1887 }
Viral Modi3a32cc52013-02-08 11:14:52 -08001888 }
1889 }
1890 else
1891 {
1892 hddLog(VOS_TRACE_LEVEL_FATAL,
1893 "%s: Invalid device mode failed to set valid channel", __func__);
1894 return -EINVAL;
1895 }
1896 EXIT();
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05301897 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -08001898}
1899
Jeff Johnson295189b2012-06-20 16:38:30 -07001900#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
1901static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
1902 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001903#else
1904static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
1905 struct cfg80211_beacon_data *params,
1906 const u8 *ssid, size_t ssid_len,
1907 enum nl80211_hidden_ssid hidden_ssid)
1908#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07001909{
1910 tsap_Config_t *pConfig;
1911 beacon_data_t *pBeacon = NULL;
1912 struct ieee80211_mgmt *pMgmt_frame;
1913 v_U8_t *pIe=NULL;
1914 v_U16_t capab_info;
1915 eCsrAuthType RSNAuthType;
1916 eCsrEncryptionType RSNEncryptType;
1917 eCsrEncryptionType mcRSNEncryptType;
1918 int status = VOS_STATUS_SUCCESS;
1919 tpWLAN_SAPEventCB pSapEventCallback;
1920 hdd_hostapd_state_t *pHostapdState;
1921 v_U8_t wpaRsnIEdata[(SIR_MAC_MAX_IE_LENGTH * 2)+4]; //Max ie length 255 * 2(WPA+RSN) + 2 bytes (vendor specific ID) * 2
1922 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05301923 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07001924 struct qc_mac_acl_entry *acl_entry = NULL;
1925 v_SINT_t i;
Madan Mohan Koyyalamudi543172b2012-12-05 16:40:18 -08001926 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
Chet Lanctot8cecea22014-02-11 19:09:36 -08001927 v_BOOL_t MFPCapable;
1928 v_BOOL_t MFPRequired;
Abhishek Singhf0ac1752014-03-05 17:47:09 +05301929 eHddDot11Mode sapDot11Mode =
1930 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->sapDot11Mode;
Jeff Johnson295189b2012-06-20 16:38:30 -07001931
1932 ENTER();
1933
1934 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter);
1935
1936 pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
1937
1938 pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
1939
1940 pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
1941
1942 pConfig->beacon_int = pMgmt_frame->u.beacon.beacon_int;
1943
1944 //channel is already set in the set_channel Call back
1945 //pConfig->channel = pCommitConfig->channel;
1946
1947 /*Protection parameter to enable or disable*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301948 pConfig->protEnabled =
Jeff Johnson295189b2012-06-20 16:38:30 -07001949 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtEnabled;
1950
1951 pConfig->dtim_period = pBeacon->dtim_period;
1952
Arif Hussain6d2a3322013-11-17 19:50:10 -08001953 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"****pConfig->dtim_period=%d***",
Jeff Johnson295189b2012-06-20 16:38:30 -07001954 pConfig->dtim_period);
1955
1956
Madan Mohan Koyyalamudie0ca11f2012-11-27 15:57:52 -08001957 if (pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson32d95a32012-09-10 13:15:23 -07001958 {
1959 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -07001960 WLAN_EID_COUNTRY);
Kiet Lam083504c2013-11-25 14:17:45 +05301961 if(memcmp(pHddCtx->cfg_ini->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0)
1962 {
1963 tANI_BOOLEAN restartNeeded;
1964 pConfig->ieee80211d = 1;
1965 vos_mem_copy(pConfig->countryCode, pHddCtx->cfg_ini->apCntryCode, 3);
1966 sme_setRegInfo(hHal, pConfig->countryCode);
1967 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
1968 }
1969 else if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07001970 {
Jeff Johnson32d95a32012-09-10 13:15:23 -07001971 tANI_BOOLEAN restartNeeded;
Jeff Johnson32d95a32012-09-10 13:15:23 -07001972 pConfig->ieee80211d = 1;
1973 vos_mem_copy(pConfig->countryCode, &pIe[2], 3);
1974 sme_setRegInfo(hHal, pConfig->countryCode);
1975 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
Jeff Johnson295189b2012-06-20 16:38:30 -07001976 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07001977 else
1978 {
1979 pConfig->ieee80211d = 0;
1980 }
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05301981 /*
1982 * If auto channel is configured i.e. channel is 0,
1983 * so skip channel validation.
1984 */
1985 if( AUTO_CHANNEL_SELECT != pConfig->channel )
1986 {
1987 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pHostapdAdapter,pConfig->channel))
1988 {
1989 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08001990 "%s: Invalid Channel [%d]", __func__, pConfig->channel);
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05301991 return -EINVAL;
1992 }
1993 }
1994 else
1995 {
1996 if(1 != pHddCtx->is_dynamic_channel_range_set)
1997 {
1998 hdd_config_t *hdd_pConfig= (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini;
1999 WLANSAP_SetChannelRange(hHal, hdd_pConfig->apStartChannelNum,
2000 hdd_pConfig->apEndChannelNum,hdd_pConfig->apOperatingBand);
2001 }
2002 pHddCtx->is_dynamic_channel_range_set = 0;
2003 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002004 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07002005 else
Jeff Johnson295189b2012-06-20 16:38:30 -07002006 {
2007 pConfig->ieee80211d = 0;
2008 }
2009 pConfig->authType = eSAP_AUTO_SWITCH;
2010
2011 capab_info = pMgmt_frame->u.beacon.capab_info;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302012
2013 pConfig->privacy = (pMgmt_frame->u.beacon.capab_info &
Jeff Johnson295189b2012-06-20 16:38:30 -07002014 WLAN_CAPABILITY_PRIVACY) ? VOS_TRUE : VOS_FALSE;
2015
2016 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uPrivacy = pConfig->privacy;
2017
2018 /*Set wps station to configured*/
2019 pIe = wlan_hdd_get_wps_ie_ptr(pBeacon->tail, pBeacon->tail_len);
2020
2021 if(pIe)
2022 {
2023 if(pIe[1] < (2 + WPS_OUI_TYPE_SIZE))
2024 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08002025 hddLog( VOS_TRACE_LEVEL_ERROR, "**Wps Ie Length is too small***");
Jeff Johnson295189b2012-06-20 16:38:30 -07002026 return -EINVAL;
2027 }
2028 else if(memcmp(&pIe[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) == 0)
2029 {
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07002030 hddLog( VOS_TRACE_LEVEL_INFO, "** WPS IE(len %d) ***", (pIe[1]+2));
Jeff Johnson295189b2012-06-20 16:38:30 -07002031 /* Check 15 bit of WPS IE as it contain information for wps state
2032 * WPS state
2033 */
2034 if(SAP_WPS_ENABLED_UNCONFIGURED == pIe[15])
2035 {
2036 pConfig->wps_state = SAP_WPS_ENABLED_UNCONFIGURED;
2037 } else if(SAP_WPS_ENABLED_CONFIGURED == pIe[15])
2038 {
2039 pConfig->wps_state = SAP_WPS_ENABLED_CONFIGURED;
2040 }
2041 }
2042 }
2043 else
2044 {
2045 pConfig->wps_state = SAP_WPS_DISABLED;
2046 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302047 pConfig->fwdWPSPBCProbeReq = 1; // Forward WPS PBC probe request frame up
Jeff Johnson295189b2012-06-20 16:38:30 -07002048
2049 pConfig->RSNWPAReqIELength = 0;
2050 pConfig->pRSNWPAReqIE = NULL;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302051 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -07002052 WLAN_EID_RSN);
2053 if(pIe && pIe[1])
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302054 {
Jeff Johnson295189b2012-06-20 16:38:30 -07002055 pConfig->RSNWPAReqIELength = pIe[1] + 2;
2056 memcpy(&wpaRsnIEdata[0], pIe, pConfig->RSNWPAReqIELength);
2057 pConfig->pRSNWPAReqIE = &wpaRsnIEdata[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302058 /* The actual processing may eventually be more extensive than
2059 * this. Right now, just consume any PMKIDs that are sent in
Jeff Johnson295189b2012-06-20 16:38:30 -07002060 * by the app.
2061 * */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302062 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -07002063 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
2064 &RSNEncryptType,
2065 &mcRSNEncryptType,
2066 &RSNAuthType,
Chet Lanctot8cecea22014-02-11 19:09:36 -08002067 &MFPCapable,
2068 &MFPRequired,
Jeff Johnson295189b2012-06-20 16:38:30 -07002069 pConfig->pRSNWPAReqIE[1]+2,
2070 pConfig->pRSNWPAReqIE );
2071
2072 if( VOS_STATUS_SUCCESS == status )
2073 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302074 /* Now copy over all the security attributes you have
2075 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -07002076 * */
2077 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
2078 pConfig->mcRSNEncryptType = mcRSNEncryptType;
2079 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
2080 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05302081 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -08002082 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -07002083 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
2084 }
2085 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302086
Jeff Johnson295189b2012-06-20 16:38:30 -07002087 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE,
2088 pBeacon->tail, pBeacon->tail_len);
2089
2090 if(pIe && pIe[1] && (pIe[0] == DOT11F_EID_WPA))
2091 {
2092 if (pConfig->pRSNWPAReqIE)
2093 {
2094 /*Mixed mode WPA/WPA2*/
2095 memcpy((&wpaRsnIEdata[0] + pConfig->RSNWPAReqIELength), pIe, pIe[1] + 2);
2096 pConfig->RSNWPAReqIELength += pIe[1] + 2;
2097 }
2098 else
2099 {
2100 pConfig->RSNWPAReqIELength = pIe[1] + 2;
2101 memcpy(&wpaRsnIEdata[0], pIe, pConfig->RSNWPAReqIELength);
2102 pConfig->pRSNWPAReqIE = &wpaRsnIEdata[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302103 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -07002104 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
2105 &RSNEncryptType,
2106 &mcRSNEncryptType,
2107 &RSNAuthType,
Chet Lanctot8cecea22014-02-11 19:09:36 -08002108 &MFPCapable,
2109 &MFPRequired,
Jeff Johnson295189b2012-06-20 16:38:30 -07002110 pConfig->pRSNWPAReqIE[1]+2,
2111 pConfig->pRSNWPAReqIE );
2112
2113 if( VOS_STATUS_SUCCESS == status )
2114 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302115 /* Now copy over all the security attributes you have
2116 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -07002117 * */
2118 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
2119 pConfig->mcRSNEncryptType = mcRSNEncryptType;
2120 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
2121 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05302122 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -08002123 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -07002124 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
2125 }
2126 }
2127 }
2128
Jeff Johnson4416a782013-03-25 14:17:50 -07002129 if (pConfig->RSNWPAReqIELength > sizeof wpaRsnIEdata) {
2130 hddLog( VOS_TRACE_LEVEL_ERROR, "**RSNWPAReqIELength is too large***");
2131 return -EINVAL;
2132 }
2133
Jeff Johnson295189b2012-06-20 16:38:30 -07002134 pConfig->SSIDinfo.ssidHidden = VOS_FALSE;
2135
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002136#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07002137 if (params->ssid != NULL)
2138 {
2139 memcpy(pConfig->SSIDinfo.ssid.ssId, params->ssid, params->ssid_len);
2140 pConfig->SSIDinfo.ssid.length = params->ssid_len;
2141 if (params->hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
2142 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
2143 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002144#else
2145 if (ssid != NULL)
2146 {
2147 memcpy(pConfig->SSIDinfo.ssid.ssId, ssid, ssid_len);
2148 pConfig->SSIDinfo.ssid.length = ssid_len;
2149 if (hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
2150 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
2151 }
2152#endif
2153
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302154 vos_mem_copy(pConfig->self_macaddr.bytes,
Jeff Johnson295189b2012-06-20 16:38:30 -07002155 pHostapdAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302156
Jeff Johnson295189b2012-06-20 16:38:30 -07002157 /* default value */
2158 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
2159 pConfig->num_accept_mac = 0;
2160 pConfig->num_deny_mac = 0;
2161
2162 pIe = wlan_hdd_get_vendor_oui_ie_ptr(BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
2163 pBeacon->tail, pBeacon->tail_len);
2164
2165 /* pIe for black list is following form:
2166 type : 1 byte
2167 length : 1 byte
2168 OUI : 4 bytes
2169 acl type : 1 byte
2170 no of mac addr in black list: 1 byte
2171 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302172 */
2173 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07002174 {
2175 pConfig->SapMacaddr_acl = pIe[6];
2176 pConfig->num_deny_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -08002177 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no deny mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07002178 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05302179 if (pConfig->num_deny_mac > MAX_ACL_MAC_ADDRESS)
2180 pConfig->num_deny_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07002181 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
2182 for (i = 0; i < pConfig->num_deny_mac; i++)
2183 {
2184 vos_mem_copy(&pConfig->deny_mac[i], acl_entry->addr, sizeof(qcmacaddr));
2185 acl_entry++;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302186 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002187 }
2188 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
2189 pBeacon->tail, pBeacon->tail_len);
2190
2191 /* pIe for white list is following form:
2192 type : 1 byte
2193 length : 1 byte
2194 OUI : 4 bytes
2195 acl type : 1 byte
2196 no of mac addr in white list: 1 byte
2197 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302198 */
2199 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07002200 {
2201 pConfig->SapMacaddr_acl = pIe[6];
2202 pConfig->num_accept_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -08002203 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no accept mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07002204 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05302205 if (pConfig->num_accept_mac > MAX_ACL_MAC_ADDRESS)
2206 pConfig->num_accept_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07002207 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
2208 for (i = 0; i < pConfig->num_accept_mac; i++)
2209 {
2210 vos_mem_copy(&pConfig->accept_mac[i], acl_entry->addr, sizeof(qcmacaddr));
2211 acl_entry++;
2212 }
2213 }
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05302214
Jeff Johnson295189b2012-06-20 16:38:30 -07002215 wlan_hdd_set_sapHwmode(pHostapdAdapter);
2216
Jeff Johnsone7245742012-09-05 17:12:55 -07002217#ifdef WLAN_FEATURE_11AC
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -08002218 /* Overwrite the hostapd setting for HW mode only for 11ac.
Kiet Lam0f320422013-11-21 19:29:17 +05302219 * This is valid only if mode is set to 11n in hostapd, either AUTO or
2220 * 11ac in .ini and 11ac is supported by both host and firmware.
2221 * Otherwise, leave whatever is set in hostapd (a OR b OR g OR n mode)
2222 */
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -08002223 if( ((pConfig->SapHw_mode == eSAP_DOT11_MODE_11n) ||
2224 (pConfig->SapHw_mode == eSAP_DOT11_MODE_11n_ONLY)) &&
Abhishek Singhf0ac1752014-03-05 17:47:09 +05302225 (( sapDot11Mode == eHDD_DOT11_MODE_AUTO ) ||
2226 ( sapDot11Mode == eHDD_DOT11_MODE_11ac ) ||
2227 ( sapDot11Mode == eHDD_DOT11_MODE_11ac_ONLY ) ) &&
2228 (sme_IsFeatureSupportedByDriver(DOT11AC)) &&
2229 (sme_IsFeatureSupportedByFW(DOT11AC)) )
Jeff Johnsone7245742012-09-05 17:12:55 -07002230 {
2231 pConfig->SapHw_mode = eSAP_DOT11_MODE_11ac;
Ravi Joshi83bfaa12013-05-28 22:12:08 -07002232
Rashmi Ramanna3b59e122014-04-10 14:45:13 +05302233 /* Disable VHT support in 2.4 GHz and */
Ravi Joshi83bfaa12013-05-28 22:12:08 -07002234 if (pConfig->channel <= 14 &&
2235 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->enableVhtFor24GHzBand == FALSE)
2236 {
2237 pConfig->SapHw_mode = eSAP_DOT11_MODE_11n;
2238 }
Jeff Johnsone7245742012-09-05 17:12:55 -07002239 }
2240#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302241
Ravi Joshiaeb7d9e2013-05-02 12:28:14 -07002242 if ( AUTO_CHANNEL_SELECT != pConfig->channel )
2243 {
2244 sme_SelectCBMode(hHal,
2245 sapConvertSapPhyModeToCsrPhyMode(pConfig->SapHw_mode),
2246 pConfig->channel);
2247 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002248 // ht_capab is not what the name conveys,this is used for protection bitmap
2249 pConfig->ht_capab =
2250 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtection;
2251
2252 if ( 0 != wlan_hdd_cfg80211_update_apies(pHostapdAdapter, params) )
2253 {
2254 hddLog(LOGE, FL("SAP Not able to set AP IEs"));
2255 return -EINVAL;
2256 }
2257
2258 //Uapsd Enabled Bit
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302259 pConfig->UapsdEnable =
Jeff Johnson295189b2012-06-20 16:38:30 -07002260 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apUapsdEnabled;
2261 //Enable OBSS protection
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302262 pConfig->obssProtEnabled =
2263 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apOBSSProtEnabled;
Jeff Johnson295189b2012-06-20 16:38:30 -07002264
Chet Lanctot8cecea22014-02-11 19:09:36 -08002265#ifdef WLAN_FEATURE_11W
2266 pConfig->mfpCapable = MFPCapable;
2267 pConfig->mfpRequired = MFPRequired;
2268 hddLog(LOGW, FL("Soft AP MFP capable %d, MFP required %d\n"),
2269 pConfig->mfpCapable, pConfig->mfpRequired);
2270#endif
2271
Arif Hussain6d2a3322013-11-17 19:50:10 -08002272 hddLog(LOGW, FL("SOftAP macaddress : "MAC_ADDRESS_STR),
Jeff Johnson295189b2012-06-20 16:38:30 -07002273 MAC_ADDR_ARRAY(pHostapdAdapter->macAddressCurrent.bytes));
Arif Hussain6d2a3322013-11-17 19:50:10 -08002274 hddLog(LOGW,FL("ssid =%s, beaconint=%d, channel=%d"),
2275 pConfig->SSIDinfo.ssid.ssId, (int)pConfig->beacon_int,
2276 (int)pConfig->channel);
2277 hddLog(LOGW,FL("hw_mode=%x, privacy=%d, authType=%d"),
2278 pConfig->SapHw_mode, pConfig->privacy,
2279 pConfig->authType);
2280 hddLog(LOGW,FL("RSN/WPALen=%d, Uapsd = %d"),
2281 (int)pConfig->RSNWPAReqIELength, pConfig->UapsdEnable);
2282 hddLog(LOGW,FL("ProtEnabled = %d, OBSSProtEnabled = %d"),
2283 pConfig->protEnabled, pConfig->obssProtEnabled);
Jeff Johnson295189b2012-06-20 16:38:30 -07002284
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302285 if(test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -07002286 {
2287 //Bss already started. just return.
2288 //TODO Probably it should update some beacon params.
2289 hddLog( LOGE, "Bss Already started...Ignore the request");
2290 EXIT();
2291 return 0;
2292 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302293
Jeff Johnson295189b2012-06-20 16:38:30 -07002294 pConfig->persona = pHostapdAdapter->device_mode;
2295
2296 pSapEventCallback = hdd_hostapd_SAPEventCB;
2297 if(WLANSAP_StartBss(pVosContext, pSapEventCallback, pConfig,
2298 (v_PVOID_t)pHostapdAdapter->dev) != VOS_STATUS_SUCCESS)
2299 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08002300 hddLog(LOGE,FL("SAP Start Bss fail"));
Jeff Johnson295189b2012-06-20 16:38:30 -07002301 return -EINVAL;
2302 }
2303
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302304 hddLog(LOG1,
Jeff Johnson295189b2012-06-20 16:38:30 -07002305 FL("Waiting for Scan to complete(auto mode) and BSS to start"));
2306
2307 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302308
Jeff Johnson295189b2012-06-20 16:38:30 -07002309 if (!VOS_IS_STATUS_SUCCESS(status))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302310 {
2311 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08002312 ("ERROR: HDD vos wait for single_event failed!!"));
Tushnim Bhattacharyyaad37df12013-10-02 12:01:33 -07002313 smeGetCommandQStatus(hHal);
Jeff Johnson295189b2012-06-20 16:38:30 -07002314 VOS_ASSERT(0);
2315 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302316
Jeff Johnson295189b2012-06-20 16:38:30 -07002317 set_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags);
2318
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07002319#ifdef WLAN_FEATURE_P2P_DEBUG
2320 if (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO)
2321 {
2322 if(globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED)
2323 {
2324 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
2325 hddLog(LOGE,"[P2P State] From Go nego completed to "
Jeff Johnson1250df42012-12-10 14:31:52 -08002326 "Non-autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07002327 }
2328 else if(globalP2PConnectionStatus == P2P_NOT_ACTIVE)
2329 {
2330 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
2331 hddLog(LOGE,"[P2P State] From Inactive to "
Jeff Johnson1250df42012-12-10 14:31:52 -08002332 "Autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07002333 }
2334 }
2335#endif
2336
Jeff Johnson295189b2012-06-20 16:38:30 -07002337 pHostapdState->bCommit = TRUE;
2338 EXIT();
2339
2340 return 0;
2341}
2342
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002343#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302344static int wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy,
2345 struct net_device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -07002346 struct beacon_parameters *params)
2347{
2348 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302349 hdd_context_t *pHddCtx;
2350 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07002351
2352 ENTER();
2353
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302354 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2355 TRACE_CODE_HDD_CFG80211_ADD_BEACON,
2356 pAdapter->sessionId, params->interval));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05302357 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "device mode=%s (%d)",
2358 hdd_device_modetoString(pAdapter->device_mode),
2359 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07002360
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302361 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2362 status = wlan_hdd_validate_context(pHddCtx);
2363
2364 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002365 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302366 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2367 "%s: HDD context is not valid", __func__);
2368 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002369 }
2370
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302371 if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07002372 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07002373 )
2374 {
2375 beacon_data_t *old,*new;
2376
2377 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302378
Jeff Johnson295189b2012-06-20 16:38:30 -07002379 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302380 {
2381 hddLog(VOS_TRACE_LEVEL_WARN,
2382 FL("already beacon info added to session(%d)"),
2383 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07002384 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302385 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002386
2387 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
2388
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302389 if(status != VOS_STATUS_SUCCESS)
Jeff Johnson295189b2012-06-20 16:38:30 -07002390 {
2391 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08002392 "%s:Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002393 return -EINVAL;
2394 }
2395
2396 pAdapter->sessionCtx.ap.beacon = new;
2397
2398 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
2399 }
2400
2401 EXIT();
2402 return status;
2403}
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302404
2405static int wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07002406 struct net_device *dev,
2407 struct beacon_parameters *params)
2408{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302409 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302410 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302411 hdd_context_t *pHddCtx;
2412 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07002413
2414 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302415 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2416 TRACE_CODE_HDD_CFG80211_SET_BEACON,
2417 pAdapter->sessionId, pHddStaCtx->conn_info.authType));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05302418 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
2419 __func__, hdd_device_modetoString(pAdapter->device_mode),
2420 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07002421
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302422 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2423 status = wlan_hdd_validate_context(pHddCtx);
2424
2425 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002426 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302427 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2428 "%s: HDD context is not valid", __func__);
2429 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002430 }
2431
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302432 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07002433 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302434 )
Jeff Johnson295189b2012-06-20 16:38:30 -07002435 {
2436 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302437
Jeff Johnson295189b2012-06-20 16:38:30 -07002438 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302439
Jeff Johnson295189b2012-06-20 16:38:30 -07002440 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302441 {
2442 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2443 FL("session(%d) old and new heads points to NULL"),
2444 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07002445 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302446 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002447
2448 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
2449
2450 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302451 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08002452 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002453 return -EINVAL;
2454 }
2455
2456 pAdapter->sessionCtx.ap.beacon = new;
2457
2458 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
2459 }
2460
2461 EXIT();
2462 return status;
2463}
2464
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002465#endif //(LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
2466
2467#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07002468static int wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy,
2469 struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002470#else
2471static int wlan_hdd_cfg80211_stop_ap (struct wiphy *wiphy,
2472 struct net_device *dev)
2473#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07002474{
2475 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnsone7245742012-09-05 17:12:55 -07002476 hdd_context_t *pHddCtx = NULL;
2477 hdd_scaninfo_t *pScanInfo = NULL;
2478 hdd_adapter_t *staAdapter = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302479 VOS_STATUS status;
Jeff Johnson295189b2012-06-20 16:38:30 -07002480
2481 ENTER();
2482
2483 if (NULL == pAdapter)
2484 {
2485 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002486 "%s: HDD adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002487 return -ENODEV;
2488 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07002489
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302490 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2491 TRACE_CODE_HDD_CFG80211_STOP_AP,
2492 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302493 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2494 status = wlan_hdd_validate_context(pHddCtx);
2495
2496 if (0 != status)
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07002497 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302498 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2499 "%s: HDD context is not valid", __func__);
2500 return status;
Jeff Johnson4416a782013-03-25 14:17:50 -07002501 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07002502
2503 staAdapter = hdd_get_adapter(pAdapter->pHddCtx, WLAN_HDD_INFRA_STATION);
2504 if (NULL == staAdapter)
2505 {
2506 staAdapter = hdd_get_adapter(pAdapter->pHddCtx, WLAN_HDD_P2P_CLIENT);
2507 if (NULL == staAdapter)
2508 {
Rajesh Chauhan52d885b2013-11-01 10:54:25 -07002509 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
2510 "%s: HDD adapter context for STA/P2P-CLI is Null",
2511 __func__);
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07002512 }
2513 }
2514
2515 pScanInfo = &pHddCtx->scan_info;
2516
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05302517 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
2518 __func__, hdd_device_modetoString(pAdapter->device_mode),
2519 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07002520
Rajesh Chauhan52d885b2013-11-01 10:54:25 -07002521 if ((pScanInfo != NULL) && pScanInfo->mScanPending && staAdapter)
Jeff Johnsone7245742012-09-05 17:12:55 -07002522 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302523 long ret;
2524
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -08002525 INIT_COMPLETION(pScanInfo->abortscan_event_var);
Srinivas, Dasari138af4f2014-02-07 11:13:45 +05302526 hdd_abort_mac_scan(staAdapter->pHddCtx, pAdapter->sessionId,
2527 eCSR_SCAN_ABORT_DEFAULT);
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302528 ret = wait_for_completion_interruptible_timeout(
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -08002529 &pScanInfo->abortscan_event_var,
Jeff Johnsone7245742012-09-05 17:12:55 -07002530 msecs_to_jiffies(WLAN_WAIT_TIME_ABORTSCAN));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302531 if (ret <= 0)
Jeff Johnsone7245742012-09-05 17:12:55 -07002532 {
Rajesh Chauhan52d885b2013-11-01 10:54:25 -07002533 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302534 FL("Timeout occurred while waiting for abortscan %ld"),
2535 ret);
Yue Ma4f55ef32014-01-23 16:45:33 -08002536
2537 if (pHddCtx->isLogpInProgress)
2538 {
2539 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2540 "%s: LOGP in Progress. Ignore!!!", __func__);
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302541
2542 VOS_ASSERT(pScanInfo->mScanPending);
Yue Ma4f55ef32014-01-23 16:45:33 -08002543 return -EAGAIN;
2544 }
Jeff Johnsone7245742012-09-05 17:12:55 -07002545 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -07002546 }
2547 }
2548
Arun Kumar Khandavallia3bd8002014-01-17 16:21:19 +05302549 hdd_hostapd_stop(dev);
2550
Jeff Johnson295189b2012-06-20 16:38:30 -07002551 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07002552 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07002553 )
2554 {
2555 beacon_data_t *old;
2556
2557 old = pAdapter->sessionCtx.ap.beacon;
2558
2559 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302560 {
2561 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2562 FL("session(%d) beacon data points to NULL"),
2563 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07002564 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302565 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002566
Jeff Johnson295189b2012-06-20 16:38:30 -07002567 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07002568
2569 mutex_lock(&pHddCtx->sap_lock);
2570 if(test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
2571 {
Jeff Johnson4416a782013-03-25 14:17:50 -07002572 if ( VOS_STATUS_SUCCESS == (status = WLANSAP_StopBss(pHddCtx->pvosContext) ) )
Jeff Johnson295189b2012-06-20 16:38:30 -07002573 {
2574 hdd_hostapd_state_t *pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
2575
2576 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
2577
2578 if (!VOS_IS_STATUS_SUCCESS(status))
2579 {
2580 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08002581 ("ERROR: HDD vos wait for single_event failed!!"));
Jeff Johnson295189b2012-06-20 16:38:30 -07002582 VOS_ASSERT(0);
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302583 }
2584 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002585 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
2586 }
2587 mutex_unlock(&pHddCtx->sap_lock);
2588
2589 if(status != VOS_STATUS_SUCCESS)
2590 {
2591 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08002592 "%s:Error!!! Stopping the BSS",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002593 return -EINVAL;
2594 }
2595
Jeff Johnson4416a782013-03-25 14:17:50 -07002596 if (ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -07002597 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 0,NULL, eANI_BOOLEAN_FALSE)
2598 ==eHAL_STATUS_FAILURE)
2599 {
2600 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08002601 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07002602 }
2603
Jeff Johnson4416a782013-03-25 14:17:50 -07002604 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -07002605 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
2606 eANI_BOOLEAN_FALSE) )
2607 {
2608 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08002609 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07002610 }
2611
2612 // Reset WNI_CFG_PROBE_RSP Flags
2613 wlan_hdd_reset_prob_rspies(pAdapter);
2614
2615 pAdapter->sessionCtx.ap.beacon = NULL;
2616 kfree(old);
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07002617#ifdef WLAN_FEATURE_P2P_DEBUG
2618 if((pAdapter->device_mode == WLAN_HDD_P2P_GO) &&
2619 (globalP2PConnectionStatus == P2P_GO_COMPLETED_STATE))
2620 {
2621 hddLog(LOGE,"[P2P State] From GO completed to Inactive state "
2622 "GO got removed");
2623 globalP2PConnectionStatus = P2P_NOT_ACTIVE;
2624 }
2625#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07002626 }
2627 EXIT();
2628 return status;
2629}
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002630
2631#if (LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
2632
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302633static int wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
2634 struct net_device *dev,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002635 struct cfg80211_ap_settings *params)
2636{
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302637 hdd_adapter_t *pAdapter;
2638 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302639 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002640
2641 ENTER();
2642
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302643 if (NULL == dev)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07002644 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302645 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302646 "%s: Device is Null", __func__);
2647 return -ENODEV;
2648 }
2649
2650 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2651 if (NULL == pAdapter)
2652 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302653 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302654 "%s: HDD adapter is Null", __func__);
2655 return -ENODEV;
2656 }
2657
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302658 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2659 TRACE_CODE_HDD_CFG80211_START_AP, pAdapter->sessionId,
2660 params-> beacon_interval));
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302661 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
2662 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302663 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302664 "%s: HDD adapter magic is invalid", __func__);
2665 return -ENODEV;
2666 }
2667
2668 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302669 status = wlan_hdd_validate_context(pHddCtx);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302670
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302671 if (0 != status)
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302672 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302673 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2674 "%s: HDD context is not valid", __func__);
2675 return status;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302676 }
2677
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05302678 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device mode = %s (%d)",
2679 __func__, hdd_device_modetoString(pAdapter->device_mode),
2680 pAdapter->device_mode);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302681
2682 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002683 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002684 )
2685 {
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302686 beacon_data_t *old, *new;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002687
2688 old = pAdapter->sessionCtx.ap.beacon;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302689
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002690 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302691 {
2692 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
2693 FL("already beacon info added to session(%d)"),
2694 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002695 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302696 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002697
2698 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter, &new, &params->beacon, params->dtim_period);
2699
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302700 if (status != 0)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002701 {
2702 hddLog(VOS_TRACE_LEVEL_FATAL,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302703 "%s:Error!!! Allocating the new beacon", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002704 return -EINVAL;
2705 }
2706 pAdapter->sessionCtx.ap.beacon = new;
Viral Modi3a32cc52013-02-08 11:14:52 -08002707#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
Yue Maf49ba872013-08-19 12:04:25 -07002708 wlan_hdd_cfg80211_set_channel(wiphy, dev,
2709#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
2710 params->channel, params->channel_type);
2711#else
2712 params->chandef.chan, cfg80211_get_chandef_type(&(params->chandef)));
2713#endif
Viral Modi3a32cc52013-02-08 11:14:52 -08002714#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002715 status = wlan_hdd_cfg80211_start_bss(pAdapter, &params->beacon, params->ssid,
2716 params->ssid_len, params->hidden_ssid);
2717 }
2718
2719 EXIT();
2720 return status;
2721}
2722
2723
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302724static int wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002725 struct net_device *dev,
2726 struct cfg80211_beacon_data *params)
2727{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302728 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302729 hdd_context_t *pHddCtx;
2730 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002731
2732 ENTER();
2733
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302734 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2735 TRACE_CODE_HDD_CFG80211_CHANGE_BEACON,
2736 pAdapter->sessionId, pAdapter->device_mode));
Arif Hussain6d2a3322013-11-17 19:50:10 -08002737 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002738 __func__, pAdapter->device_mode);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302739
2740 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2741 status = wlan_hdd_validate_context(pHddCtx);
2742
2743 if (0 != status)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07002744 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302745 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2746 "%s: HDD context is not valid", __func__);
2747 return status;
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07002748 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002749
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302750 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002751 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302752 )
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002753 {
2754 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302755
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002756 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302757
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002758 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302759 {
2760 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2761 FL("session(%d) beacon data points to NULL"),
2762 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002763 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302764 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002765
2766 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter, &new, params, 0);
2767
2768 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302769 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08002770 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002771 return -EINVAL;
2772 }
2773
2774 pAdapter->sessionCtx.ap.beacon = new;
2775
2776 status = wlan_hdd_cfg80211_start_bss(pAdapter, params, NULL, 0, 0);
2777 }
2778
2779 EXIT();
2780 return status;
2781}
2782
2783#endif //(LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
2784
Jeff Johnson295189b2012-06-20 16:38:30 -07002785
2786static int wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
2787 struct net_device *dev,
2788 struct bss_parameters *params)
2789{
2790 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2791
2792 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302793
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302794 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2795 TRACE_CODE_HDD_CFG80211_CHANGE_BSS,
2796 pAdapter->sessionId, params->ap_isolate));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05302797 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
2798 __func__, hdd_device_modetoString(pAdapter->device_mode),
2799 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07002800
2801 if((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07002802 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302803 )
Jeff Johnson295189b2012-06-20 16:38:30 -07002804 {
2805 /* ap_isolate == -1 means that in change bss, upper layer doesn't
2806 * want to update this parameter */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302807 if (-1 != params->ap_isolate)
Jeff Johnson295189b2012-06-20 16:38:30 -07002808 {
2809 pAdapter->sessionCtx.ap.apDisableIntraBssFwd = !!params->ap_isolate;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302810 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002811 }
2812
2813 EXIT();
2814 return 0;
2815}
2816
Kiet Lam10841362013-11-01 11:36:50 +05302817/* FUNCTION: wlan_hdd_change_country_code_cd
2818* to wait for contry code completion
2819*/
2820void* wlan_hdd_change_country_code_cb(void *pAdapter)
2821{
2822 hdd_adapter_t *call_back_pAdapter = pAdapter;
2823 complete(&call_back_pAdapter->change_country_code);
2824 return NULL;
2825}
2826
Jeff Johnson295189b2012-06-20 16:38:30 -07002827/*
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +05302828 * FUNCTION: __wlan_hdd_cfg80211_change_iface
Jeff Johnson295189b2012-06-20 16:38:30 -07002829 * This function is used to set the interface type (INFRASTRUCTURE/ADHOC)
2830 */
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +05302831int __wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07002832 struct net_device *ndev,
2833 enum nl80211_iftype type,
2834 u32 *flags,
2835 struct vif_params *params
2836 )
2837{
2838 struct wireless_dev *wdev;
2839 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Rajesh Chauhana0516c62014-01-30 16:11:18 -08002840 hdd_context_t *pHddCtx;
Mohit Khanna0f232092012-09-11 14:46:08 -07002841 hdd_adapter_t *pP2pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07002842 tCsrRoamProfile *pRoamProfile = NULL;
2843 eCsrRoamBssType LastBSSType;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302844 hdd_config_t *pConfig = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07002845 eMib_dot11DesiredBssType connectedBssType;
2846 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302847 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07002848
2849 ENTER();
2850
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302851 if (!pAdapter)
Rajesh Chauhana0516c62014-01-30 16:11:18 -08002852 {
2853 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2854 "%s: Adapter context is null", __func__);
2855 return VOS_STATUS_E_FAILURE;
2856 }
2857
2858 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2859 if (!pHddCtx)
2860 {
2861 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2862 "%s: HDD context is null", __func__);
2863 return VOS_STATUS_E_FAILURE;
2864 }
2865
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05302866 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
2867 TRACE_CODE_HDD_CFG80211_CHANGE_IFACE,
2868 pAdapter->sessionId, type));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302869 status = wlan_hdd_validate_context(pHddCtx);
2870
2871 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -07002872 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302873 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2874 "%s: HDD context is not valid", __func__);
2875 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -07002876 }
2877
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05302878 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
2879 __func__, hdd_device_modetoString(pAdapter->device_mode),
2880 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07002881
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302882 pConfig = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -07002883 wdev = ndev->ieee80211_ptr;
2884
2885#ifdef WLAN_BTAMP_FEATURE
2886 if((NL80211_IFTYPE_P2P_CLIENT == type)||
2887 (NL80211_IFTYPE_ADHOC == type)||
2888 (NL80211_IFTYPE_AP == type)||
2889 (NL80211_IFTYPE_P2P_GO == type))
2890 {
2891 pHddCtx->isAmpAllowed = VOS_FALSE;
2892 // stop AMP traffic
2893 status = WLANBAP_StopAmp();
2894 if(VOS_STATUS_SUCCESS != status )
2895 {
2896 pHddCtx->isAmpAllowed = VOS_TRUE;
2897 hddLog(VOS_TRACE_LEVEL_FATAL,
2898 "%s: Failed to stop AMP", __func__);
2899 return -EINVAL;
2900 }
2901 }
2902#endif //WLAN_BTAMP_FEATURE
2903 /* Reset the current device mode bit mask*/
2904 wlan_hdd_clear_concurrency_mode(pHddCtx, pAdapter->device_mode);
2905
2906 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -07002907 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnsone7245742012-09-05 17:12:55 -07002908 || (pAdapter->device_mode == WLAN_HDD_P2P_DEVICE)
Jeff Johnson295189b2012-06-20 16:38:30 -07002909 )
2910 {
2911 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -08002912 if (!pWextState)
2913 {
2914 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2915 "%s: pWextState is null", __func__);
2916 return VOS_STATUS_E_FAILURE;
2917 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002918 pRoamProfile = &pWextState->roamProfile;
2919 LastBSSType = pRoamProfile->BSSType;
2920
2921 switch (type)
2922 {
2923 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -07002924 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -07002925 hddLog(VOS_TRACE_LEVEL_INFO,
2926 "%s: setting interface Type to INFRASTRUCTURE", __func__);
2927 pRoamProfile->BSSType = eCSR_BSS_TYPE_INFRASTRUCTURE;
Jeff Johnsone7245742012-09-05 17:12:55 -07002928#ifdef WLAN_FEATURE_11AC
2929 if(pConfig->dot11Mode == eHDD_DOT11_MODE_AUTO)
2930 {
2931 pConfig->dot11Mode = eHDD_DOT11_MODE_11ac;
2932 }
2933#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302934 pRoamProfile->phyMode =
Jeff Johnsone7245742012-09-05 17:12:55 -07002935 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07002936 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08002937 //Check for sub-string p2p to confirm its a p2p interface
2938 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302939 {
Gopichand Nakkala864d3552012-12-31 16:08:51 -08002940 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
2941 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
2942 }
2943 else
2944 {
2945 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -07002946 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -08002947 }
Madan Mohan Koyyalamudi81746922013-07-17 14:38:51 +05302948#ifdef FEATURE_WLAN_TDLS
2949 /* The open adapter for the p2p shall skip initializations in
2950 * tdls_init if the device mode is WLAN_HDD_P2P_DEVICE, for
2951 * TDLS is supported only on WLAN_HDD_P2P_CLIENT. Hence invoke
2952 * tdls_init when the change_iface sets the device mode to
2953 * WLAN_HDD_P2P_CLIENT.
2954 */
2955
2956 if ( pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
2957 {
2958 if (0 != wlan_hdd_tdls_init (pAdapter))
2959 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302960 hddLog(VOS_TRACE_LEVEL_ERROR,
2961 "%s: tdls initialization failed", __func__);
Madan Mohan Koyyalamudi81746922013-07-17 14:38:51 +05302962 return -EINVAL;
2963 }
2964 }
2965#endif
2966
Jeff Johnson295189b2012-06-20 16:38:30 -07002967 break;
2968 case NL80211_IFTYPE_ADHOC:
2969 hddLog(VOS_TRACE_LEVEL_INFO,
2970 "%s: setting interface Type to ADHOC", __func__);
2971 pRoamProfile->BSSType = eCSR_BSS_TYPE_START_IBSS;
2972 pRoamProfile->phyMode =
2973 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Shailender Karmuchia734f332013-04-19 14:02:48 -07002974 pAdapter->device_mode = WLAN_HDD_IBSS;
Jeff Johnson295189b2012-06-20 16:38:30 -07002975 wdev->iftype = type;
2976 break;
2977
2978 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -07002979 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07002980 {
2981 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
2982 "%s: setting interface Type to %s", __func__,
2983 (type == NL80211_IFTYPE_AP) ? "SoftAP" : "P2pGo");
2984
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08002985 //Cancel any remain on channel for GO mode
2986 if (NL80211_IFTYPE_P2P_GO == type)
2987 {
2988 wlan_hdd_cancel_existing_remain_on_channel(pAdapter);
2989 }
Mohit Khanna0f232092012-09-11 14:46:08 -07002990 if (NL80211_IFTYPE_AP == type)
2991 {
2992 /* As Loading WLAN Driver one interface being created for p2p device
2993 * address. This will take one HW STA and the max number of clients
2994 * that can connect to softAP will be reduced by one. so while changing
2995 * the interface type to NL80211_IFTYPE_AP (SoftAP) remove p2p0
2996 * interface as it is not required in SoftAP mode.
2997 */
2998
2999 // Get P2P Adapter
3000 pP2pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_DEVICE);
3001
3002 if (pP2pAdapter)
3003 {
3004 hdd_stop_adapter(pHddCtx, pP2pAdapter);
3005 hdd_deinit_adapter(pHddCtx, pP2pAdapter);
3006 hdd_close_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
3007 }
3008 }
Swaroop Goltia2e32212014-04-09 23:37:33 +05303009 //Disable IMPS & BMPS for SAP/GO
3010 if(VOS_STATUS_E_FAILURE ==
3011 hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_P2P_GO))
3012 {
3013 //Fail to Exit BMPS
3014 VOS_ASSERT(0);
3015 }
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05303016#ifdef FEATURE_WLAN_TDLS
Mohit Khanna0f232092012-09-11 14:46:08 -07003017
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05303018 /* A Mutex Lock is introduced while changing the mode to
3019 * protect the concurrent access for the Adapters by TDLS
3020 * module.
3021 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05303022 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05303023#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07003024 //De-init the adapter.
3025 hdd_stop_adapter( pHddCtx, pAdapter );
3026 hdd_deinit_adapter( pHddCtx, pAdapter );
3027 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
Jeff Johnson295189b2012-06-20 16:38:30 -07003028 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
3029 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05303030#ifdef FEATURE_WLAN_TDLS
3031 mutex_unlock(&pHddCtx->tdls_lock);
3032#endif
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -07003033 if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) &&
3034 (pConfig->apRandomBssidEnabled))
3035 {
3036 /* To meet Android requirements create a randomized
3037 MAC address of the form 02:1A:11:Fx:xx:xx */
3038 get_random_bytes(&ndev->dev_addr[3], 3);
3039 ndev->dev_addr[0] = 0x02;
3040 ndev->dev_addr[1] = 0x1A;
3041 ndev->dev_addr[2] = 0x11;
3042 ndev->dev_addr[3] |= 0xF0;
3043 memcpy(pAdapter->macAddressCurrent.bytes, ndev->dev_addr,
3044 VOS_MAC_ADDR_SIZE);
Arif Hussain24bafea2013-11-15 15:10:03 -08003045 pr_info("wlan: Generated HotSpot BSSID " MAC_ADDRESS_STR"\n",
3046 MAC_ADDR_ARRAY(ndev->dev_addr));
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -07003047 }
3048
Jeff Johnson295189b2012-06-20 16:38:30 -07003049 hdd_set_ap_ops( pAdapter->dev );
3050
Kiet Lam10841362013-11-01 11:36:50 +05303051 /* This is for only SAP mode where users can
3052 * control country through ini.
3053 * P2P GO follows station country code
3054 * acquired during the STA scanning. */
3055 if((NL80211_IFTYPE_AP == type) &&
3056 (memcmp(pConfig->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0))
3057 {
3058 int status = 0;
3059 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_INFO,
3060 "%s: setting country code from INI ", __func__);
3061 init_completion(&pAdapter->change_country_code);
3062 status = (int)sme_ChangeCountryCode(pHddCtx->hHal,
3063 (void *)(tSmeChangeCountryCallback)
3064 wlan_hdd_change_country_code_cb,
3065 pConfig->apCntryCode, pAdapter,
3066 pHddCtx->pvosContext,
Abhishek Singha306a442013-11-07 18:39:01 +05303067 eSIR_FALSE,
3068 eSIR_TRUE);
Kiet Lam10841362013-11-01 11:36:50 +05303069 if (eHAL_STATUS_SUCCESS == status)
3070 {
3071 /* Wait for completion */
c_hpothu6ff1c3c2013-10-01 19:01:57 +05303072 ret = wait_for_completion_interruptible_timeout(
Kiet Lam10841362013-11-01 11:36:50 +05303073 &pAdapter->change_country_code,
3074 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05303075 if (ret <= 0)
Kiet Lam10841362013-11-01 11:36:50 +05303076 {
3077 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05303078 FL("SME Timed out while setting country code %ld"),
3079 ret);
Yue Ma4f55ef32014-01-23 16:45:33 -08003080
3081 if (pHddCtx->isLogpInProgress)
3082 {
3083 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3084 "%s: LOGP in Progress. Ignore!!!", __func__);
3085 return -EAGAIN;
3086 }
Kiet Lam10841362013-11-01 11:36:50 +05303087 }
3088 }
3089 else
3090 {
3091 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08003092 "%s: SME Change Country code failed",__func__);
Kiet Lam10841362013-11-01 11:36:50 +05303093 return -EINVAL;
3094 }
3095 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003096 status = hdd_init_ap_mode(pAdapter);
3097 if(status != VOS_STATUS_SUCCESS)
3098 {
3099 hddLog(VOS_TRACE_LEVEL_FATAL,
3100 "%s: Error initializing the ap mode", __func__);
3101 return -EINVAL;
3102 }
3103 hdd_set_conparam(1);
3104
Jeff Johnson295189b2012-06-20 16:38:30 -07003105 /*interface type changed update in wiphy structure*/
3106 if(wdev)
3107 {
3108 wdev->iftype = type;
3109 pHddCtx->change_iface = type;
3110 }
3111 else
3112 {
3113 hddLog(VOS_TRACE_LEVEL_ERROR,
3114 "%s: ERROR !!!! Wireless dev is NULL", __func__);
3115 return -EINVAL;
3116 }
3117 goto done;
3118 }
3119
3120 default:
3121 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
3122 __func__);
3123 return -EOPNOTSUPP;
3124 }
3125 }
3126 else if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07003127 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07003128 )
3129 {
3130 switch(type)
3131 {
3132 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -07003133 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -07003134 case NL80211_IFTYPE_ADHOC:
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05303135#ifdef FEATURE_WLAN_TDLS
3136
3137 /* A Mutex Lock is introduced while changing the mode to
3138 * protect the concurrent access for the Adapters by TDLS
3139 * module.
3140 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05303141 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05303142#endif
Jeff Johnson32d95a32012-09-10 13:15:23 -07003143 hdd_stop_adapter( pHddCtx, pAdapter );
3144 hdd_deinit_adapter( pHddCtx, pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07003145 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08003146 //Check for sub-string p2p to confirm its a p2p interface
3147 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala864d3552012-12-31 16:08:51 -08003148 {
3149 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
3150 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
3151 }
3152 else
3153 {
3154 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -07003155 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -08003156 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003157 hdd_set_conparam(0);
3158 pHddCtx->change_iface = type;
Jeff Johnson295189b2012-06-20 16:38:30 -07003159 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
3160 hdd_set_station_ops( pAdapter->dev );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05303161#ifdef FEATURE_WLAN_TDLS
3162 mutex_unlock(&pHddCtx->tdls_lock);
3163#endif
Sunil Dutt66485cb2013-12-19 19:05:03 +05303164 status = hdd_init_station_mode( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07003165 if( VOS_STATUS_SUCCESS != status )
3166 return -EOPNOTSUPP;
Jeff Johnsone7245742012-09-05 17:12:55 -07003167 /* In case of JB, for P2P-GO, only change interface will be called,
3168 * This is the right place to enable back bmps_imps()
3169 */
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05303170 if (pHddCtx->hdd_wlan_suspended)
3171 {
3172 hdd_set_pwrparams(pHddCtx);
3173 }
Jeff Johnsone7245742012-09-05 17:12:55 -07003174 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07003175 goto done;
3176 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -07003177 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07003178 wdev->iftype = type;
Jeff Johnson295189b2012-06-20 16:38:30 -07003179 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
3180 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Jeff Johnson295189b2012-06-20 16:38:30 -07003181 goto done;
3182 default:
3183 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
3184 __func__);
3185 return -EOPNOTSUPP;
3186
3187 }
3188
3189 }
3190 else
3191 {
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05303192 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: unsupported device mode(%s (%d))",
3193 __func__, hdd_device_modetoString(pAdapter->device_mode),
3194 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07003195 return -EOPNOTSUPP;
3196 }
3197
3198
3199 if(pRoamProfile)
3200 {
3201 if ( LastBSSType != pRoamProfile->BSSType )
3202 {
3203 /*interface type changed update in wiphy structure*/
3204 wdev->iftype = type;
3205
3206 /*the BSS mode changed, We need to issue disconnect
3207 if connected or in IBSS disconnect state*/
3208 if ( hdd_connGetConnectedBssType(
3209 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), &connectedBssType ) ||
3210 ( eCSR_BSS_TYPE_START_IBSS == LastBSSType ) )
3211 {
3212 /*need to issue a disconnect to CSR.*/
3213 INIT_COMPLETION(pAdapter->disconnect_comp_var);
3214 if( eHAL_STATUS_SUCCESS ==
3215 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
3216 pAdapter->sessionId,
3217 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
3218 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05303219 ret = wait_for_completion_interruptible_timeout(
3220 &pAdapter->disconnect_comp_var,
3221 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
3222 if (ret <= 0)
3223 {
3224 hddLog(VOS_TRACE_LEVEL_ERROR,
3225 FL("wait on disconnect_comp_var failed %ld"), ret);
3226 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003227 }
3228 }
3229 }
3230 }
3231
3232done:
3233 /*set bitmask based on updated value*/
3234 wlan_hdd_set_concurrency_mode(pHddCtx, pAdapter->device_mode);
Leo Chang6fe1f922013-06-07 19:21:24 -07003235
3236 /* Only STA mode support TM now
3237 * all other mode, TM feature should be disabled */
3238 if ( (pHddCtx->cfg_ini->thermalMitigationEnable) &&
3239 (~VOS_STA & pHddCtx->concurrency_mode) )
3240 {
3241 hddDevTmLevelChangedHandler(pHddCtx->parent_dev, 0);
3242 }
3243
Jeff Johnson295189b2012-06-20 16:38:30 -07003244#ifdef WLAN_BTAMP_FEATURE
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303245 if((NL80211_IFTYPE_STATION == type) && (pHddCtx->concurrency_mode <= 1) &&
Jeff Johnson295189b2012-06-20 16:38:30 -07003246 (pHddCtx->no_of_sessions[WLAN_HDD_INFRA_STATION] <=1))
3247 {
3248 //we are ok to do AMP
3249 pHddCtx->isAmpAllowed = VOS_TRUE;
3250 }
3251#endif //WLAN_BTAMP_FEATURE
3252 EXIT();
3253 return 0;
3254}
3255
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +05303256/*
3257 * FUNCTION: wlan_hdd_cfg80211_change_iface
3258 * wrapper function to protect the actual implementation from SSR.
3259 */
3260int wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
3261 struct net_device *ndev,
3262 enum nl80211_iftype type,
3263 u32 *flags,
3264 struct vif_params *params
3265 )
3266{
3267 int ret;
3268
3269 vos_ssr_protect(__func__);
3270 ret = __wlan_hdd_cfg80211_change_iface(wiphy, ndev, type, flags, params);
3271 vos_ssr_unprotect(__func__);
3272
3273 return ret;
3274}
3275
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003276#ifdef FEATURE_WLAN_TDLS
3277static int wlan_hdd_tdls_add_station(struct wiphy *wiphy,
3278 struct net_device *dev, u8 *mac, bool update, tCsrStaParams *StaParams)
3279{
3280 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3281 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3282 VOS_STATUS status;
Hoonki Lee5305c3a2013-04-29 23:28:59 -07003283 hddTdlsPeer_t *pTdlsPeer;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05303284 long ret;
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05303285 tANI_U16 numCurrTdlsPeers;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003286
3287 ENTER();
3288
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05303289 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003290 {
3291 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3292 "Invalid arguments");
3293 return -EINVAL;
3294 }
Hoonki Lee27511902013-03-14 18:19:06 -07003295
3296 if ((eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode) ||
3297 (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode))
3298 {
3299 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
3300 "%s: TDLS mode is disabled OR not enabled in FW."
3301 MAC_ADDRESS_STR " Request declined.",
3302 __func__, MAC_ADDR_ARRAY(mac));
3303 return -ENOTSUPP;
3304 }
3305
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003306 if (pHddCtx->isLogpInProgress)
3307 {
3308 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3309 "%s:LOGP in Progress. Ignore!!!", __func__);
Gopichand Nakkala05922802013-03-14 12:23:19 -07003310 wlan_hdd_tdls_set_link_status(pAdapter, mac, eTDLS_LINK_IDLE);
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003311 return -EBUSY;
3312 }
3313
Naresh Jayaram9c6f4462014-02-13 12:20:31 +05303314 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, mac);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07003315
3316 if ( NULL == pTdlsPeer ) {
3317 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
3318 "%s: " MAC_ADDRESS_STR " (update %d) not exist. return invalid",
3319 __func__, MAC_ADDR_ARRAY(mac), update);
3320 return -EINVAL;
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07003321 }
Hoonki Lee5305c3a2013-04-29 23:28:59 -07003322
3323 /* in add station, we accept existing valid staId if there is */
3324 if ((0 == update) &&
3325 ((pTdlsPeer->link_status >= eTDLS_LINK_CONNECTING) ||
3326 (TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003327 {
Hoonki Lee5305c3a2013-04-29 23:28:59 -07003328 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003329 "%s: " MAC_ADDRESS_STR
Hoonki Lee5305c3a2013-04-29 23:28:59 -07003330 " link_status %d. staId %d. add station ignored.",
3331 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, pTdlsPeer->staId);
3332 return 0;
3333 }
3334 /* in change station, we accept only when staId is valid */
3335 if ((1 == update) &&
3336 ((pTdlsPeer->link_status > eTDLS_LINK_CONNECTING) ||
3337 (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
3338 {
3339 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
3340 "%s: " MAC_ADDRESS_STR
3341 " link status %d. staId %d. change station %s.",
3342 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, pTdlsPeer->staId,
3343 (TDLS_STA_INDEX_VALID(pTdlsPeer->staId)) ? "ignored" : "declined");
3344 return (TDLS_STA_INDEX_VALID(pTdlsPeer->staId)) ? 0 : -EPERM;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003345 }
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07003346
3347 /* when others are on-going, we want to change link_status to idle */
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05303348 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, mac, TRUE))
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003349 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07003350 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3351 "%s: " MAC_ADDRESS_STR
3352 " TDLS setup is ongoing. Request declined.",
3353 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala05922802013-03-14 12:23:19 -07003354 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003355 }
3356
3357 /* first to check if we reached to maximum supported TDLS peer.
3358 TODO: for now, return -EPERM looks working fine,
3359 but need to check if any other errno fit into this category.*/
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05303360 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
3361 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003362 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07003363 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3364 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05303365 " TDLS Max peer already connected. Request declined."
3366 " Num of peers (%d), Max allowed (%d).",
3367 __func__, MAC_ADDR_ARRAY(mac), numCurrTdlsPeers,
3368 HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -07003369 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003370 }
3371 else
3372 {
3373 hddTdlsPeer_t *pTdlsPeer;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05303374 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, mac, TRUE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003375 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003376 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07003377 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3378 "%s: " MAC_ADDRESS_STR " already connected. Request declined.",
3379 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003380 return -EPERM;
3381 }
3382 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003383 if (0 == update)
3384 wlan_hdd_tdls_set_link_status(pAdapter, mac, eTDLS_LINK_CONNECTING);
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003385
Jeff Johnsond75fe012013-04-06 10:53:06 -07003386 /* debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05303387 if (NULL != StaParams)
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003388 {
3389 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
3390 "%s: TDLS Peer Parameters.", __func__);
Hoonki Lee66b75f32013-04-16 18:30:07 -07003391 if(StaParams->htcap_present)
3392 {
3393 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
3394 "ht_capa->cap_info: %0x", StaParams->HTCap.capInfo);
3395 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
3396 "ht_capa->extended_capabilities: %0x",
3397 StaParams->HTCap.extendedHtCapInfo);
3398 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003399 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
3400 "params->capability: %0x",StaParams->capability);
3401 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07003402 "params->ext_capab_len: %0x",StaParams->extn_capability[0]);
Hoonki Lee66b75f32013-04-16 18:30:07 -07003403 if(StaParams->vhtcap_present)
3404 {
3405 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
3406 "rxMcsMap %x rxHighest %x txMcsMap %x txHighest %x",
3407 StaParams->VHTCap.suppMcs.rxMcsMap, StaParams->VHTCap.suppMcs.rxHighest,
3408 StaParams->VHTCap.suppMcs.txMcsMap, StaParams->VHTCap.suppMcs.txHighest);
3409 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003410 {
3411 int i = 0;
Hoonki Lee5305c3a2013-04-29 23:28:59 -07003412 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "Supported rates:");
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003413 for (i = 0; i < sizeof(StaParams->supported_rates); i++)
3414 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
3415 "[%d]: %x ", i, StaParams->supported_rates[i]);
3416 }
Jeff Johnsond75fe012013-04-06 10:53:06 -07003417 } /* end debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05303418 else if ((1 == update) && (NULL == StaParams))
3419 {
3420 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3421 "%s : update is true, but staParams is NULL. Error!", __func__);
3422 return -EPERM;
3423 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003424
3425 INIT_COMPLETION(pAdapter->tdls_add_station_comp);
3426
3427 if (!update)
3428 {
3429 status = sme_AddTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
3430 pAdapter->sessionId, mac);
3431 }
3432 else
3433 {
3434 status = sme_ChangeTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
3435 pAdapter->sessionId, mac, StaParams);
3436 }
3437
c_hpothu6ff1c3c2013-10-01 19:01:57 +05303438 ret = wait_for_completion_interruptible_timeout(&pAdapter->tdls_add_station_comp,
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003439 msecs_to_jiffies(WAIT_TIME_TDLS_ADD_STA));
3440
c_hpothu6ff1c3c2013-10-01 19:01:57 +05303441 if (ret <= 0)
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003442 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07003443 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05303444 "%s: timeout waiting for tdls add station indication %ld",
3445 __func__, ret);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07003446 return -EPERM;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003447 }
c_hpothu6ff1c3c2013-10-01 19:01:57 +05303448
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003449 if ( eHAL_STATUS_SUCCESS != pAdapter->tdlsAddStaStatus)
3450 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07003451 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003452 "%s: Add Station is unsucessful", __func__);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07003453 return -EPERM;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003454 }
3455
3456 return 0;
Gopichand Nakkala05922802013-03-14 12:23:19 -07003457
3458error:
3459 wlan_hdd_tdls_set_link_status(pAdapter, mac, eTDLS_LINK_IDLE);
3460 return -EPERM;
3461
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003462}
3463#endif
3464
Jeff Johnson295189b2012-06-20 16:38:30 -07003465static int wlan_hdd_change_station(struct wiphy *wiphy,
3466 struct net_device *dev,
3467 u8 *mac,
3468 struct station_parameters *params)
3469{
3470 VOS_STATUS status = VOS_STATUS_SUCCESS;
3471 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Gopichand Nakkala29149562013-05-10 21:43:41 +05303472 hdd_context_t *pHddCtx;
3473 hdd_station_ctx_t *pHddStaCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07003474 v_MACADDR_t STAMacAddress;
Gopichand Nakkalab0856222013-03-12 22:39:05 -07003475#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003476 tCsrStaParams StaParams = {0};
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003477 tANI_U8 isBufSta = 0;
Naresh Jayaram3180aa42014-02-12 21:47:26 +05303478 tANI_U8 isOffChannelSupported = 0;
Gopichand Nakkalab0856222013-03-12 22:39:05 -07003479#endif
Jeff Johnsone7245742012-09-05 17:12:55 -07003480 ENTER();
3481
Gopichand Nakkala29149562013-05-10 21:43:41 +05303482 if ((NULL == pAdapter))
3483 {
3484 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
3485 "invalid adapter ");
3486 return -EINVAL;
3487 }
3488
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05303489 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
3490 TRACE_CODE_HDD_CHANGE_STATION,
3491 pAdapter->sessionId, params->listen_interval));
Gopichand Nakkala29149562013-05-10 21:43:41 +05303492 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
3493 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3494
3495 if ((NULL == pHddCtx) || (NULL == pHddStaCtx))
3496 {
3497 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
3498 "invalid HDD state or HDD station context");
3499 return -EINVAL;
3500 }
3501
3502 if (pHddCtx->isLogpInProgress)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07003503 {
3504 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3505 "%s:LOGP in Progress. Ignore!!!", __func__);
3506 return -EAGAIN;
3507 }
3508
Jeff Johnson295189b2012-06-20 16:38:30 -07003509 vos_mem_copy(STAMacAddress.bytes, mac, sizeof(v_MACADDR_t));
3510
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003511 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
3512 || (pAdapter->device_mode == WLAN_HDD_P2P_GO))
Jeff Johnson295189b2012-06-20 16:38:30 -07003513 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003514 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED))
Jeff Johnson295189b2012-06-20 16:38:30 -07003515 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303516 status = hdd_softap_change_STA_state( pAdapter, &STAMacAddress,
Jeff Johnson295189b2012-06-20 16:38:30 -07003517 WLANTL_STA_AUTHENTICATED);
3518
Gopichand Nakkala29149562013-05-10 21:43:41 +05303519 if (status != VOS_STATUS_SUCCESS)
3520 {
3521 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3522 "%s: Not able to change TL state to AUTHENTICATED", __func__);
3523 return -EINVAL;
3524 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003525 }
3526 }
Hoonki Leea6d49be2013-04-05 09:43:25 -07003527 else if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
3528 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)) {
Gopichand Nakkala29149562013-05-10 21:43:41 +05303529#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003530 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
3531 StaParams.capability = params->capability;
3532 StaParams.uapsd_queues = params->uapsd_queues;
3533 StaParams.max_sp = params->max_sp;
3534
Naresh Jayaram3180aa42014-02-12 21:47:26 +05303535 /* Convert (first channel , number of channels) tuple to
3536 * the total list of channels. This goes with the assumption
3537 * that if the first channel is < 14, then the next channels
3538 * are an incremental of 1 else an incremental of 4 till the number
3539 * of channels.
3540 */
3541 if (0 != params->supported_channels_len) {
3542 int i = 0,j = 0,k = 0, no_of_channels = 0 ;
3543 for ( i = 0 ; i < params->supported_channels_len ; i+=2)
3544 {
3545 int wifi_chan_index;
3546 StaParams.supported_channels[j] = params->supported_channels[i];
3547 wifi_chan_index =
3548 ((StaParams.supported_channels[j] <= HDD_CHANNEL_14 ) ? 1 : 4 );
3549 no_of_channels = params->supported_channels[i+1];
3550 for(k=1; k <= no_of_channels; k++)
3551 {
3552 StaParams.supported_channels[j+1] =
3553 StaParams.supported_channels[j] + wifi_chan_index;
3554 j+=1;
3555 }
3556 }
3557 StaParams.supported_channels_len = j;
3558 }
3559 vos_mem_copy(StaParams.supported_oper_classes,
3560 params->supported_oper_classes,
3561 params->supported_oper_classes_len);
3562 StaParams.supported_oper_classes_len =
3563 params->supported_oper_classes_len;
3564
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003565 if (0 != params->ext_capab_len)
3566 vos_mem_copy(StaParams.extn_capability, params->ext_capab,
3567 sizeof(StaParams.extn_capability));
3568
3569 if (NULL != params->ht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -07003570 {
3571 StaParams.htcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003572 vos_mem_copy(&StaParams.HTCap, params->ht_capa, sizeof(tSirHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -07003573 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003574
3575 StaParams.supported_rates_len = params->supported_rates_len;
3576
3577 /* Note : The Maximum sizeof supported_rates sent by the Supplicant is 32.
3578 * The supported_rates array , for all the structures propogating till Add Sta
3579 * to the firmware has to be modified , if the supplicant (ieee80211) is
3580 * modified to send more rates.
3581 */
3582
3583 /* To avoid Data Currption , set to max length to SIR_MAC_MAX_SUPP_RATES
3584 */
3585 if (StaParams.supported_rates_len > SIR_MAC_MAX_SUPP_RATES)
3586 StaParams.supported_rates_len = SIR_MAC_MAX_SUPP_RATES;
3587
3588 if (0 != StaParams.supported_rates_len) {
3589 int i = 0;
3590 vos_mem_copy(StaParams.supported_rates, params->supported_rates,
3591 StaParams.supported_rates_len);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07003592 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003593 "Supported Rates with Length %d", StaParams.supported_rates_len);
3594 for (i=0; i < StaParams.supported_rates_len; i++)
Hoonki Lee5305c3a2013-04-29 23:28:59 -07003595 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003596 "[%d]: %0x", i, StaParams.supported_rates[i]);
3597 }
3598
3599 if (NULL != params->vht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -07003600 {
3601 StaParams.vhtcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003602 vos_mem_copy(&StaParams.VHTCap, params->vht_capa, sizeof(tSirVHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -07003603 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003604
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003605 if (0 != params->ext_capab_len ) {
3606 /*Define A Macro : TODO Sunil*/
3607 if ((1<<4) & StaParams.extn_capability[3]) {
3608 isBufSta = 1;
3609 }
Naresh Jayaram3180aa42014-02-12 21:47:26 +05303610 /* TDLS Channel Switching Support */
3611 if ((1<<6) & StaParams.extn_capability[3]) {
3612 isOffChannelSupported = 1;
3613 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003614 }
Naresh Jayaram3180aa42014-02-12 21:47:26 +05303615 status = wlan_hdd_tdls_set_peer_caps( pAdapter, mac,
3616 &StaParams, isBufSta,
3617 isOffChannelSupported);
3618
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05303619 if (VOS_STATUS_SUCCESS != status) {
3620 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3621 "%s: wlan_hdd_tdls_set_peer_caps failed!", __func__);
3622 return -EINVAL;
3623 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003624 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 1, &StaParams);
3625
3626 if (VOS_STATUS_SUCCESS != status) {
3627 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3628 "%s: sme_ChangeTdlsPeerSta failed!", __func__);
3629 return -EINVAL;
3630 }
3631 }
Gopichand Nakkalab0856222013-03-12 22:39:05 -07003632#endif
Gopichand Nakkala6239acd2013-06-14 14:48:00 +05303633 }
Jeff Johnsone7245742012-09-05 17:12:55 -07003634 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07003635 return status;
3636}
3637
3638/*
Jeff Johnson295189b2012-06-20 16:38:30 -07003639 * FUNCTION: wlan_hdd_cfg80211_add_key
3640 * This function is used to initialize the key information
3641 */
3642#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003643static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07003644 struct net_device *ndev,
3645 u8 key_index, bool pairwise,
3646 const u8 *mac_addr,
3647 struct key_params *params
3648 )
3649#else
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003650static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07003651 struct net_device *ndev,
3652 u8 key_index, const u8 *mac_addr,
3653 struct key_params *params
3654 )
3655#endif
3656{
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003657 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -07003658 tCsrRoamSetKey setKey;
3659 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05303660 int status;
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003661 v_U32_t roamId= 0xFF;
3662 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07003663 hdd_hostapd_state_t *pHostapdState;
3664 VOS_STATUS vos_status;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07003665 eHalStatus halStatus;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05303666 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07003667
3668 ENTER();
3669
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05303670 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
3671 TRACE_CODE_HDD_CFG80211_ADD_KEY,
3672 pAdapter->sessionId, params->key_len));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05303673 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
3674 status = wlan_hdd_validate_context(pHddCtx);
3675
3676 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07003677 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05303678 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3679 "%s: HDD context is not valid", __func__);
3680 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07003681 }
3682
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05303683 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
3684 __func__, hdd_device_modetoString(pAdapter->device_mode),
3685 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07003686
3687 if (CSR_MAX_NUM_KEY <= key_index)
3688 {
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003689 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07003690 key_index);
3691
3692 return -EINVAL;
3693 }
3694
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003695 if (CSR_MAX_KEY_LEN < params->key_len)
3696 {
3697 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key length %d", __func__,
3698 params->key_len);
3699
3700 return -EINVAL;
3701 }
3702
3703 hddLog(VOS_TRACE_LEVEL_INFO,
3704 "%s: called with key index = %d & key length %d",
3705 __func__, key_index, params->key_len);
Jeff Johnson295189b2012-06-20 16:38:30 -07003706
3707 /*extract key idx, key len and key*/
3708 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
3709 setKey.keyId = key_index;
3710 setKey.keyLength = params->key_len;
3711 vos_mem_copy(&setKey.Key[0],params->key, params->key_len);
3712
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003713 switch (params->cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -07003714 {
3715 case WLAN_CIPHER_SUITE_WEP40:
3716 setKey.encType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
3717 break;
3718
3719 case WLAN_CIPHER_SUITE_WEP104:
3720 setKey.encType = eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
3721 break;
3722
3723 case WLAN_CIPHER_SUITE_TKIP:
3724 {
3725 u8 *pKey = &setKey.Key[0];
3726 setKey.encType = eCSR_ENCRYPT_TYPE_TKIP;
3727
3728 vos_mem_zero(pKey, CSR_MAX_KEY_LEN);
3729
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003730 /*Supplicant sends the 32bytes key in this order
Jeff Johnson295189b2012-06-20 16:38:30 -07003731
3732 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003733 | Tk1 |TX-MIC | RX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -07003734 |--------------|----------|----------|
3735 <---16bytes---><--8bytes--><--8bytes-->
3736
3737 */
3738 /*Sme expects the 32 bytes key to be in the below order
3739
3740 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003741 | Tk1 |RX-MIC | TX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -07003742 |--------------|----------|----------|
3743 <---16bytes---><--8bytes--><--8bytes-->
3744 */
3745 /* Copy the Temporal Key 1 (TK1) */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003746 vos_mem_copy(pKey, params->key, 16);
Jeff Johnson295189b2012-06-20 16:38:30 -07003747
3748 /*Copy the rx mic first*/
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003749 vos_mem_copy(&pKey[16], &params->key[24], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -07003750
3751 /*Copy the tx mic */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003752 vos_mem_copy(&pKey[24], &params->key[16], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -07003753
3754
3755 break;
3756 }
3757
3758 case WLAN_CIPHER_SUITE_CCMP:
3759 setKey.encType = eCSR_ENCRYPT_TYPE_AES;
3760 break;
3761
3762#ifdef FEATURE_WLAN_WAPI
3763 case WLAN_CIPHER_SUITE_SMS4:
3764 {
3765 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
3766 wlan_hdd_cfg80211_set_key_wapi(pAdapter, key_index, mac_addr,
3767 params->key, params->key_len);
3768 return 0;
3769 }
3770#endif
Chet Lanctot186b5732013-03-18 10:26:30 -07003771
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08003772#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -07003773 case WLAN_CIPHER_SUITE_KRK:
3774 setKey.encType = eCSR_ENCRYPT_TYPE_KRK;
3775 break;
3776#endif
Chet Lanctot186b5732013-03-18 10:26:30 -07003777
3778#ifdef WLAN_FEATURE_11W
3779 case WLAN_CIPHER_SUITE_AES_CMAC:
3780 setKey.encType = eCSR_ENCRYPT_TYPE_AES_CMAC;
Chet Lanctot3b5158a2013-03-31 16:45:21 -07003781 break;
Chet Lanctot186b5732013-03-18 10:26:30 -07003782#endif
3783
Jeff Johnson295189b2012-06-20 16:38:30 -07003784 default:
Jeff Johnson0299d0a2013-10-30 12:37:43 -07003785 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unsupported cipher type %u",
Jeff Johnson295189b2012-06-20 16:38:30 -07003786 __func__, params->cipher);
3787 return -EOPNOTSUPP;
3788 }
3789
3790 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: encryption type %d",
3791 __func__, setKey.encType);
3792
Shailender Karmuchi642e9812013-05-30 14:34:49 -07003793 if (
Jeff Johnson295189b2012-06-20 16:38:30 -07003794#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
3795 (!pairwise)
3796#else
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003797 (!mac_addr || is_broadcast_ether_addr(mac_addr))
Jeff Johnson295189b2012-06-20 16:38:30 -07003798#endif
Shailender Karmuchi642e9812013-05-30 14:34:49 -07003799 )
3800 {
3801 /* set group key*/
3802 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3803 "%s- %d: setting Broadcast key",
3804 __func__, __LINE__);
3805 setKey.keyDirection = eSIR_RX_ONLY;
3806 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
3807 }
3808 else
3809 {
3810 /* set pairwise key*/
3811 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3812 "%s- %d: setting pairwise key",
3813 __func__, __LINE__);
3814 setKey.keyDirection = eSIR_TX_RX;
3815 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
3816 }
3817 if ((WLAN_HDD_IBSS == pAdapter->device_mode) && !pairwise)
3818 {
3819 setKey.keyDirection = eSIR_TX_RX;
3820 /*Set the group key*/
3821 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
3822 pAdapter->sessionId, &setKey, &roamId );
Jeff Johnson295189b2012-06-20 16:38:30 -07003823
Shailender Karmuchi642e9812013-05-30 14:34:49 -07003824 if ( 0 != status )
3825 {
3826 hddLog(VOS_TRACE_LEVEL_ERROR,
3827 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
3828 return -EINVAL;
3829 }
3830 /*Save the keys here and call sme_RoamSetKey for setting
3831 the PTK after peer joins the IBSS network*/
3832 vos_mem_copy(&pAdapter->sessionCtx.station.ibss_enc_key,
3833 &setKey, sizeof(tCsrRoamSetKey));
3834 return status;
3835 }
Gopichand Nakkala29149562013-05-10 21:43:41 +05303836 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP) ||
3837 (pAdapter->device_mode == WLAN_HDD_P2P_GO))
3838 {
Jeff Johnson295189b2012-06-20 16:38:30 -07003839 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003840 if( pHostapdState->bssState == BSS_START )
3841 {
c_hpothu7c55da62014-01-23 18:34:02 +05303842 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3843 vos_status = wlan_hdd_check_ula_done(pAdapter);
3844
3845 if ( vos_status != VOS_STATUS_SUCCESS )
3846 {
3847 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3848 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
3849 __LINE__, vos_status );
3850
3851 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
3852
3853 return -EINVAL;
3854 }
3855
Jeff Johnson295189b2012-06-20 16:38:30 -07003856 status = WLANSAP_SetKeySta( pVosContext, &setKey);
3857
3858 if ( status != eHAL_STATUS_SUCCESS )
3859 {
3860 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3861 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
3862 __LINE__, status );
3863 }
3864 }
3865
3866 /* Saving WEP keys */
3867 else if( eCSR_ENCRYPT_TYPE_WEP40_STATICKEY == setKey.encType ||
3868 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY == setKey.encType )
3869 {
3870 //Save the wep key in ap context. Issue setkey after the BSS is started.
3871 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
3872 vos_mem_copy(&pAPCtx->wepKey[key_index], &setKey, sizeof(tCsrRoamSetKey));
3873 }
3874 else
3875 {
3876 //Save the key in ap context. Issue setkey after the BSS is started.
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003877 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07003878 vos_mem_copy(&pAPCtx->groupKey, &setKey, sizeof(tCsrRoamSetKey));
3879 }
3880 }
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003881 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION) ||
3882 (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT) )
Jeff Johnson295189b2012-06-20 16:38:30 -07003883 {
3884 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
3885 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3886
Gopichand Nakkala3d295922013-05-07 16:19:14 +05303887#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
3888 if (!pairwise)
3889#else
3890 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
3891#endif
3892 {
3893 /* set group key*/
3894 if (pHddStaCtx->roam_info.deferKeyComplete)
3895 {
3896 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3897 "%s- %d: Perform Set key Complete",
3898 __func__, __LINE__);
3899 hdd_PerformRoamSetKeyComplete(pAdapter);
3900 }
3901 }
3902
Jeff Johnson295189b2012-06-20 16:38:30 -07003903 pWextState->roamProfile.Keys.KeyLength[key_index] = (u8)params->key_len;
3904
Venkata Prathyusha Kuntupalliee2ce712013-01-17 14:09:24 -08003905 pWextState->roamProfile.Keys.defaultIndex = key_index;
3906
3907
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003908 vos_mem_copy(&pWextState->roamProfile.Keys.KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -07003909 params->key, params->key_len);
3910
Gopichand Nakkala3d295922013-05-07 16:19:14 +05303911
Jeff Johnson295189b2012-06-20 16:38:30 -07003912 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
3913
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303914 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -07003915 "%s: set key for peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303916 __func__, setKey.peerMac[0], setKey.peerMac[1],
3917 setKey.peerMac[2], setKey.peerMac[3],
3918 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -07003919 setKey.keyDirection);
3920
3921 vos_status = wlan_hdd_check_ula_done(pAdapter);
3922
3923 if ( vos_status != VOS_STATUS_SUCCESS )
3924 {
3925 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3926 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
3927 __LINE__, vos_status );
3928
3929 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
3930
3931 return -EINVAL;
3932
3933 }
3934
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07003935#ifdef WLAN_FEATURE_VOWIFI_11R
Gopichand Nakkala3d295922013-05-07 16:19:14 +05303936 /* The supplicant may attempt to set the PTK once pre-authentication
3937 is done. Save the key in the UMAC and include it in the ADD BSS
3938 request */
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07003939 halStatus = sme_FTUpdateKey( WLAN_HDD_GET_HAL_CTX(pAdapter), &setKey);
Gopichand Nakkala3d295922013-05-07 16:19:14 +05303940 if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_SUCCESS )
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07003941 {
Gopichand Nakkala3d295922013-05-07 16:19:14 +05303942 hddLog(VOS_TRACE_LEVEL_INFO_MED,
3943 "%s: Update PreAuth Key success", __func__);
3944 return 0;
3945 }
3946 else if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_FAILED )
3947 {
3948 hddLog(VOS_TRACE_LEVEL_ERROR,
3949 "%s: Update PreAuth Key failed", __func__);
Gopichand Nakkalad7d13652013-02-15 01:48:00 +05303950 return -EINVAL;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07003951 }
3952#endif /* WLAN_FEATURE_VOWIFI_11R */
Jeff Johnson295189b2012-06-20 16:38:30 -07003953
3954 /* issue set key request to SME*/
3955 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
3956 pAdapter->sessionId, &setKey, &roamId );
3957
3958 if ( 0 != status )
3959 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303960 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07003961 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
3962 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
3963 return -EINVAL;
3964 }
3965
3966
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303967 /* in case of IBSS as there was no information available about WEP keys during
3968 * IBSS join, group key intialized with NULL key, so re-initialize group key
Jeff Johnson295189b2012-06-20 16:38:30 -07003969 * with correct value*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303970 if ( (eCSR_BSS_TYPE_START_IBSS == pWextState->roamProfile.BSSType) &&
3971 !( ( IW_AUTH_KEY_MGMT_802_1X
3972 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X))
Jeff Johnson295189b2012-06-20 16:38:30 -07003973 && (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType)
3974 )
3975 &&
3976 ( (WLAN_CIPHER_SUITE_WEP40 == params->cipher)
3977 || (WLAN_CIPHER_SUITE_WEP104 == params->cipher)
3978 )
3979 )
3980 {
3981 setKey.keyDirection = eSIR_RX_ONLY;
3982 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
3983
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303984 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -07003985 "%s: set key peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303986 __func__, setKey.peerMac[0], setKey.peerMac[1],
3987 setKey.peerMac[2], setKey.peerMac[3],
3988 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -07003989 setKey.keyDirection);
3990
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303991 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07003992 pAdapter->sessionId, &setKey, &roamId );
3993
3994 if ( 0 != status )
3995 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303996 hddLog(VOS_TRACE_LEVEL_ERROR,
3997 "%s: sme_RoamSetKey failed for group key (IBSS), returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07003998 __func__, status);
3999 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
4000 return -EINVAL;
4001 }
4002 }
4003 }
4004
4005 return 0;
4006}
4007
4008/*
4009 * FUNCTION: wlan_hdd_cfg80211_get_key
4010 * This function is used to get the key information
4011 */
4012#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304013static int wlan_hdd_cfg80211_get_key(
4014 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07004015 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304016 u8 key_index, bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -07004017 const u8 *mac_addr, void *cookie,
4018 void (*callback)(void *cookie, struct key_params*)
4019 )
4020#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304021static int wlan_hdd_cfg80211_get_key(
4022 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07004023 struct net_device *ndev,
4024 u8 key_index, const u8 *mac_addr, void *cookie,
4025 void (*callback)(void *cookie, struct key_params*)
4026 )
4027#endif
4028{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304029 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -07004030 hdd_wext_state_t *pWextState= WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
4031 tCsrRoamProfile *pRoamProfile = &(pWextState->roamProfile);
4032 struct key_params params;
4033
4034 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304035
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05304036 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
4037 TRACE_CODE_HDD_CFG80211_GET_KEY,
4038 pAdapter->sessionId, params.cipher));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05304039 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
4040 __func__, hdd_device_modetoString(pAdapter->device_mode),
4041 pAdapter->device_mode);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304042
Jeff Johnson295189b2012-06-20 16:38:30 -07004043 memset(&params, 0, sizeof(params));
4044
4045 if (CSR_MAX_NUM_KEY <= key_index)
4046 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05304047 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid key index %d"), key_index);
Jeff Johnson295189b2012-06-20 16:38:30 -07004048 return -EINVAL;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304049 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004050
4051 switch(pRoamProfile->EncryptionType.encryptionType[0])
4052 {
4053 case eCSR_ENCRYPT_TYPE_NONE:
4054 params.cipher = IW_AUTH_CIPHER_NONE;
4055 break;
4056
4057 case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY:
4058 case eCSR_ENCRYPT_TYPE_WEP40:
4059 params.cipher = WLAN_CIPHER_SUITE_WEP40;
4060 break;
4061
4062 case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY:
4063 case eCSR_ENCRYPT_TYPE_WEP104:
4064 params.cipher = WLAN_CIPHER_SUITE_WEP104;
4065 break;
4066
4067 case eCSR_ENCRYPT_TYPE_TKIP:
4068 params.cipher = WLAN_CIPHER_SUITE_TKIP;
4069 break;
4070
4071 case eCSR_ENCRYPT_TYPE_AES:
4072 params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
4073 break;
4074
4075 default:
4076 params.cipher = IW_AUTH_CIPHER_NONE;
4077 break;
4078 }
4079
4080 params.key_len = pRoamProfile->Keys.KeyLength[key_index];
4081 params.seq_len = 0;
4082 params.seq = NULL;
4083 params.key = &pRoamProfile->Keys.KeyMaterial[key_index][0];
4084 callback(cookie, &params);
4085 return 0;
4086}
4087
4088/*
4089 * FUNCTION: wlan_hdd_cfg80211_del_key
4090 * This function is used to delete the key information
4091 */
4092#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304093static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07004094 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304095 u8 key_index,
4096 bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -07004097 const u8 *mac_addr
4098 )
4099#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304100static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07004101 struct net_device *ndev,
4102 u8 key_index,
4103 const u8 *mac_addr
4104 )
4105#endif
4106{
4107 int status = 0;
4108
4109 //This code needs to be revisited. There is sme_removeKey API, we should
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304110 //plan to use that. After the change to use correct index in setkey,
Jeff Johnson295189b2012-06-20 16:38:30 -07004111 //it is observed that this is invalidating peer
4112 //key index whenever re-key is done. This is affecting data link.
4113 //It should be ok to ignore del_key.
4114#if 0
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304115 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
4116 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07004117 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
4118 tCsrRoamSetKey setKey;
4119 v_U32_t roamId= 0xFF;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304120
Jeff Johnson295189b2012-06-20 16:38:30 -07004121 ENTER();
4122
4123 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device_mode = %d\n",
4124 __func__,pAdapter->device_mode);
4125
4126 if (CSR_MAX_NUM_KEY <= key_index)
4127 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304128 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07004129 key_index);
4130
4131 return -EINVAL;
4132 }
4133
4134 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
4135 setKey.keyId = key_index;
4136
4137 if (mac_addr)
4138 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
4139 else
4140 vos_mem_copy(setKey.peerMac, groupmacaddr, WNI_CFG_BSSID_LEN);
4141
4142 setKey.encType = eCSR_ENCRYPT_TYPE_NONE;
4143
4144 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07004145 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304146 )
4147 {
4148
4149 hdd_hostapd_state_t *pHostapdState =
Jeff Johnson295189b2012-06-20 16:38:30 -07004150 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
4151 if( pHostapdState->bssState == BSS_START)
4152 {
4153 status = WLANSAP_SetKeySta( pVosContext, &setKey);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304154
Jeff Johnson295189b2012-06-20 16:38:30 -07004155 if ( status != eHAL_STATUS_SUCCESS )
4156 {
4157 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4158 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
4159 __LINE__, status );
4160 }
4161 }
4162 }
4163 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304164 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnson295189b2012-06-20 16:38:30 -07004165 )
4166 {
4167 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4168
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304169 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
4170
4171 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -07004172 "%s: delete key for peerMac %2x:%2x:%2x:%2x:%2x:%2x",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304173 __func__, setKey.peerMac[0], setKey.peerMac[1],
4174 setKey.peerMac[2], setKey.peerMac[3],
Jeff Johnson295189b2012-06-20 16:38:30 -07004175 setKey.peerMac[4], setKey.peerMac[5]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304176 if(pAdapter->sessionCtx.station.conn_info.connState ==
4177 eConnectionState_Associated)
Jeff Johnson295189b2012-06-20 16:38:30 -07004178 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304179 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07004180 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304181
Jeff Johnson295189b2012-06-20 16:38:30 -07004182 if ( 0 != status )
4183 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304184 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07004185 "%s: sme_RoamSetKey failure, returned %d",
4186 __func__, status);
4187 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
4188 return -EINVAL;
4189 }
4190 }
4191 }
4192#endif
Jeff Johnsone7245742012-09-05 17:12:55 -07004193 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07004194 return status;
4195}
4196
4197/*
4198 * FUNCTION: wlan_hdd_cfg80211_set_default_key
4199 * This function is used to set the default tx key index
4200 */
4201#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
4202static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
4203 struct net_device *ndev,
4204 u8 key_index,
4205 bool unicast, bool multicast)
4206#else
4207static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
4208 struct net_device *ndev,
4209 u8 key_index)
4210#endif
4211{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304212 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05304213 int status;
Gopichand Nakkala29149562013-05-10 21:43:41 +05304214 hdd_wext_state_t *pWextState;
4215 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05304216 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07004217
4218 ENTER();
4219
Gopichand Nakkala29149562013-05-10 21:43:41 +05304220 if ((NULL == pAdapter))
4221 {
4222 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
4223 "invalid adapter");
4224 return -EINVAL;
4225 }
4226
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05304227 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
4228 TRACE_CODE_HDD_CFG80211_SET_DEFAULT_KEY,
4229 pAdapter->sessionId, key_index));
4230
Gopichand Nakkala29149562013-05-10 21:43:41 +05304231 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
4232 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4233
4234 if ((NULL == pWextState) || (NULL == pHddStaCtx))
4235 {
4236 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
4237 "invalid Wext state or HDD context");
4238 return -EINVAL;
4239 }
4240
Arif Hussain6d2a3322013-11-17 19:50:10 -08004241 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d key_index = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07004242 __func__,pAdapter->device_mode, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304243
Jeff Johnson295189b2012-06-20 16:38:30 -07004244 if (CSR_MAX_NUM_KEY <= key_index)
4245 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304246 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07004247 key_index);
4248
4249 return -EINVAL;
4250 }
4251
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05304252 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
4253 status = wlan_hdd_validate_context(pHddCtx);
4254
4255 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004256 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05304257 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4258 "%s: HDD context is not valid", __func__);
4259 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004260 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304261
Jeff Johnson295189b2012-06-20 16:38:30 -07004262 if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -07004263 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304264 )
Jeff Johnson295189b2012-06-20 16:38:30 -07004265 {
Gopichand Nakkala29149562013-05-10 21:43:41 +05304266 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
Arif Hussain6943f522013-11-04 20:10:10 -08004267 pHddStaCtx->conn_info.ucEncryptionType) &&
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304268 (eCSR_ENCRYPT_TYPE_AES !=
Arif Hussain6943f522013-11-04 20:10:10 -08004269 pHddStaCtx->conn_info.ucEncryptionType)
Jeff Johnson295189b2012-06-20 16:38:30 -07004270 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304271 {
4272 /* if default key index is not same as previous one,
Jeff Johnson295189b2012-06-20 16:38:30 -07004273 * then update the default key index */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304274
Jeff Johnson295189b2012-06-20 16:38:30 -07004275 tCsrRoamSetKey setKey;
4276 v_U32_t roamId= 0xFF;
4277 tCsrKeys *Keys = &pWextState->roamProfile.Keys;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304278
4279 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: default tx key index %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07004280 __func__, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304281
Jeff Johnson295189b2012-06-20 16:38:30 -07004282 Keys->defaultIndex = (u8)key_index;
4283 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
4284 setKey.keyId = key_index;
4285 setKey.keyLength = Keys->KeyLength[key_index];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304286
4287 vos_mem_copy(&setKey.Key[0],
4288 &Keys->KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -07004289 Keys->KeyLength[key_index]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304290
Gopichand Nakkala29149562013-05-10 21:43:41 +05304291 setKey.keyDirection = eSIR_TX_RX;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304292
4293 vos_mem_copy(setKey.peerMac,
Jeff Johnson295189b2012-06-20 16:38:30 -07004294 &pHddStaCtx->conn_info.bssId[0],
4295 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304296
Gopichand Nakkala29149562013-05-10 21:43:41 +05304297 if (Keys->KeyLength[key_index] == CSR_WEP40_KEY_LEN &&
4298 pWextState->roamProfile.EncryptionType.encryptionType[0] ==
4299 eCSR_ENCRYPT_TYPE_WEP104)
4300 {
4301 /*In the case of dynamic wep supplicant hardcodes DWEP type to eCSR_ENCRYPT_TYPE_WEP104
4302 even though ap is configured for WEP-40 encryption. In this canse the key length
4303 is 5 but the encryption type is 104 hence checking the key langht(5) and encryption
4304 type(104) and switching encryption type to 40*/
4305 pWextState->roamProfile.EncryptionType.encryptionType[0] =
4306 eCSR_ENCRYPT_TYPE_WEP40;
4307 pWextState->roamProfile.mcEncryptionType.encryptionType[0] =
4308 eCSR_ENCRYPT_TYPE_WEP40;
4309 }
4310
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304311 setKey.encType =
Jeff Johnson295189b2012-06-20 16:38:30 -07004312 pWextState->roamProfile.EncryptionType.encryptionType[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304313
Jeff Johnson295189b2012-06-20 16:38:30 -07004314 /* issue set key request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304315 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07004316 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304317
Jeff Johnson295189b2012-06-20 16:38:30 -07004318 if ( 0 != status )
4319 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304320 hddLog(VOS_TRACE_LEVEL_ERROR,
4321 "%s: sme_RoamSetKey failed, returned %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07004322 status);
4323 return -EINVAL;
4324 }
4325 }
4326 }
4327
4328 /* In SoftAp mode setting key direction for default mode */
4329 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
4330 {
4331 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
4332 pWextState->roamProfile.EncryptionType.encryptionType[0]) &&
4333 (eCSR_ENCRYPT_TYPE_AES !=
4334 pWextState->roamProfile.EncryptionType.encryptionType[0])
4335 )
4336 {
4337 /* Saving key direction for default key index to TX default */
4338 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
4339 pAPCtx->wepKey[key_index].keyDirection = eSIR_TX_DEFAULT;
4340 }
4341 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304342
Jeff Johnson295189b2012-06-20 16:38:30 -07004343 return status;
4344}
4345
Jeff Johnson295189b2012-06-20 16:38:30 -07004346/*
4347 * FUNCTION: wlan_hdd_cfg80211_inform_bss
4348 * This function is used to inform the BSS details to nl80211 interface.
4349 */
4350static struct cfg80211_bss* wlan_hdd_cfg80211_inform_bss(
4351 hdd_adapter_t *pAdapter, tCsrRoamConnectedProfile *roamProfile)
4352{
4353 struct net_device *dev = pAdapter->dev;
4354 struct wireless_dev *wdev = dev->ieee80211_ptr;
4355 struct wiphy *wiphy = wdev->wiphy;
4356 tSirBssDescription *pBssDesc = roamProfile->pBssDesc;
4357 int chan_no;
4358 int ie_length;
4359 const char *ie;
4360 unsigned int freq;
4361 struct ieee80211_channel *chan;
4362 int rssi = 0;
4363 struct cfg80211_bss *bss = NULL;
4364
4365 ENTER();
4366
4367 if( NULL == pBssDesc )
4368 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08004369 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pBssDesc is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004370 return bss;
4371 }
4372
4373 chan_no = pBssDesc->channelId;
4374 ie_length = GET_IE_LEN_IN_BSS_DESC( pBssDesc->length );
4375 ie = ((ie_length != 0) ? (const char *)&pBssDesc->ieFields: NULL);
4376
4377 if( NULL == ie )
4378 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08004379 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: IE of BSS descriptor is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004380 return bss;
4381 }
4382
4383#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
4384 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
4385 {
4386 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
4387 }
4388 else
4389 {
4390 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
4391 }
4392#else
4393 freq = ieee80211_channel_to_frequency(chan_no);
4394#endif
4395
4396 chan = __ieee80211_get_channel(wiphy, freq);
4397
Santhosh Kumar Padmaa45fdb12014-04-15 15:54:38 +05304398 if (!chan) {
4399 hddLog(VOS_TRACE_LEVEL_ERROR, "%s chan pointer is NULL", __func__);
4400 return NULL;
4401 }
4402
Jeff Johnson295189b2012-06-20 16:38:30 -07004403 bss = cfg80211_get_bss(wiphy, chan, pBssDesc->bssId,
4404 &roamProfile->SSID.ssId[0], roamProfile->SSID.length,
4405 WLAN_CAPABILITY_ESS, WLAN_CAPABILITY_ESS);
4406 if (bss == NULL)
4407 {
4408 rssi = (VOS_MIN ((pBssDesc->rssi + pBssDesc->sinr), 0))*100;
4409
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304410 return (cfg80211_inform_bss(wiphy, chan, pBssDesc->bssId,
4411 le64_to_cpu(*(__le64 *)pBssDesc->timeStamp),
Jeff Johnson295189b2012-06-20 16:38:30 -07004412 pBssDesc->capabilityInfo,
4413 pBssDesc->beaconInterval, ie, ie_length,
4414 rssi, GFP_KERNEL ));
4415}
4416 else
4417 {
4418 return bss;
4419 }
4420}
4421
4422
4423
4424/*
4425 * FUNCTION: wlan_hdd_cfg80211_inform_bss_frame
4426 * This function is used to inform the BSS details to nl80211 interface.
4427 */
4428struct cfg80211_bss*
4429wlan_hdd_cfg80211_inform_bss_frame( hdd_adapter_t *pAdapter,
4430 tSirBssDescription *bss_desc
4431 )
4432{
4433 /*
4434 cfg80211_inform_bss() is not updating ie field of bss entry, if entry
4435 already exists in bss data base of cfg80211 for that particular BSS ID.
4436 Using cfg80211_inform_bss_frame to update the bss entry instead of
4437 cfg80211_inform_bss, But this call expects mgmt packet as input. As of
4438 now there is no possibility to get the mgmt(probe response) frame from PE,
4439 converting bss_desc to ieee80211_mgmt(probe response) and passing to
4440 cfg80211_inform_bss_frame.
4441 */
4442 struct net_device *dev = pAdapter->dev;
4443 struct wireless_dev *wdev = dev->ieee80211_ptr;
4444 struct wiphy *wiphy = wdev->wiphy;
4445 int chan_no = bss_desc->channelId;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08004446#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
4447 qcom_ie_age *qie_age = NULL;
4448 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length ) + sizeof(qcom_ie_age);
4449#else
Jeff Johnson295189b2012-06-20 16:38:30 -07004450 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length );
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08004451#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07004452 const char *ie =
4453 ((ie_length != 0) ? (const char *)&bss_desc->ieFields: NULL);
4454 unsigned int freq;
4455 struct ieee80211_channel *chan;
Abhishek Singh1e2bfa32014-01-02 15:44:15 +05304456 struct ieee80211_mgmt *mgmt = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07004457 struct cfg80211_bss *bss_status = NULL;
4458 size_t frame_len = sizeof (struct ieee80211_mgmt) + ie_length;
4459 int rssi = 0;
Wilson Yangf80a0542013-10-07 13:02:37 -07004460 hdd_context_t *pHddCtx;
4461 int status;
Jeff Johnsone7245742012-09-05 17:12:55 -07004462#ifdef WLAN_OPEN_SOURCE
4463 struct timespec ts;
4464#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07004465
Wilson Yangf80a0542013-10-07 13:02:37 -07004466 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
4467 status = wlan_hdd_validate_context(pHddCtx);
4468
4469 /*bss_update is not allowed during wlan driver loading or unloading*/
Mihir Shete18156292014-03-11 15:38:30 +05304470 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Wilson Yangf80a0542013-10-07 13:02:37 -07004471 {
4472 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4473 "%s:Loading_unloading in Progress. Ignore!!!",__func__);
4474 return NULL;
4475 }
4476
4477
4478 if (0 != status)
4479 {
4480 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4481 "%s: HDD context is not valid", __func__);
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -07004482 return NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -07004483 }
4484
Abhishek Singh1e2bfa32014-01-02 15:44:15 +05304485 mgmt = kzalloc((sizeof (struct ieee80211_mgmt) + ie_length), GFP_KERNEL);
Wilson Yangf80a0542013-10-07 13:02:37 -07004486 if (!mgmt)
4487 {
4488 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4489 "%s: memory allocation failed ", __func__);
4490 return NULL;
4491 }
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -07004492
Jeff Johnson295189b2012-06-20 16:38:30 -07004493 memcpy(mgmt->bssid, bss_desc->bssId, ETH_ALEN);
Jeff Johnsone7245742012-09-05 17:12:55 -07004494
4495#ifdef WLAN_OPEN_SOURCE
4496 /* Android does not want the timestamp from the frame.
4497 Instead it wants a monotonic increasing value */
4498 get_monotonic_boottime(&ts);
4499 mgmt->u.probe_resp.timestamp =
4500 ((u64)ts.tv_sec * 1000000) + (ts.tv_nsec / 1000);
4501#else
4502 /* keep old behavior for non-open source (for now) */
Jeff Johnson295189b2012-06-20 16:38:30 -07004503 memcpy(&mgmt->u.probe_resp.timestamp, bss_desc->timeStamp,
4504 sizeof (bss_desc->timeStamp));
Jeff Johnsone7245742012-09-05 17:12:55 -07004505
4506#endif
4507
Jeff Johnson295189b2012-06-20 16:38:30 -07004508 mgmt->u.probe_resp.beacon_int = bss_desc->beaconInterval;
4509 mgmt->u.probe_resp.capab_info = bss_desc->capabilityInfo;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08004510
4511#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
4512 /* GPS Requirement: need age ie per entry. Using vendor specific. */
4513 /* Assuming this is the last IE, copy at the end */
4514 ie_length -=sizeof(qcom_ie_age);
4515 qie_age = (qcom_ie_age *)(mgmt->u.probe_resp.variable + ie_length);
4516 qie_age->element_id = QCOM_VENDOR_IE_ID;
4517 qie_age->len = QCOM_VENDOR_IE_AGE_LEN;
4518 qie_age->oui_1 = QCOM_OUI1;
4519 qie_age->oui_2 = QCOM_OUI2;
4520 qie_age->oui_3 = QCOM_OUI3;
4521 qie_age->type = QCOM_VENDOR_IE_AGE_TYPE;
4522 qie_age->age = vos_timer_get_system_ticks() - bss_desc->nReceivedTime;
4523#endif
4524
Jeff Johnson295189b2012-06-20 16:38:30 -07004525 memcpy(mgmt->u.probe_resp.variable, ie, ie_length);
Gopichand Nakkalad908ec82013-05-16 19:32:19 +05304526 if (bss_desc->fProbeRsp)
4527 {
4528 mgmt->frame_control |=
4529 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_RESP);
4530 }
4531 else
4532 {
4533 mgmt->frame_control |=
4534 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_BEACON);
4535 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004536
4537#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304538 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ) &&
Jeff Johnson295189b2012-06-20 16:38:30 -07004539 (wiphy->bands[IEEE80211_BAND_2GHZ] != NULL))
4540 {
4541 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
4542 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304543 else if ((chan_no > ARRAY_SIZE(hdd_channels_2_4_GHZ)) &&
Jeff Johnson295189b2012-06-20 16:38:30 -07004544 (wiphy->bands[IEEE80211_BAND_5GHZ] != NULL))
4545
4546 {
4547 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
4548 }
4549 else
4550 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05304551 hddLog(VOS_TRACE_LEVEL_ERROR, "%s Invalid chan_no:%d",
4552 __func__, chan_no);
Jeff Johnson295189b2012-06-20 16:38:30 -07004553 kfree(mgmt);
4554 return NULL;
4555 }
4556#else
4557 freq = ieee80211_channel_to_frequency(chan_no);
4558#endif
4559 chan = __ieee80211_get_channel(wiphy, freq);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -08004560 /*when the band is changed on the fly using the GUI, three things are done
4561 * 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)
4562 * as part of the scan abort, message willbe queued to PE and we proceed with flushing and changinh the band.
4563 * pe will stop the scanning further and report back the results what ever it had till now by calling the call back function.
4564 * if the time between update band and scandone call back is sufficent enough the band change reflects in SME, SME validates the channels
4565 * and discards the channels correponding to previous band and calls back with zero bss results.
4566 * 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
4567 * all the channels correponding to previous band.this is due to race condition.but those channels are invalid to the new band and so
4568 * this function __ieee80211_get_channel will return NULL.Each time we report scan result with this pointer null warning kernel trace is printed.
4569 * if the scan results contain large number of APs continuosly kernel warning trace is printed and it will lead to apps watch dog bark.
4570 * So drop the bss and continue to next bss.
4571 */
4572 if(chan == NULL)
4573 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05304574 hddLog(VOS_TRACE_LEVEL_ERROR, "%s chan pointer is NULL", __func__);
Chilam Ngc4244af2013-04-01 15:37:32 -07004575 kfree(mgmt);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -08004576 return NULL;
4577 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004578 /*To keep the rssi icon of the connected AP in the scan window
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304579 *and the rssi icon of the wireless networks in sync
Jeff Johnson295189b2012-06-20 16:38:30 -07004580 * */
4581 if (( eConnectionState_Associated ==
4582 pAdapter->sessionCtx.station.conn_info.connState ) &&
4583 ( VOS_TRUE == vos_mem_compare(bss_desc->bssId,
4584 pAdapter->sessionCtx.station.conn_info.bssId,
4585 WNI_CFG_BSSID_LEN)))
4586 {
4587 /* supplicant takes the signal strength in terms of mBm(100*dBm) */
4588 rssi = (pAdapter->rssi * 100);
4589 }
4590 else
4591 {
4592 rssi = (VOS_MIN ((bss_desc->rssi + bss_desc->sinr), 0))*100;
4593 }
4594
Nirav Shah20ac06f2013-12-12 18:14:06 +05304595 hddLog(VOS_TRACE_LEVEL_INFO, "%s: BSSID:" MAC_ADDRESS_STR " Channel:%d"
4596 "RSSI:%d", __func__, MAC_ADDR_ARRAY(mgmt->bssid),
4597 chan->center_freq, (int)(rssi/100));
4598
Jeff Johnson295189b2012-06-20 16:38:30 -07004599 bss_status = cfg80211_inform_bss_frame(wiphy, chan, mgmt,
4600 frame_len, rssi, GFP_KERNEL);
4601 kfree(mgmt);
4602 return bss_status;
4603}
4604
4605/*
4606 * FUNCTION: wlan_hdd_cfg80211_update_bss_db
4607 * This function is used to update the BSS data base of CFG8011
4608 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304609struct cfg80211_bss* wlan_hdd_cfg80211_update_bss_db( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07004610 tCsrRoamInfo *pRoamInfo
4611 )
4612{
4613 tCsrRoamConnectedProfile roamProfile;
4614 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
4615 struct cfg80211_bss *bss = NULL;
4616
4617 ENTER();
4618
4619 memset(&roamProfile, 0, sizeof(tCsrRoamConnectedProfile));
4620 sme_RoamGetConnectProfile(hHal, pAdapter->sessionId, &roamProfile);
4621
4622 if (NULL != roamProfile.pBssDesc)
4623 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304624 bss = wlan_hdd_cfg80211_inform_bss(pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07004625 &roamProfile);
4626
4627 if (NULL == bss)
4628 {
4629 hddLog(VOS_TRACE_LEVEL_INFO, "%s: cfg80211_inform_bss return NULL",
4630 __func__);
4631 }
4632
4633 sme_RoamFreeConnectProfile(hHal, &roamProfile);
4634 }
4635 else
4636 {
4637 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: roamProfile.pBssDesc is NULL",
4638 __func__);
4639 }
4640 return bss;
4641}
4642
4643/*
4644 * FUNCTION: wlan_hdd_cfg80211_update_bss
4645 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304646static int wlan_hdd_cfg80211_update_bss( struct wiphy *wiphy,
4647 hdd_adapter_t *pAdapter
Jeff Johnson295189b2012-06-20 16:38:30 -07004648 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304649{
Jeff Johnson295189b2012-06-20 16:38:30 -07004650 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
4651 tCsrScanResultInfo *pScanResult;
4652 eHalStatus status = 0;
4653 tScanResultHandle pResult;
4654 struct cfg80211_bss *bss_status = NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -07004655 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07004656
4657 ENTER();
4658
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05304659 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
4660 TRACE_CODE_HDD_CFG80211_UPDATE_BSS,
4661 NO_SESSION, pAdapter->sessionId));
4662
Wilson Yangf80a0542013-10-07 13:02:37 -07004663 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
4664
4665 if (pHddCtx->isLogpInProgress)
Jeff Johnson295189b2012-06-20 16:38:30 -07004666 {
Wilson Yangf80a0542013-10-07 13:02:37 -07004667 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
4668 "%s:LOGP in Progress. Ignore!!!",__func__);
4669 return -EAGAIN;
Jeff Johnson295189b2012-06-20 16:38:30 -07004670 }
4671
Wilson Yangf80a0542013-10-07 13:02:37 -07004672
4673 /*bss_update is not allowed during wlan driver loading or unloading*/
Mihir Shete18156292014-03-11 15:38:30 +05304674 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Wilson Yangf80a0542013-10-07 13:02:37 -07004675 {
4676 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4677 "%s:Loading_unloading in Progress. Ignore!!!",__func__);
4678 return VOS_STATUS_E_PERM;
4679 }
4680
4681
Jeff Johnson295189b2012-06-20 16:38:30 -07004682 /*
4683 * start getting scan results and populate cgf80211 BSS database
4684 */
4685 status = sme_ScanGetResult(hHal, pAdapter->sessionId, NULL, &pResult);
4686
4687 /* no scan results */
4688 if (NULL == pResult)
4689 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05304690 hddLog(VOS_TRACE_LEVEL_INFO, "%s: No scan result Status %d",
4691 __func__, status);
Jeff Johnson295189b2012-06-20 16:38:30 -07004692 return status;
4693 }
4694
4695 pScanResult = sme_ScanResultGetFirst(hHal, pResult);
4696
4697 while (pScanResult)
4698 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304699 /*
4700 * cfg80211_inform_bss() is not updating ie field of bss entry, if
4701 * entry already exists in bss data base of cfg80211 for that
4702 * particular BSS ID. Using cfg80211_inform_bss_frame to update the
4703 * bss entry instead of cfg80211_inform_bss, But this call expects
4704 * mgmt packet as input. As of now there is no possibility to get
4705 * the mgmt(probe response) frame from PE, converting bss_desc to
Jeff Johnson295189b2012-06-20 16:38:30 -07004706 * ieee80211_mgmt(probe response) and passing to c
4707 * fg80211_inform_bss_frame.
4708 * */
4709
4710 bss_status = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
4711 &pScanResult->BssDescriptor);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304712
Jeff Johnson295189b2012-06-20 16:38:30 -07004713
4714 if (NULL == bss_status)
4715 {
4716 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -08004717 "%s: NULL returned by cfg80211_inform_bss", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004718 }
4719 else
4720 {
Yue Maf49ba872013-08-19 12:04:25 -07004721 cfg80211_put_bss(
4722#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0))
4723 wiphy,
4724#endif
4725 bss_status);
Jeff Johnson295189b2012-06-20 16:38:30 -07004726 }
4727
4728 pScanResult = sme_ScanResultGetNext(hHal, pResult);
4729 }
4730
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304731 sme_ScanResultPurge(hHal, pResult);
Jeff Johnson295189b2012-06-20 16:38:30 -07004732
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304733 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07004734}
4735
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004736void
4737hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel)
4738{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304739 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussaina7c8e412013-11-20 11:06:42 -08004740 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(macAddr));
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004741} /****** end hddPrintMacAddr() ******/
4742
4743void
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07004744hddPrintPmkId(tANI_U8 *pmkId, tANI_U8 logLevel)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004745{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304746 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussain6d2a3322013-11-17 19:50:10 -08004747 "%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X",
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07004748 pmkId[0], pmkId[1], pmkId[2], pmkId[3], pmkId[4],
4749 pmkId[5], pmkId[6], pmkId[7], pmkId[8], pmkId[9], pmkId[10],
4750 pmkId[11], pmkId[12], pmkId[13], pmkId[14], pmkId[15]);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004751} /****** end hddPrintPmkId() ******/
4752
4753//hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel);
4754//hddPrintMacAddr(macAddr, VOS_TRACE_LEVEL_FATAL);
4755
4756//void sirDumpBuf(tpAniSirGlobal pMac, tANI_U8 modId, tANI_U32 level, tANI_U8 *buf, tANI_U32 size);
4757//sirDumpBuf(pMac, VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, pmkid, 16);
4758
4759#define dump_bssid(bssid) \
4760 { \
Jeff Johnsone7245742012-09-05 17:12:55 -07004761 hddLog(VOS_TRACE_LEVEL_INFO, "BSSID (MAC) address:\t"); \
4762 hddPrintMacAddr(bssid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004763 }
4764
4765#define dump_pmkid(pMac, pmkid) \
4766 { \
Jeff Johnsone7245742012-09-05 17:12:55 -07004767 hddLog(VOS_TRACE_LEVEL_INFO, "PMKSA-ID:\t"); \
4768 hddPrintPmkId(pmkid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004769 }
4770
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -07004771#if defined(FEATURE_WLAN_LFR) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004772/*
4773 * FUNCTION: wlan_hdd_cfg80211_pmksa_candidate_notify
4774 * This function is used to notify the supplicant of a new PMKSA candidate.
4775 */
4776int wlan_hdd_cfg80211_pmksa_candidate_notify(
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304777 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004778 int index, bool preauth )
4779{
Jeff Johnsone7245742012-09-05 17:12:55 -07004780#ifdef FEATURE_WLAN_OKC
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004781 struct net_device *dev = pAdapter->dev;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004782 hdd_context_t *pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004783
4784 ENTER();
Jeff Johnsone7245742012-09-05 17:12:55 -07004785 hddLog(VOS_TRACE_LEVEL_INFO, "%s is going to notify supplicant of:", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004786
4787 if( NULL == pRoamInfo )
4788 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08004789 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pRoamInfo is NULL", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004790 return -EINVAL;
4791 }
4792
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004793 if (eANI_BOOLEAN_TRUE == hdd_is_okc_mode_enabled(pHddCtx))
4794 {
4795 dump_bssid(pRoamInfo->bssid);
4796 cfg80211_pmksa_candidate_notify(dev, index,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004797 pRoamInfo->bssid, preauth, GFP_KERNEL);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004798 }
Jeff Johnsone7245742012-09-05 17:12:55 -07004799#endif /* FEATURE_WLAN_OKC */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304800 return 0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004801}
4802#endif //FEATURE_WLAN_LFR
4803
Yue Maef608272013-04-08 23:09:17 -07004804#ifdef FEATURE_WLAN_LFR_METRICS
4805/*
4806 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth
4807 * 802.11r/LFR metrics reporting function to report preauth initiation
4808 *
4809 */
4810#define MAX_LFR_METRICS_EVENT_LENGTH 100
4811VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth(hdd_adapter_t *pAdapter,
4812 tCsrRoamInfo *pRoamInfo)
4813{
4814 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
4815 union iwreq_data wrqu;
4816
4817 ENTER();
4818
4819 if (NULL == pAdapter)
4820 {
4821 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
4822 return VOS_STATUS_E_FAILURE;
4823 }
4824
4825 /* create the event */
4826 memset(&wrqu, 0, sizeof(wrqu));
4827 memset(metrics_notification, 0, sizeof(metrics_notification));
4828
4829 wrqu.data.pointer = metrics_notification;
4830 wrqu.data.length = scnprintf(metrics_notification,
4831 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_INIT "
4832 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
4833
4834 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
4835
4836 EXIT();
4837
4838 return VOS_STATUS_SUCCESS;
4839}
4840
4841/*
4842 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth_status
4843 * 802.11r/LFR metrics reporting function to report preauth completion
4844 * or failure
4845 */
4846VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth_status(
4847 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo, bool preauth_status)
4848{
4849 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
4850 union iwreq_data wrqu;
4851
4852 ENTER();
4853
4854 if (NULL == pAdapter)
4855 {
4856 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
4857 return VOS_STATUS_E_FAILURE;
4858 }
4859
4860 /* create the event */
4861 memset(&wrqu, 0, sizeof(wrqu));
4862 memset(metrics_notification, 0, sizeof(metrics_notification));
4863
4864 scnprintf(metrics_notification, sizeof(metrics_notification),
4865 "QCOM: LFR_PREAUTH_STATUS "MAC_ADDRESS_STR,
4866 MAC_ADDR_ARRAY(pRoamInfo->bssid));
4867
4868 if (1 == preauth_status)
4869 strncat(metrics_notification, " TRUE", 5);
4870 else
4871 strncat(metrics_notification, " FALSE", 6);
4872
4873 wrqu.data.pointer = metrics_notification;
4874 wrqu.data.length = strlen(metrics_notification);
4875
4876 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
4877
4878 EXIT();
4879
4880 return VOS_STATUS_SUCCESS;
4881}
4882
4883/*
4884 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_handover
4885 * 802.11r/LFR metrics reporting function to report handover initiation
4886 *
4887 */
4888VOS_STATUS wlan_hdd_cfg80211_roam_metrics_handover(hdd_adapter_t * pAdapter,
4889 tCsrRoamInfo *pRoamInfo)
4890{
4891 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
4892 union iwreq_data wrqu;
4893
4894 ENTER();
4895
4896 if (NULL == pAdapter)
4897 {
4898 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
4899 return VOS_STATUS_E_FAILURE;
4900 }
4901
4902 /* create the event */
4903 memset(&wrqu, 0, sizeof(wrqu));
4904 memset(metrics_notification, 0, sizeof(metrics_notification));
4905
4906 wrqu.data.pointer = metrics_notification;
4907 wrqu.data.length = scnprintf(metrics_notification,
4908 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_HANDOVER "
4909 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
4910
4911 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
4912
4913 EXIT();
4914
4915 return VOS_STATUS_SUCCESS;
4916}
4917#endif
4918
Jeff Johnson295189b2012-06-20 16:38:30 -07004919/*
4920 * FUNCTION: hdd_cfg80211_scan_done_callback
4921 * scanning callback function, called after finishing scan
4922 *
4923 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304924static eHalStatus hdd_cfg80211_scan_done_callback(tHalHandle halHandle,
Jeff Johnson295189b2012-06-20 16:38:30 -07004925 void *pContext, tANI_U32 scanId, eCsrScanStatus status)
4926{
4927 struct net_device *dev = (struct net_device *) pContext;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304928 //struct wireless_dev *wdev = dev->ieee80211_ptr;
Jeff Johnson295189b2012-06-20 16:38:30 -07004929 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07004930 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
4931 hdd_scaninfo_t *pScanInfo = &pHddCtx->scan_info;
Jeff Johnson295189b2012-06-20 16:38:30 -07004932 struct cfg80211_scan_request *req = NULL;
4933 int ret = 0;
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +05304934 bool aborted = false;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05304935 long waitRet = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07004936
4937 ENTER();
4938
4939 hddLog(VOS_TRACE_LEVEL_INFO,
4940 "%s called with halHandle = %p, pContext = %p,"
Arif Hussain6d2a3322013-11-17 19:50:10 -08004941 "scanID = %d, returned status = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07004942 __func__, halHandle, pContext, (int) scanId, (int) status);
4943
Kiet Lamac06e2c2013-10-23 16:25:07 +05304944 pScanInfo->mScanPendingCounter = 0;
4945
Jeff Johnson295189b2012-06-20 16:38:30 -07004946 //Block on scan req completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +05304947 waitRet = wait_for_completion_interruptible_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07004948 &pScanInfo->scan_req_completion_event,
4949 msecs_to_jiffies(WLAN_WAIT_TIME_SCAN_REQ));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05304950 if (waitRet <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -07004951 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05304952 hddLog(VOS_TRACE_LEVEL_ERROR,
4953 "%s wait on scan_req_completion_event failed %ld",__func__, waitRet);
Jeff Johnson295189b2012-06-20 16:38:30 -07004954 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -07004955 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -07004956 }
4957
Yue Maef608272013-04-08 23:09:17 -07004958 if (pScanInfo->mScanPending != VOS_TRUE)
Jeff Johnson295189b2012-06-20 16:38:30 -07004959 {
4960 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -07004961 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -07004962 }
4963
4964 /* Check the scanId */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304965 if (pScanInfo->scanId != scanId)
Jeff Johnson295189b2012-06-20 16:38:30 -07004966 {
4967 hddLog(VOS_TRACE_LEVEL_INFO,
4968 "%s called with mismatched scanId pScanInfo->scanId = %d "
Arif Hussain6d2a3322013-11-17 19:50:10 -08004969 "scanId = %d", __func__, (int) pScanInfo->scanId,
Jeff Johnson295189b2012-06-20 16:38:30 -07004970 (int) scanId);
4971 }
4972
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304973 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07004974 pAdapter);
4975
4976 if (0 > ret)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304977 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004978
4979
4980 /* If any client wait scan result through WEXT
4981 * send scan done event to client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07004982 if (pHddCtx->scan_info.waitScanResult)
Jeff Johnson295189b2012-06-20 16:38:30 -07004983 {
4984 /* The other scan request waiting for current scan finish
4985 * Send event to notify current scan finished */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07004986 if(WEXT_SCAN_PENDING_DELAY == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -07004987 {
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07004988 vos_event_set(&pHddCtx->scan_info.scan_finished_event);
Jeff Johnson295189b2012-06-20 16:38:30 -07004989 }
4990 /* Send notify to WEXT client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07004991 else if(WEXT_SCAN_PENDING_PIGGYBACK == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -07004992 {
4993 struct net_device *dev = pAdapter->dev;
4994 union iwreq_data wrqu;
4995 int we_event;
4996 char *msg;
4997
4998 memset(&wrqu, '\0', sizeof(wrqu));
4999 we_event = SIOCGIWSCAN;
5000 msg = NULL;
5001 wireless_send_event(dev, we_event, &wrqu, msg);
5002 }
5003 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07005004 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07005005
5006 /* Get the Scan Req */
5007 req = pAdapter->request;
5008
5009 if (!req)
5010 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08005011 hddLog(VOS_TRACE_LEVEL_ERROR, "request is became NULL");
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07005012 pScanInfo->mScanPending = VOS_FALSE;
Jeff Johnsone7245742012-09-05 17:12:55 -07005013 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -07005014 }
5015
5016 /*
5017 * setting up 0, just in case.
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305018 */
Jeff Johnson295189b2012-06-20 16:38:30 -07005019 req->n_ssids = 0;
5020 req->n_channels = 0;
5021 req->ie = 0;
5022
Jeff Johnson295189b2012-06-20 16:38:30 -07005023 pAdapter->request = NULL;
Jeff Johnsone7245742012-09-05 17:12:55 -07005024 /* Scan is no longer pending */
5025 pScanInfo->mScanPending = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07005026
Madan Mohan Koyyalamudib764bf82012-10-11 16:38:51 -07005027 /*
5028 * cfg80211_scan_done informing NL80211 about completion
5029 * of scanning
5030 */
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +05305031 if (status == eCSR_SCAN_ABORT || status == eCSR_SCAN_FAILURE)
5032 {
5033 aborted = true;
5034 }
5035 cfg80211_scan_done(req, aborted);
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -08005036 complete(&pScanInfo->abortscan_event_var);
Jeff Johnson295189b2012-06-20 16:38:30 -07005037
Jeff Johnsone7245742012-09-05 17:12:55 -07005038allow_suspend:
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07005039 /* release the wake lock at the end of the scan*/
5040 hdd_allow_suspend();
Jeff Johnsone7245742012-09-05 17:12:55 -07005041
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -07005042 /* Acquire wakelock to handle the case where APP's tries to suspend
5043 * immediatly after the driver gets connect request(i.e after scan)
5044 * from supplicant, this result in app's is suspending and not able
5045 * to process the connect request to AP */
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +05305046 hdd_prevent_suspend_timeout(1000);
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -07005047
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07005048#ifdef FEATURE_WLAN_TDLS
5049 wlan_hdd_tdls_scan_done_callback(pAdapter);
5050#endif
5051
Jeff Johnson295189b2012-06-20 16:38:30 -07005052 EXIT();
5053 return 0;
5054}
5055
5056/*
Rashmi Ramannab1429032014-04-26 14:59:09 +05305057 * FUNCTION: hdd_isConnectionInProgress
5058 * Go through each adapter and check if Connection is in progress
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08005059 *
5060 */
Rashmi Ramannab1429032014-04-26 14:59:09 +05305061v_BOOL_t hdd_isConnectionInProgress( hdd_context_t *pHddCtx )
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08005062{
5063 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
5064 hdd_station_ctx_t *pHddStaCtx = NULL;
5065 hdd_adapter_t *pAdapter = NULL;
5066 VOS_STATUS status = 0;
5067 v_U8_t staId = 0;
5068 v_U8_t *staMac = NULL;
5069
c_hpothu9b781ba2013-12-30 20:57:45 +05305070 if (TRUE == pHddCtx->btCoexModeSet)
5071 {
5072 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Rashmi Ramannab1429032014-04-26 14:59:09 +05305073 FL("BTCoex Mode operation in progress"));
5074 return VOS_TRUE;
c_hpothu9b781ba2013-12-30 20:57:45 +05305075 }
5076
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08005077 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
5078
5079 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
5080 {
5081 pAdapter = pAdapterNode->pAdapter;
5082
5083 if( pAdapter )
5084 {
5085 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05305086 "%s: Adapter with device mode %s (%d) exists",
5087 __func__, hdd_device_modetoString(pAdapter->device_mode),
5088 pAdapter->device_mode);
Rashmi Ramannab1429032014-04-26 14:59:09 +05305089 if (((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
5090 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
5091 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode)) &&
5092 (eConnectionState_Connecting ==
5093 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
5094 {
5095 hddLog(VOS_TRACE_LEVEL_ERROR,
5096 "%s: %p(%d) Connection is in progress", __func__,
5097 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
5098 return VOS_TRUE;
5099 }
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08005100 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05305101 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
5102 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08005103 {
5104 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
5105 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05305106 (VOS_FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08005107 {
5108 staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]);
5109 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain24bafea2013-11-15 15:10:03 -08005110 "%s: client " MAC_ADDRESS_STR
5111 " is in the middle of WPS/EAPOL exchange.", __func__,
5112 MAC_ADDR_ARRAY(staMac));
Rashmi Ramannab1429032014-04-26 14:59:09 +05305113 return VOS_TRUE;
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08005114 }
5115 }
5116 else if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) ||
5117 (WLAN_HDD_P2P_GO == pAdapter->device_mode))
5118 {
5119 for (staId = 0; staId < WLAN_MAX_STA_COUNT; staId++)
5120 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305121 if ((pAdapter->aStaInfo[staId].isUsed) &&
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08005122 (WLANTL_STA_CONNECTED == pAdapter->aStaInfo[staId].tlSTAState))
5123 {
5124 staMac = (v_U8_t *) &(pAdapter->aStaInfo[staId].macAddrSTA.bytes[0]);
5125
5126 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain24bafea2013-11-15 15:10:03 -08005127 "%s: client " MAC_ADDRESS_STR " of SoftAP/P2P-GO is in the "
5128 "middle of WPS/EAPOL exchange.", __func__,
5129 MAC_ADDR_ARRAY(staMac));
Rashmi Ramannab1429032014-04-26 14:59:09 +05305130 return VOS_TRUE;
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08005131 }
5132 }
5133 }
5134 }
5135 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
5136 pAdapterNode = pNext;
5137 }
Rashmi Ramannab1429032014-04-26 14:59:09 +05305138 return VOS_FALSE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305139}
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08005140
5141/*
Jeff Johnson295189b2012-06-20 16:38:30 -07005142 * FUNCTION: wlan_hdd_cfg80211_scan
5143 * this scan respond to scan trigger and update cfg80211 scan database
5144 * later, scan dump command can be used to recieve scan results
5145 */
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -08005146int wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
5147#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
5148 struct net_device *dev,
5149#endif
5150 struct cfg80211_scan_request *request)
5151{
5152#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
5153 struct net_device *dev = request->wdev->netdev;
5154#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305155 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Jeff Johnson295189b2012-06-20 16:38:30 -07005156 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
5157 hdd_wext_state_t *pwextBuf = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305158 hdd_config_t *cfg_param = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07005159 tCsrScanRequest scanRequest;
5160 tANI_U8 *channelList = NULL, i;
5161 v_U32_t scanId = 0;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305162 int status;
5163 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07005164 v_U8_t* pP2pIe = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07005165
5166 ENTER();
5167
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05305168 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
5169 TRACE_CODE_HDD_CFG80211_SCAN,
5170 pAdapter->sessionId, request->n_channels));
5171
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05305172 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
5173 __func__, hdd_device_modetoString(pAdapter->device_mode),
5174 pAdapter->device_mode);
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08005175
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305176 status = wlan_hdd_validate_context(pHddCtx);
5177
5178 if (0 != status)
5179 {
5180 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5181 "%s: HDD context is not valid", __func__);
5182 return status;
5183 }
5184
5185 cfg_param = pHddCtx->cfg_ini;
5186 pScanInfo = &pHddCtx->scan_info;
5187
Jeff Johnson295189b2012-06-20 16:38:30 -07005188#ifdef WLAN_BTAMP_FEATURE
5189 //Scan not supported when AMP traffic is on.
Gopichand Nakkala681989c2013-03-06 22:27:48 -08005190 if (VOS_TRUE == WLANBAP_AmpSessionOn())
Jeff Johnson295189b2012-06-20 16:38:30 -07005191 {
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08005192 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07005193 "%s: No scanning when AMP is on", __func__);
5194 return -EOPNOTSUPP;
5195 }
5196#endif
5197 //Scan on any other interface is not supported.
Gopichand Nakkala681989c2013-03-06 22:27:48 -08005198 if (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07005199 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -08005200 hddLog(VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05305201 "%s: Not scanning on device_mode = %s (%d)",
5202 __func__, hdd_device_modetoString(pAdapter->device_mode),
5203 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07005204 return -EOPNOTSUPP;
5205 }
5206
5207 if (TRUE == pScanInfo->mScanPending)
5208 {
Kiet Lamac06e2c2013-10-23 16:25:07 +05305209 if ( MAX_PENDING_LOG > pScanInfo->mScanPendingCounter++ )
5210 {
5211 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: mScanPending is TRUE", __func__);
5212 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08005213 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -07005214 }
5215
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305216 //Don't Allow Scan and return busy if Remain On
Jeff Johnson32d95a32012-09-10 13:15:23 -07005217 //Channel and action frame is pending
5218 //Otherwise Cancel Remain On Channel and allow Scan
5219 //If no action frame pending
Gopichand Nakkala681989c2013-03-06 22:27:48 -08005220 if (0 != wlan_hdd_check_remain_on_channel(pAdapter))
Jeff Johnson32d95a32012-09-10 13:15:23 -07005221 {
Kiet Lamac06e2c2013-10-23 16:25:07 +05305222 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Remain On Channel Pending", __func__);
Jeff Johnson32d95a32012-09-10 13:15:23 -07005223 return -EBUSY;
5224 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08005225#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07005226 /* if tdls disagree scan right now, return immediately.
5227 tdls will schedule the scan when scan is allowed. (return SUCCESS)
5228 or will reject the scan if any TDLS is in progress. (return -EBUSY)
5229 */
5230 status = wlan_hdd_tdls_scan_callback (pAdapter,
5231 wiphy,
5232#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
5233 dev,
Gopichand Nakkalac3c42b92013-03-20 19:42:34 -07005234#endif
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07005235 request);
5236 if(status <= 0)
5237 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05305238 if(!status)
5239 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS in progress."
5240 "scan rejected %d", __func__, status);
5241 else
5242 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS teardown is ongoing %d",
5243 __func__, status);
5244
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07005245 return status;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08005246 }
5247#endif
Jeff Johnson32d95a32012-09-10 13:15:23 -07005248
Jeff Johnson295189b2012-06-20 16:38:30 -07005249 if (mutex_lock_interruptible(&pHddCtx->tmInfo.tmOperationLock))
5250 {
5251 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_ERROR,
Jeff Johnson1250df42012-12-10 14:31:52 -08005252 "%s: Acquire lock fail", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005253 return -EAGAIN;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305254 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005255 if (TRUE == pHddCtx->tmInfo.tmAction.enterImps)
5256 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05305257 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07005258 "%s: MAX TM Level Scan not allowed", __func__);
5259 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305260 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -07005261 }
5262 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
5263
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08005264 /* Check if scan is allowed at this point of time.
5265 */
Rashmi Ramannab1429032014-04-26 14:59:09 +05305266 if (hdd_isConnectionInProgress(pHddCtx))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08005267 {
5268 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Scan not allowed", __func__);
5269 return -EBUSY;
5270 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305271
Jeff Johnson295189b2012-06-20 16:38:30 -07005272 vos_mem_zero( &scanRequest, sizeof(scanRequest));
5273
5274 if (NULL != request)
5275 {
5276 hddLog(VOS_TRACE_LEVEL_INFO, "scan request for ssid = %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305277 (int)request->n_ssids);
Jeff Johnson295189b2012-06-20 16:38:30 -07005278
5279 /* Even though supplicant doesn't provide any SSIDs, n_ssids is set to 1.
5280 * Becasue of this, driver is assuming that this is not wildcard scan and so
5281 * is not aging out the scan results.
5282 */
Jeff Johnson32d95a32012-09-10 13:15:23 -07005283 if (request->ssids && '\0' == request->ssids->ssid[0])
Jeff Johnson295189b2012-06-20 16:38:30 -07005284 {
5285 request->n_ssids = 0;
5286 }
5287
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07005288 if ((request->ssids) && (0 < request->n_ssids))
Jeff Johnson295189b2012-06-20 16:38:30 -07005289 {
5290 tCsrSSIDInfo *SsidInfo;
5291 int j;
5292 scanRequest.SSIDs.numOfSSIDs = request->n_ssids;
5293 /* Allocate num_ssid tCsrSSIDInfo structure */
5294 SsidInfo = scanRequest.SSIDs.SSIDList =
5295 ( tCsrSSIDInfo *)vos_mem_malloc(
5296 request->n_ssids*sizeof(tCsrSSIDInfo));
5297
5298 if(NULL == scanRequest.SSIDs.SSIDList)
5299 {
5300 hddLog(VOS_TRACE_LEVEL_ERROR,
Nirav Shah20ac06f2013-12-12 18:14:06 +05305301 "%s: memory alloc failed SSIDInfo buffer", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005302 return -ENOMEM;
5303 }
5304
5305 /* copy all the ssid's and their length */
5306 for(j = 0; j < request->n_ssids; j++, SsidInfo++)
5307 {
5308 /* get the ssid length */
5309 SsidInfo->SSID.length = request->ssids[j].ssid_len;
5310 vos_mem_copy(SsidInfo->SSID.ssId, &request->ssids[j].ssid[0],
5311 SsidInfo->SSID.length);
5312 SsidInfo->SSID.ssId[SsidInfo->SSID.length] = '\0';
Nirav Shah20ac06f2013-12-12 18:14:06 +05305313 hddLog(VOS_TRACE_LEVEL_INFO, "SSID number %d: %s",
Jeff Johnson295189b2012-06-20 16:38:30 -07005314 j, SsidInfo->SSID.ssId);
5315 }
5316 /* set the scan type to active */
5317 scanRequest.scanType = eSIR_ACTIVE_SCAN;
5318 }
5319 else if(WLAN_HDD_P2P_GO == pAdapter->device_mode)
5320 {
5321 /* set the scan type to active */
5322 scanRequest.scanType = eSIR_ACTIVE_SCAN;
5323 }
5324 else
5325 {
5326 /*Set the scan type to default type, in this case it is ACTIVE*/
5327 scanRequest.scanType = pScanInfo->scan_mode;
5328 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305329 scanRequest.minChnTime = cfg_param->nActiveMinChnTime;
Jeff Johnson295189b2012-06-20 16:38:30 -07005330 scanRequest.maxChnTime = cfg_param->nActiveMaxChnTime;
5331 }
5332 else
5333 {
5334 /* set the scan type to active */
5335 scanRequest.scanType = eSIR_ACTIVE_SCAN;
5336 vos_mem_set( scanRequest.bssid, sizeof( tCsrBssid ), 0xff );
5337
5338 /* set min and max channel time to zero */
5339 scanRequest.minChnTime = 0;
5340 scanRequest.maxChnTime = 0;
5341 }
5342
5343 /* set BSSType to default type */
5344 scanRequest.BSSType = eCSR_BSS_TYPE_ANY;
5345
5346 /*TODO: scan the requested channels only*/
5347
5348 /*Right now scanning all the channels */
5349 if( request )
5350 {
c_hpothu53512302014-04-15 18:49:53 +05305351 if (MAX_CHANNEL < request->n_channels)
5352 {
5353 hddLog(VOS_TRACE_LEVEL_WARN,
5354 "No of Scan Channels exceeded limit: %d", request->n_channels);
5355 request->n_channels = MAX_CHANNEL;
5356 }
Nirav Shah20ac06f2013-12-12 18:14:06 +05305357 hddLog(VOS_TRACE_LEVEL_INFO,
5358 "No of Scan Channels: %d", request->n_channels);
c_hpothu53512302014-04-15 18:49:53 +05305359
Jeff Johnson295189b2012-06-20 16:38:30 -07005360 if( request->n_channels )
5361 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05305362 char chList [(request->n_channels*5)+1];
5363 int len;
Jeff Johnson295189b2012-06-20 16:38:30 -07005364 channelList = vos_mem_malloc( request->n_channels );
5365 if( NULL == channelList )
5366 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305367 hddLog(VOS_TRACE_LEVEL_ERROR,
Nirav Shah20ac06f2013-12-12 18:14:06 +05305368 "%s: memory alloc failed channelList", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005369 status = -ENOMEM;
5370 goto free_mem;
5371 }
5372
Nirav Shah20ac06f2013-12-12 18:14:06 +05305373 for( i = 0, len = 0; i < request->n_channels ; i++ )
5374 {
Jeff Johnson295189b2012-06-20 16:38:30 -07005375 channelList[i] = request->channels[i]->hw_value;
Nirav Shah20ac06f2013-12-12 18:14:06 +05305376 len += snprintf(chList+len, 5, "%d ", channelList[i]);
5377 }
5378
5379 hddLog(VOS_TRACE_LEVEL_INFO,
5380 "Channel-List: %s ", chList);
Jeff Johnson295189b2012-06-20 16:38:30 -07005381 }
5382
5383 scanRequest.ChannelInfo.numOfChannels = request->n_channels;
5384 scanRequest.ChannelInfo.ChannelList = channelList;
5385
5386 /* set requestType to full scan */
5387 scanRequest.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305388
5389 /* Flush the scan results(only p2p beacons) for STA scan and P2P
Madan Mohan Koyyalamudi8d50f312012-11-27 15:48:57 -08005390 * search (Flush on both full scan and social scan but not on single
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305391 * channel scan).P2P search happens on 3 social channels (1, 6, 11)
Madan Mohan Koyyalamudi8d50f312012-11-27 15:48:57 -08005392 */
5393
5394 /* Supplicant does single channel scan after 8-way handshake
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305395 * and in that case driver shoudnt flush scan results. If
5396 * driver flushes the scan results here and unfortunately if
5397 * the AP doesnt respond to our probe req then association
Madan Mohan Koyyalamudi8d50f312012-11-27 15:48:57 -08005398 * fails which is not desired
5399 */
5400
5401 if( request->n_channels != WLAN_HDD_P2P_SINGLE_CHANNEL_SCAN )
5402 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05305403 hddLog(VOS_TRACE_LEVEL_DEBUG, "Flushing P2P Results");
Madan Mohan Koyyalamudi8d50f312012-11-27 15:48:57 -08005404 sme_ScanFlushP2PResult( WLAN_HDD_GET_HAL_CTX(pAdapter),
5405 pAdapter->sessionId );
5406 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005407
5408 if( request->ie_len )
5409 {
5410 /* save this for future association (join requires this) */
Agarwal Ashish4f616132013-12-30 23:32:50 +05305411 /*TODO: Array needs to be converted to dynamic allocation,
5412 * as multiple ie.s can be sent in cfg80211_scan_request structure
5413 * CR 597966
5414 */
Jeff Johnson295189b2012-06-20 16:38:30 -07005415 memset( &pScanInfo->scanAddIE, 0, sizeof(pScanInfo->scanAddIE) );
5416 memcpy( pScanInfo->scanAddIE.addIEdata, request->ie, request->ie_len);
5417 pScanInfo->scanAddIE.length = request->ie_len;
5418
Agarwal Ashish4f616132013-12-30 23:32:50 +05305419 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Jeff Johnsone7245742012-09-05 17:12:55 -07005420 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
Agarwal Ashish4f616132013-12-30 23:32:50 +05305421 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -07005422 {
Agarwal Ashish4f616132013-12-30 23:32:50 +05305423 if ( request->ie_len <= SIR_MAC_MAX_IE_LENGTH)
5424 {
5425 pwextBuf->roamProfile.nAddIEScanLength = request->ie_len;
5426 memcpy( pwextBuf->roamProfile.addIEScan,
5427 request->ie, request->ie_len);
5428 }
5429 else
5430 {
5431 hddLog(VOS_TRACE_LEVEL_ERROR, "Scan Ie length is invalid:"
Arun Kumar Khandavalli75eeb122014-03-27 21:43:12 +05305432 "%zu", request->ie_len);
Agarwal Ashish4f616132013-12-30 23:32:50 +05305433 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005434
Agarwal Ashish4f616132013-12-30 23:32:50 +05305435 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005436 scanRequest.uIEFieldLen = pScanInfo->scanAddIE.length;
5437 scanRequest.pIEField = pScanInfo->scanAddIE.addIEdata;
5438
Jeff Johnson295189b2012-06-20 16:38:30 -07005439 pP2pIe = wlan_hdd_get_p2p_ie_ptr((v_U8_t*)request->ie,
5440 request->ie_len);
5441 if (pP2pIe != NULL)
5442 {
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07005443#ifdef WLAN_FEATURE_P2P_DEBUG
5444 if (((globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED) ||
5445 (globalP2PConnectionStatus == P2P_GO_NEG_PROCESS)) &&
5446 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
5447 {
5448 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_1;
5449 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
5450 "Go nego completed to Connection is started");
5451 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
5452 "for 8way Handshake");
5453 }
5454 else if((globalP2PConnectionStatus == P2P_CLIENT_DISCONNECTED_STATE) &&
5455 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
5456 {
5457 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_2;
5458 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
5459 "Disconnected state to Connection is started");
5460 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
5461 "for 4way Handshake");
5462 }
5463#endif
5464
Jeff Johnsone7245742012-09-05 17:12:55 -07005465 /* no_cck will be set during p2p find to disable 11b rates */
5466 if(TRUE == request->no_cck)
Jeff Johnson295189b2012-06-20 16:38:30 -07005467 {
Jeff Johnson295189b2012-06-20 16:38:30 -07005468 hddLog(VOS_TRACE_LEVEL_INFO,
5469 "%s: This is a P2P Search", __func__);
5470 scanRequest.p2pSearch = 1;
Jeff Johnsone7245742012-09-05 17:12:55 -07005471
Jeff Johnsone7245742012-09-05 17:12:55 -07005472 if( request->n_channels == WLAN_HDD_P2P_SOCIAL_CHANNELS )
5473 {
Madan Mohan Koyyalamudi1b1d9e82012-10-21 11:38:33 -07005474 /* set requestType to P2P Discovery */
5475 scanRequest.requestType = eCSR_SCAN_P2P_DISCOVERY;
Jeff Johnsone7245742012-09-05 17:12:55 -07005476 }
5477
5478 /*
5479 Skip Dfs Channel in case of P2P Search
5480 if it is set in ini file
5481 */
5482 if(cfg_param->skipDfsChnlInP2pSearch)
5483 {
5484 scanRequest.skipDfsChnlInP2pSearch = 1;
5485 }
5486 else
5487 {
5488 scanRequest.skipDfsChnlInP2pSearch = 0;
5489 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005490
Jeff Johnson295189b2012-06-20 16:38:30 -07005491 }
5492 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005493 }
5494 }
5495
5496 INIT_COMPLETION(pScanInfo->scan_req_completion_event);
5497
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07005498 /* acquire the wakelock to avoid the apps suspend during the scan. To
5499 * address the following issues.
5500 * 1) Disconnected scenario: we are not allowing the suspend as WLAN is not in
5501 * BMPS/IMPS this result in android trying to suspend aggressively and backing off
5502 * for long time, this result in apps running at full power for long time.
5503 * 2) Connected scenario: If we allow the suspend during the scan, RIVA will
5504 * be stuck in full power because of resume BMPS
5505 */
5506 hdd_prevent_suspend();
Jeff Johnsone7245742012-09-05 17:12:55 -07005507
Nirav Shah20ac06f2013-12-12 18:14:06 +05305508 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
5509 "requestType %d, scanType %d, minChnTime %d, maxChnTime %d,"
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05305510 "p2pSearch %d, skipDfsChnlInP2pSearch %d",
5511 scanRequest.requestType, scanRequest.scanType,
5512 scanRequest.minChnTime, scanRequest.maxChnTime,
Nirav Shah20ac06f2013-12-12 18:14:06 +05305513 scanRequest.p2pSearch, scanRequest.skipDfsChnlInP2pSearch);
5514
Jeff Johnsone7245742012-09-05 17:12:55 -07005515 status = sme_ScanRequest( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07005516 pAdapter->sessionId, &scanRequest, &scanId,
5517 &hdd_cfg80211_scan_done_callback, dev );
Jeff Johnsone7245742012-09-05 17:12:55 -07005518
Jeff Johnson295189b2012-06-20 16:38:30 -07005519 if (eHAL_STATUS_SUCCESS != status)
5520 {
5521 hddLog(VOS_TRACE_LEVEL_ERROR,
5522 "%s: sme_ScanRequest returned error %d", __func__, status);
5523 complete(&pScanInfo->scan_req_completion_event);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -07005524 if(eHAL_STATUS_RESOURCES == status)
5525 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05305526 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: HO is in progress."
5527 "So defer the scan by informing busy",__func__);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -07005528 status = -EBUSY;
5529 } else {
5530 status = -EIO;
5531 }
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07005532 hdd_allow_suspend();
Jeff Johnson295189b2012-06-20 16:38:30 -07005533 goto free_mem;
5534 }
5535
5536 pScanInfo->mScanPending = TRUE;
5537 pAdapter->request = request;
5538 pScanInfo->scanId = scanId;
5539
5540 complete(&pScanInfo->scan_req_completion_event);
5541
5542free_mem:
5543 if( scanRequest.SSIDs.SSIDList )
5544 {
5545 vos_mem_free(scanRequest.SSIDs.SSIDList);
5546 }
5547
5548 if( channelList )
5549 vos_mem_free( channelList );
5550
5551 EXIT();
5552
5553 return status;
5554}
5555
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07005556
5557void hdd_select_cbmode( hdd_adapter_t *pAdapter,v_U8_t operationChannel)
5558{
5559 v_U8_t iniDot11Mode =
5560 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->dot11Mode;
5561 eHddDot11Mode hddDot11Mode = iniDot11Mode;
5562
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +05305563 hddLog(LOG1, FL("Channel Bonding Mode Selected is %u"),
5564 iniDot11Mode);
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07005565 switch ( iniDot11Mode )
5566 {
5567 case eHDD_DOT11_MODE_AUTO:
5568 case eHDD_DOT11_MODE_11ac:
5569 case eHDD_DOT11_MODE_11ac_ONLY:
5570#ifdef WLAN_FEATURE_11AC
5571 hddDot11Mode = eHDD_DOT11_MODE_11ac;
5572#else
5573 hddDot11Mode = eHDD_DOT11_MODE_11n;
5574#endif
5575 break;
5576 case eHDD_DOT11_MODE_11n:
5577 case eHDD_DOT11_MODE_11n_ONLY:
5578 hddDot11Mode = eHDD_DOT11_MODE_11n;
5579 break;
5580 default:
5581 hddDot11Mode = iniDot11Mode;
5582 break;
5583 }
5584 /* This call decides required channel bonding mode */
5585 sme_SelectCBMode((WLAN_HDD_GET_CTX(pAdapter)->hHal),
5586 hdd_cfg_xlate_to_csr_phy_mode(hddDot11Mode),
5587 operationChannel);
5588}
5589
Jeff Johnson295189b2012-06-20 16:38:30 -07005590/*
5591 * FUNCTION: wlan_hdd_cfg80211_connect_start
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305592 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -07005593 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305594int wlan_hdd_cfg80211_connect_start( hdd_adapter_t *pAdapter,
Jeff Johnson32d95a32012-09-10 13:15:23 -07005595 const u8 *ssid, size_t ssid_len, const u8 *bssid, u8 operatingChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -07005596{
5597 int status = 0;
5598 hdd_wext_state_t *pWextState;
Yue Mae36e3552014-03-05 17:06:20 -08005599 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07005600 v_U32_t roamId;
5601 tCsrRoamProfile *pRoamProfile;
Jeff Johnson295189b2012-06-20 16:38:30 -07005602 eCsrAuthType RSNAuthType;
5603
5604 ENTER();
5605
5606 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Yue Mae36e3552014-03-05 17:06:20 -08005607 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
5608
5609 status = wlan_hdd_validate_context(pHddCtx);
5610 if (status)
5611 {
5612 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5613 "%s: HDD context is not valid!", __func__);
5614 return status;
5615 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305616
Jeff Johnson295189b2012-06-20 16:38:30 -07005617 if (SIR_MAC_MAX_SSID_LENGTH < ssid_len)
5618 {
5619 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wrong SSID len", __func__);
5620 return -EINVAL;
5621 }
5622
5623 pRoamProfile = &pWextState->roamProfile;
5624
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305625 if (pRoamProfile)
Jeff Johnson295189b2012-06-20 16:38:30 -07005626 {
Jeff Johnsone7245742012-09-05 17:12:55 -07005627 hdd_station_ctx_t *pHddStaCtx;
5628 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07005629
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305630 if (HDD_WMM_USER_MODE_NO_QOS ==
Jeff Johnson295189b2012-06-20 16:38:30 -07005631 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->WmmMode)
5632 {
5633 /*QoS not enabled in cfg file*/
5634 pRoamProfile->uapsd_mask = 0;
5635 }
5636 else
5637 {
5638 /*QoS enabled, update uapsd mask from cfg file*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305639 pRoamProfile->uapsd_mask =
Jeff Johnson295189b2012-06-20 16:38:30 -07005640 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask;
5641 }
5642
5643 pRoamProfile->SSIDs.numOfSSIDs = 1;
5644 pRoamProfile->SSIDs.SSIDList->SSID.length = ssid_len;
5645 vos_mem_zero(pRoamProfile->SSIDs.SSIDList->SSID.ssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305646 sizeof(pRoamProfile->SSIDs.SSIDList->SSID.ssId));
Jeff Johnson295189b2012-06-20 16:38:30 -07005647 vos_mem_copy((void *)(pRoamProfile->SSIDs.SSIDList->SSID.ssId),
5648 ssid, ssid_len);
5649
5650 if (bssid)
5651 {
5652 pRoamProfile->BSSIDs.numOfBSSIDs = 1;
5653 vos_mem_copy((void *)(pRoamProfile->BSSIDs.bssid), bssid,
5654 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305655 /* Save BSSID in seperate variable as well, as RoamProfile
5656 BSSID is getting zeroed out in the association process. And in
Jeff Johnson295189b2012-06-20 16:38:30 -07005657 case of join failure we should send valid BSSID to supplicant
5658 */
5659 vos_mem_copy((void *)(pWextState->req_bssId), bssid,
5660 WNI_CFG_BSSID_LEN);
5661 }
Dhanashri Atre51981c62013-06-13 11:47:57 -07005662 else
5663 {
5664 vos_mem_zero((void *)(pRoamProfile->BSSIDs.bssid),WNI_CFG_BSSID_LEN);
5665 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005666
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +05305667 hddLog(LOG1, FL("Connect to SSID: %s opertating Channel: %u"),
5668 pRoamProfile->SSIDs.SSIDList->SSID.ssId, operatingChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -07005669 if ((IW_AUTH_WPA_VERSION_WPA == pWextState->wpaVersion) ||
5670 (IW_AUTH_WPA_VERSION_WPA2 == pWextState->wpaVersion))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305671 {
Jeff Johnson295189b2012-06-20 16:38:30 -07005672 /*set gen ie*/
5673 hdd_SetGENIEToCsr(pAdapter, &RSNAuthType);
5674 /*set auth*/
5675 hdd_set_csr_auth_type(pAdapter, RSNAuthType);
5676 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005677#ifdef FEATURE_WLAN_WAPI
5678 if (pAdapter->wapi_info.nWapiMode)
5679 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005680 hddLog(LOG1, "%s: Setting WAPI AUTH Type and Encryption Mode values", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005681 switch (pAdapter->wapi_info.wapiAuthMode)
5682 {
5683 case WAPI_AUTH_MODE_PSK:
5684 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005685 hddLog(LOG1, "%s: WAPI AUTH TYPE: PSK: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07005686 pAdapter->wapi_info.wapiAuthMode);
5687 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_PSK;
5688 break;
5689 }
5690 case WAPI_AUTH_MODE_CERT:
5691 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005692 hddLog(LOG1, "%s: WAPI AUTH TYPE: CERT: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07005693 pAdapter->wapi_info.wapiAuthMode);
5694 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE;
5695 break;
5696 }
5697 } // End of switch
5698 if ( pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_PSK ||
5699 pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_CERT)
5700 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005701 hddLog(LOG1, "%s: WAPI PAIRWISE/GROUP ENCRYPTION: WPI", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005702 pRoamProfile->AuthType.numEntries = 1;
5703 pRoamProfile->EncryptionType.numEntries = 1;
5704 pRoamProfile->EncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
5705 pRoamProfile->mcEncryptionType.numEntries = 1;
5706 pRoamProfile->mcEncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
5707 }
5708 }
5709#endif /* FEATURE_WLAN_WAPI */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05305710#ifdef WLAN_FEATURE_GTK_OFFLOAD
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05305711 /* Initializing gtkOffloadReqParams */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05305712 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
5713 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
5714 {
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05305715 memset(&pHddStaCtx->gtkOffloadReqParams, 0,
5716 sizeof (tSirGtkOffloadParams));
5717 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_DISABLE;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05305718 }
5719#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005720 pRoamProfile->csrPersona = pAdapter->device_mode;
5721
Jeff Johnson32d95a32012-09-10 13:15:23 -07005722 if( operatingChannel )
5723 {
5724 pRoamProfile->ChannelInfo.ChannelList = &operatingChannel;
5725 pRoamProfile->ChannelInfo.numOfChannels = 1;
5726 }
Chet Lanctot186b5732013-03-18 10:26:30 -07005727 else
5728 {
5729 pRoamProfile->ChannelInfo.ChannelList = NULL;
5730 pRoamProfile->ChannelInfo.numOfChannels = 0;
5731 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07005732 if ( (WLAN_HDD_IBSS == pAdapter->device_mode) && operatingChannel)
5733 {
5734 hdd_select_cbmode(pAdapter,operatingChannel);
5735 }
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +05305736
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08005737 /* change conn_state to connecting before sme_RoamConnect(), because sme_RoamConnect()
5738 * has a direct path to call hdd_smeRoamCallback(), which will change the conn_state
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305739 * If direct path, conn_state will be accordingly changed to NotConnected or Associated
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08005740 * by either hdd_AssociationCompletionHandler() or hdd_DisConnectHandler() in sme_RoamCallback()
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -08005741 * if sme_RomConnect is to be queued, Connecting state will remain until it is completed.
5742 */
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05305743 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
5744 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode)
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -08005745 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
5746 eConnectionState_Connecting);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305747
5748 status = sme_RoamConnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07005749 pAdapter->sessionId, pRoamProfile, &roamId);
5750
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05305751 if ((eHAL_STATUS_SUCCESS != status) &&
5752 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
5753 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +05305754
5755 {
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08005756 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: sme_RoamConnect (session %d) failed with "
5757 "status %d. -> NotConnected", __func__, pAdapter->sessionId, status);
5758 /* change back to NotAssociated */
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +05305759 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08005760 eConnectionState_NotConnected);
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +05305761 }
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -08005762
5763 pRoamProfile->ChannelInfo.ChannelList = NULL;
5764 pRoamProfile->ChannelInfo.numOfChannels = 0;
5765
Jeff Johnson295189b2012-06-20 16:38:30 -07005766 }
5767 else
5768 {
5769 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid Roam profile", __func__);
5770 return -EINVAL;
5771 }
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08005772 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07005773 return status;
5774}
5775
5776/*
5777 * FUNCTION: wlan_hdd_set_cfg80211_auth_type
5778 * This function is used to set the authentication type (OPEN/SHARED).
5779 *
5780 */
5781static int wlan_hdd_cfg80211_set_auth_type(hdd_adapter_t *pAdapter,
5782 enum nl80211_auth_type auth_type)
5783{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305784 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07005785 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
5786
5787 ENTER();
5788
5789 /*set authentication type*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305790 switch (auth_type)
Jeff Johnson295189b2012-06-20 16:38:30 -07005791 {
Jeff Johnson295189b2012-06-20 16:38:30 -07005792 case NL80211_AUTHTYPE_AUTOMATIC:
Gopichand Nakkala29149562013-05-10 21:43:41 +05305793 hddLog(VOS_TRACE_LEVEL_INFO,
5794 "%s: set authentication type to AUTOSWITCH", __func__);
5795 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_AUTOSWITCH;
5796 break;
5797
5798 case NL80211_AUTHTYPE_OPEN_SYSTEM:
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07005799#ifdef WLAN_FEATURE_VOWIFI_11R
5800 case NL80211_AUTHTYPE_FT:
5801#endif /* WLAN_FEATURE_VOWIFI_11R */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305802 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -07005803 "%s: set authentication type to OPEN", __func__);
5804 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
5805 break;
5806
5807 case NL80211_AUTHTYPE_SHARED_KEY:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305808 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -07005809 "%s: set authentication type to SHARED", __func__);
5810 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_SHARED_KEY;
5811 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005812#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -07005813 case NL80211_AUTHTYPE_NETWORK_EAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305814 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -07005815 "%s: set authentication type to CCKM WPA", __func__);
5816 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_CCKM_WPA;//eCSR_AUTH_TYPE_CCKM_RSN needs to be handled as well if required.
5817 break;
5818#endif
5819
5820
5821 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305822 hddLog(VOS_TRACE_LEVEL_ERROR,
5823 "%s: Unsupported authentication type %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07005824 auth_type);
5825 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_UNKNOWN;
5826 return -EINVAL;
5827 }
5828
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305829 pWextState->roamProfile.AuthType.authType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -07005830 pHddStaCtx->conn_info.authType;
5831 return 0;
5832}
5833
5834/*
5835 * FUNCTION: wlan_hdd_set_akm_suite
5836 * This function is used to set the key mgmt type(PSK/8021x).
5837 *
5838 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305839static int wlan_hdd_set_akm_suite( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07005840 u32 key_mgmt
5841 )
5842{
5843 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
5844 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305845
Jeff Johnson295189b2012-06-20 16:38:30 -07005846 /*set key mgmt type*/
5847 switch(key_mgmt)
5848 {
5849 case WLAN_AKM_SUITE_PSK:
Gopichand Nakkala356fb102013-03-06 12:34:04 +05305850#ifdef WLAN_FEATURE_VOWIFI_11R
5851 case WLAN_AKM_SUITE_FT_PSK:
5852#endif
5853 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to PSK",
Jeff Johnson295189b2012-06-20 16:38:30 -07005854 __func__);
5855 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_PSK;
5856 break;
5857
5858 case WLAN_AKM_SUITE_8021X:
Gopichand Nakkala356fb102013-03-06 12:34:04 +05305859#ifdef WLAN_FEATURE_VOWIFI_11R
5860 case WLAN_AKM_SUITE_FT_8021X:
5861#endif
5862 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to 8021x",
Jeff Johnson295189b2012-06-20 16:38:30 -07005863 __func__);
5864 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
5865 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005866#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -07005867#define WLAN_AKM_SUITE_CCKM 0x00409600 /* Should be in ieee802_11_defs.h */
5868#define IW_AUTH_KEY_MGMT_CCKM 8 /* Should be in linux/wireless.h */
5869 case WLAN_AKM_SUITE_CCKM:
5870 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to CCKM",
5871 __func__);
5872 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_CCKM;
5873 break;
5874#endif
Leela Venkata Kiran Kumar Reddy Chiralae208a832014-04-27 22:34:25 -07005875#ifndef WLAN_AKM_SUITE_OSEN
5876#define WLAN_AKM_SUITE_OSEN 0x506f9a01 /* Should be in ieee802_11_defs.h */
5877 case WLAN_AKM_SUITE_OSEN:
5878 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to OSEN",
5879 __func__);
5880 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
5881 break;
5882#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005883
5884 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305885 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported key mgmt type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07005886 __func__, key_mgmt);
5887 return -EINVAL;
5888
5889 }
5890 return 0;
5891}
5892
5893/*
5894 * FUNCTION: wlan_hdd_cfg80211_set_cipher
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305895 * This function is used to set the encryption type
Jeff Johnson295189b2012-06-20 16:38:30 -07005896 * (NONE/WEP40/WEP104/TKIP/CCMP).
5897 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305898static int wlan_hdd_cfg80211_set_cipher( hdd_adapter_t *pAdapter,
5899 u32 cipher,
Jeff Johnson295189b2012-06-20 16:38:30 -07005900 bool ucast
5901 )
5902{
5903 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305904 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07005905 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
5906
5907 ENTER();
5908
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305909 if (!cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -07005910 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305911 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: received cipher %d - considering none",
Jeff Johnson295189b2012-06-20 16:38:30 -07005912 __func__, cipher);
5913 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
5914 }
5915 else
5916 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305917
Jeff Johnson295189b2012-06-20 16:38:30 -07005918 /*set encryption method*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305919 switch (cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -07005920 {
5921 case IW_AUTH_CIPHER_NONE:
5922 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
5923 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305924
Jeff Johnson295189b2012-06-20 16:38:30 -07005925 case WLAN_CIPHER_SUITE_WEP40:
Gopichand Nakkala29149562013-05-10 21:43:41 +05305926 encryptionType = eCSR_ENCRYPT_TYPE_WEP40;
Jeff Johnson295189b2012-06-20 16:38:30 -07005927 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305928
Jeff Johnson295189b2012-06-20 16:38:30 -07005929 case WLAN_CIPHER_SUITE_WEP104:
Gopichand Nakkala29149562013-05-10 21:43:41 +05305930 encryptionType = eCSR_ENCRYPT_TYPE_WEP104;
Jeff Johnson295189b2012-06-20 16:38:30 -07005931 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305932
Jeff Johnson295189b2012-06-20 16:38:30 -07005933 case WLAN_CIPHER_SUITE_TKIP:
5934 encryptionType = eCSR_ENCRYPT_TYPE_TKIP;
5935 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305936
Jeff Johnson295189b2012-06-20 16:38:30 -07005937 case WLAN_CIPHER_SUITE_CCMP:
5938 encryptionType = eCSR_ENCRYPT_TYPE_AES;
5939 break;
5940#ifdef FEATURE_WLAN_WAPI
5941 case WLAN_CIPHER_SUITE_SMS4:
5942 encryptionType = eCSR_ENCRYPT_TYPE_WPI;
5943 break;
5944#endif
5945
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005946#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -07005947 case WLAN_CIPHER_SUITE_KRK:
5948 encryptionType = eCSR_ENCRYPT_TYPE_KRK;
5949 break;
5950#endif
5951 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305952 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported cipher type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07005953 __func__, cipher);
5954 return -EOPNOTSUPP;
5955 }
5956 }
5957
5958 if (ucast)
5959 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305960 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting unicast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07005961 __func__, encryptionType);
5962 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
5963 pWextState->roamProfile.EncryptionType.numEntries = 1;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305964 pWextState->roamProfile.EncryptionType.encryptionType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -07005965 encryptionType;
5966 }
5967 else
5968 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305969 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting mcast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07005970 __func__, encryptionType);
5971 pHddStaCtx->conn_info.mcEncryptionType = encryptionType;
5972 pWextState->roamProfile.mcEncryptionType.numEntries = 1;
5973 pWextState->roamProfile.mcEncryptionType.encryptionType[0] = encryptionType;
5974 }
5975
5976 return 0;
5977}
5978
5979
5980/*
5981 * FUNCTION: wlan_hdd_cfg80211_set_ie
5982 * This function is used to parse WPA/RSN IE's.
5983 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305984int wlan_hdd_cfg80211_set_ie( hdd_adapter_t *pAdapter,
5985 u8 *ie,
Jeff Johnson295189b2012-06-20 16:38:30 -07005986 size_t ie_len
5987 )
5988{
5989 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
5990 u8 *genie = ie;
5991 v_U16_t remLen = ie_len;
5992#ifdef FEATURE_WLAN_WAPI
5993 v_U32_t akmsuite[MAX_NUM_AKM_SUITES];
5994 u16 *tmp;
5995 v_U16_t akmsuiteCount;
5996 int *akmlist;
5997#endif
5998 ENTER();
5999
6000 /* clear previous assocAddIE */
6001 pWextState->assocAddIE.length = 0;
6002 pWextState->roamProfile.bWPSAssociation = VOS_FALSE;
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -07006003 pWextState->roamProfile.bOSENAssociation = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07006004
6005 while (remLen >= 2)
6006 {
6007 v_U16_t eLen = 0;
6008 v_U8_t elementId;
6009 elementId = *genie++;
6010 eLen = *genie++;
6011 remLen -= 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306012
Arif Hussain6d2a3322013-11-17 19:50:10 -08006013 hddLog(VOS_TRACE_LEVEL_INFO, "%s: IE[0x%X], LEN[%d]",
Jeff Johnson295189b2012-06-20 16:38:30 -07006014 __func__, elementId, eLen);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306015
6016 switch ( elementId )
Jeff Johnson295189b2012-06-20 16:38:30 -07006017 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306018 case DOT11F_EID_WPA:
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07006019 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 -07006020 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306021 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07006022 "%s: Invalid WPA IE", __func__);
6023 return -EINVAL;
6024 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306025 else if (0 == memcmp(&genie[0], "\x00\x50\xf2\x04", 4))
Jeff Johnson295189b2012-06-20 16:38:30 -07006026 {
6027 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306028 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPS IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -07006029 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306030
Jeff Johnson295189b2012-06-20 16:38:30 -07006031 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
6032 {
Jeff Johnson902c9832012-12-10 14:28:09 -08006033 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE. "
6034 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -07006035 VOS_ASSERT(0);
6036 return -ENOMEM;
6037 }
6038 // WSC IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
6039 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
6040 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306041
Jeff Johnson295189b2012-06-20 16:38:30 -07006042 pWextState->roamProfile.bWPSAssociation = VOS_TRUE;
6043 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
6044 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
6045 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306046 else if (0 == memcmp(&genie[0], "\x00\x50\xf2", 3))
6047 {
Jeff Johnson295189b2012-06-20 16:38:30 -07006048 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPA IE (len %d)",__func__, eLen + 2);
6049 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
6050 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2) /*ie_len*/);
6051 pWextState->roamProfile.pWPAReqIE = pWextState->WPARSNIE;
6052 pWextState->roamProfile.nWPAReqIELength = eLen + 2;//ie_len;
6053 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306054 else if ( (0 == memcmp(&genie[0], P2P_OUI_TYPE,
Kiet Lam8da98992013-11-21 15:59:07 +05306055 P2P_OUI_TYPE_SIZE)))
Jeff Johnson295189b2012-06-20 16:38:30 -07006056 {
6057 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306058 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set P2P IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -07006059 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306060
Jeff Johnson295189b2012-06-20 16:38:30 -07006061 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
6062 {
Jeff Johnson902c9832012-12-10 14:28:09 -08006063 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
6064 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -07006065 VOS_ASSERT(0);
6066 return -ENOMEM;
6067 }
6068 // P2P IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
6069 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
6070 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306071
Jeff Johnson295189b2012-06-20 16:38:30 -07006072 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
6073 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
6074 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006075#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306076 else if ( (0 == memcmp(&genie[0], WFD_OUI_TYPE,
6077 WFD_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07006078 /*Consider WFD IE, only for P2P Client */
6079 && (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
6080 {
6081 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306082 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WFD IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -07006083 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306084
Jeff Johnson295189b2012-06-20 16:38:30 -07006085 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
6086 {
Jeff Johnson902c9832012-12-10 14:28:09 -08006087 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
6088 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -07006089 VOS_ASSERT(0);
6090 return -ENOMEM;
6091 }
6092 // WFD IE is saved to Additional IE ; it should be accumulated to handle
6093 // WPS IE + P2P IE + WFD IE
6094 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
6095 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306096
Jeff Johnson295189b2012-06-20 16:38:30 -07006097 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
6098 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
6099 }
6100#endif
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07006101 /* Appending HS 2.0 Indication Element in Assiciation Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306102 else if ( (0 == memcmp(&genie[0], HS20_OUI_TYPE,
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07006103 HS20_OUI_TYPE_SIZE)) )
6104 {
6105 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306106 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set HS20 IE(len %d)",
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07006107 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07006108
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07006109 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
6110 {
Jeff Johnson902c9832012-12-10 14:28:09 -08006111 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
6112 "Need bigger buffer space");
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07006113 VOS_ASSERT(0);
6114 return -ENOMEM;
6115 }
6116 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
6117 pWextState->assocAddIE.length += eLen + 2;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07006118
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07006119 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
6120 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
6121 }
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -07006122 /* Appending OSEN Information Element in Assiciation Request */
6123 else if ( (0 == memcmp(&genie[0], OSEN_OUI_TYPE,
6124 OSEN_OUI_TYPE_SIZE)) )
6125 {
6126 v_U16_t curAddIELen = pWextState->assocAddIE.length;
6127 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set OSEN IE(len %d)",
6128 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07006129
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -07006130 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
6131 {
6132 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
6133 "Need bigger buffer space");
6134 VOS_ASSERT(0);
6135 return -ENOMEM;
6136 }
6137 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
6138 pWextState->assocAddIE.length += eLen + 2;
6139
6140 pWextState->roamProfile.bOSENAssociation = VOS_TRUE;
6141 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
6142 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
6143 }
6144
6145 break;
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -07006146 if (WLAN_HDD_IBSS == pAdapter->device_mode) {
6147
6148 /* populating as ADDIE in beacon frames */
6149 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
6150 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, genie - 2, eLen + 2,
6151 NULL, eANI_BOOLEAN_FALSE)== eHAL_STATUS_SUCCESS)
6152 {
6153 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
6154 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
6155 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
6156 {
6157 hddLog(LOGE,
6158 "Coldn't pass "
6159 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
6160 }
6161 }/* ccmCfgSetStr(,WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, , )*/
6162 else
6163 hddLog(LOGE,
6164 "Could not pass on "
6165 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
6166
6167 /* IBSS mode doesn't contain params->proberesp_ies still
6168 beaconIE's need to be populated in probe response frames */
6169 if ( (NULL != (genie - 2)) && (0 != eLen + 2) )
6170 {
6171 u16 rem_probe_resp_ie_len = eLen + 2;
6172 u8 probe_rsp_ie_len[3] = {0};
6173 u8 counter = 0;
6174
6175 /* Check Probe Resp Length if it is greater then 255 then
6176 Store Probe Rsp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1
6177 & WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are
6178 not able Store More then 255 bytes into One Variable */
6179
6180 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
6181 {
6182 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
6183 {
6184 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
6185 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
6186 }
6187 else
6188 {
6189 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
6190 rem_probe_resp_ie_len = 0;
6191 }
6192 }
6193
6194 rem_probe_resp_ie_len = 0;
6195
6196 if (probe_rsp_ie_len[0] > 0)
6197 {
6198 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
6199 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
6200 (tANI_U8*)(genie - 2),
6201 probe_rsp_ie_len[0], NULL,
6202 eANI_BOOLEAN_FALSE)
6203 == eHAL_STATUS_FAILURE)
6204 {
6205 hddLog(LOGE,
6206 "Could not pass"
6207 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
6208 }
6209 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
6210 }
6211
6212 if (probe_rsp_ie_len[1] > 0)
6213 {
6214 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
6215 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
6216 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
6217 probe_rsp_ie_len[1], NULL,
6218 eANI_BOOLEAN_FALSE)
6219 == eHAL_STATUS_FAILURE)
6220 {
6221 hddLog(LOGE,
6222 "Could not pass"
6223 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
6224 }
6225 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
6226 }
6227
6228 if (probe_rsp_ie_len[2] > 0)
6229 {
6230 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
6231 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
6232 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
6233 probe_rsp_ie_len[2], NULL,
6234 eANI_BOOLEAN_FALSE)
6235 == eHAL_STATUS_FAILURE)
6236 {
6237 hddLog(LOGE,
6238 "Could not pass"
6239 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
6240 }
6241 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
6242 }
6243
6244 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
6245 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
6246 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
6247 {
6248 hddLog(LOGE,
6249 "Could not pass"
6250 "on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
6251 }
6252 }
6253 else
6254 {
6255 // Reset WNI_CFG_PROBE_RSP Flags
6256 wlan_hdd_reset_prob_rspies(pAdapter);
6257
6258 hddLog(VOS_TRACE_LEVEL_INFO,
6259 "%s: No Probe Response IE received in set beacon",
6260 __func__);
6261 }
6262 } /* end of if (WLAN_HDD_IBSS == pAdapter->device_mode) */
Jeff Johnson295189b2012-06-20 16:38:30 -07006263 break;
6264 case DOT11F_EID_RSN:
6265 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set RSN IE(len %d)",__func__, eLen + 2);
6266 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
6267 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2)/*ie_len*/);
6268 pWextState->roamProfile.pRSNReqIE = pWextState->WPARSNIE;
6269 pWextState->roamProfile.nRSNReqIELength = eLen + 2; //ie_len;
6270 break;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07006271 /* Appending Extended Capabilities with Interworking bit set in Assoc Req */
6272 case DOT11F_EID_EXTCAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306273 {
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07006274 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306275 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set Extended CAPS IE(len %d)",
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07006276 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306277
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07006278 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
6279 {
Jeff Johnson902c9832012-12-10 14:28:09 -08006280 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
6281 "Need bigger buffer space");
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07006282 VOS_ASSERT(0);
6283 return -ENOMEM;
6284 }
6285 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
6286 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306287
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07006288 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
6289 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
6290 break;
6291 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006292#ifdef FEATURE_WLAN_WAPI
6293 case WLAN_EID_WAPI:
6294 pAdapter->wapi_info.nWapiMode = 1; //Setting WAPI Mode to ON=1
Jeff Johnson0299d0a2013-10-30 12:37:43 -07006295 hddLog(VOS_TRACE_LEVEL_INFO, "WAPI MODE IS %u",
Jeff Johnson295189b2012-06-20 16:38:30 -07006296 pAdapter->wapi_info.nWapiMode);
6297 tmp = (u16 *)ie;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306298 tmp = tmp + 2; // Skip element Id and Len, Version
Jeff Johnson295189b2012-06-20 16:38:30 -07006299 akmsuiteCount = WPA_GET_LE16(tmp);
6300 tmp = tmp + 1;
6301 akmlist = (int *)(tmp);
6302 if(akmsuiteCount <= MAX_NUM_AKM_SUITES)
6303 {
6304 memcpy(akmsuite, akmlist, (4*akmsuiteCount));
6305 }
6306 else
6307 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08006308 hddLog(VOS_TRACE_LEVEL_FATAL, "Invalid akmSuite count");
Jeff Johnson295189b2012-06-20 16:38:30 -07006309 VOS_ASSERT(0);
6310 return -EINVAL;
6311 }
6312
6313 if (WAPI_PSK_AKM_SUITE == akmsuite[0])
6314 {
6315 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO PSK",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006316 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006317 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_PSK;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306318 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006319 if (WAPI_CERT_AKM_SUITE == akmsuite[0])
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306320 {
Jeff Johnson295189b2012-06-20 16:38:30 -07006321 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO CERTIFICATE",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006322 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006323 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_CERT;
6324 }
6325 break;
6326#endif
6327 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306328 hddLog (VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07006329 "%s Set UNKNOWN IE %X", __func__, elementId);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07006330 /* when Unknown IE is received we should break and continue
6331 * to the next IE in the buffer instead we were returning
6332 * so changing this to break */
6333 break;
Jeff Johnson295189b2012-06-20 16:38:30 -07006334 }
6335 genie += eLen;
6336 remLen -= eLen;
6337 }
6338 EXIT();
6339 return 0;
6340}
6341
6342/*
Gopichand Nakkala18f0c262013-05-07 23:25:08 +05306343 * FUNCTION: hdd_isWPAIEPresent
6344 * Parse the received IE to find the WPA IE
6345 *
6346 */
6347static bool hdd_isWPAIEPresent(u8 *ie, u8 ie_len)
6348{
6349 v_U8_t eLen = 0;
6350 v_U16_t remLen = ie_len;
6351 v_U8_t elementId = 0;
6352
6353 while (remLen >= 2)
6354 {
6355 elementId = *ie++;
6356 eLen = *ie++;
6357 remLen -= 2;
6358 if (eLen > remLen)
6359 {
6360 hddLog(VOS_TRACE_LEVEL_ERROR,
6361 "%s: IE length is wrong %d", __func__, eLen);
6362 return FALSE;
6363 }
6364 if ((elementId == DOT11F_EID_WPA) && (remLen > 5))
6365 {
6366 /* OUI - 0x00 0X50 0XF2
6367 WPA Information Element - 0x01
6368 WPA version - 0x01*/
6369 if (0 == memcmp(&ie[0], "\x00\x50\xf2\x01\x01", 5))
6370 return TRUE;
6371 }
6372 ie += eLen;
6373 remLen -= eLen;
6374 }
6375 return FALSE;
6376}
6377
6378/*
Jeff Johnson295189b2012-06-20 16:38:30 -07006379 * FUNCTION: wlan_hdd_cfg80211_set_privacy
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306380 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -07006381 * parameters during connect operation.
6382 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306383int wlan_hdd_cfg80211_set_privacy( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07006384 struct cfg80211_connect_params *req
6385 )
6386{
6387 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306388 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07006389 ENTER();
6390
6391 /*set wpa version*/
6392 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
6393
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306394 if (req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -07006395 {
Gopichand Nakkala781ded42013-06-28 12:10:45 +05306396 if (NL80211_WPA_VERSION_1 == req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -07006397 {
6398 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
6399 }
6400 else if (NL80211_WPA_VERSION_2 == req->crypto.wpa_versions)
6401 {
6402 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
6403 }
6404 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306405
6406 hddLog(VOS_TRACE_LEVEL_INFO, "%s: set wpa version to %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07006407 pWextState->wpaVersion);
6408
6409 /*set authentication type*/
6410 status = wlan_hdd_cfg80211_set_auth_type(pAdapter, req->auth_type);
6411
6412 if (0 > status)
6413 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306414 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07006415 "%s: failed to set authentication type ", __func__);
6416 return status;
6417 }
6418
6419 /*set key mgmt type*/
6420 if (req->crypto.n_akm_suites)
6421 {
6422 status = wlan_hdd_set_akm_suite(pAdapter, req->crypto.akm_suites[0]);
6423 if (0 > status)
6424 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306425 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set akm suite",
Jeff Johnson295189b2012-06-20 16:38:30 -07006426 __func__);
6427 return status;
6428 }
6429 }
6430
6431 /*set pairwise cipher type*/
6432 if (req->crypto.n_ciphers_pairwise)
6433 {
6434 status = wlan_hdd_cfg80211_set_cipher(pAdapter,
6435 req->crypto.ciphers_pairwise[0], true);
6436 if (0 > status)
6437 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306438 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07006439 "%s: failed to set unicast cipher type", __func__);
6440 return status;
6441 }
6442 }
6443 else
6444 {
6445 /*Reset previous cipher suite to none*/
6446 status = wlan_hdd_cfg80211_set_cipher(pAdapter, 0, true);
6447 if (0 > status)
6448 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306449 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07006450 "%s: failed to set unicast cipher type", __func__);
6451 return status;
6452 }
6453 }
6454
6455 /*set group cipher type*/
6456 status = wlan_hdd_cfg80211_set_cipher(pAdapter, req->crypto.cipher_group,
6457 false);
6458
6459 if (0 > status)
6460 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306461 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set mcast cipher type",
Jeff Johnson295189b2012-06-20 16:38:30 -07006462 __func__);
6463 return status;
6464 }
6465
Chet Lanctot186b5732013-03-18 10:26:30 -07006466#ifdef WLAN_FEATURE_11W
6467 pWextState->roamProfile.MFPEnabled = (req->mfp == NL80211_MFP_REQUIRED);
6468#endif
6469
Jeff Johnson295189b2012-06-20 16:38:30 -07006470 /*parse WPA/RSN IE, and set the correspoing fileds in Roam profile*/
6471 if (req->ie_len)
6472 {
6473 status = wlan_hdd_cfg80211_set_ie(pAdapter, req->ie, req->ie_len);
6474 if ( 0 > status)
6475 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306476 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse the WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -07006477 __func__);
6478 return status;
6479 }
6480 }
6481
6482 /*incase of WEP set default key information*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306483 if (req->key && req->key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -07006484 {
6485 if ( (WLAN_CIPHER_SUITE_WEP40 == req->crypto.ciphers_pairwise[0])
6486 || (WLAN_CIPHER_SUITE_WEP104 == req->crypto.ciphers_pairwise[0])
6487 )
6488 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306489 if ( IW_AUTH_KEY_MGMT_802_1X
Jeff Johnson295189b2012-06-20 16:38:30 -07006490 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X ))
6491 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306492 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Dynamic WEP not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -07006493 __func__);
6494 return -EOPNOTSUPP;
6495 }
6496 else
6497 {
6498 u8 key_len = req->key_len;
6499 u8 key_idx = req->key_idx;
6500
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306501 if ((eCSR_SECURITY_WEP_KEYSIZE_MAX_BYTES >= key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -07006502 && (CSR_MAX_NUM_KEY > key_idx)
6503 )
6504 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306505 hddLog(VOS_TRACE_LEVEL_INFO,
6506 "%s: setting default wep key, key_idx = %hu key_len %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07006507 __func__, key_idx, key_len);
6508 vos_mem_copy(
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306509 &pWextState->roamProfile.Keys.KeyMaterial[key_idx][0],
Jeff Johnson295189b2012-06-20 16:38:30 -07006510 req->key, key_len);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306511 pWextState->roamProfile.Keys.KeyLength[key_idx] =
Jeff Johnson295189b2012-06-20 16:38:30 -07006512 (u8)key_len;
6513 pWextState->roamProfile.Keys.defaultIndex = (u8)key_idx;
6514 }
6515 }
6516 }
6517 }
6518
6519 return status;
6520}
6521
6522/*
Vinay Krishna Eranna21042322014-01-08 19:21:39 +05306523 * FUNCTION: wlan_hdd_try_disconnect
6524 * This function is used to disconnect from previous
6525 * connection
6526 */
6527static int wlan_hdd_try_disconnect( hdd_adapter_t *pAdapter )
6528{
6529 long ret = 0;
6530 hdd_station_ctx_t *pHddStaCtx;
6531 eMib_dot11DesiredBssType connectedBssType;
6532
6533 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6534
6535 hdd_connGetConnectedBssType(pHddStaCtx,&connectedBssType );
6536
6537 if((eMib_dot11DesiredBssType_independent == connectedBssType) ||
6538 (eConnectionState_Associated == pHddStaCtx->conn_info.connState) ||
6539 (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState))
6540 {
6541 /* Issue disconnect to CSR */
6542 INIT_COMPLETION(pAdapter->disconnect_comp_var);
6543 if( eHAL_STATUS_SUCCESS ==
6544 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
6545 pAdapter->sessionId,
6546 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
6547 {
6548 ret = wait_for_completion_interruptible_timeout(
6549 &pAdapter->disconnect_comp_var,
6550 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
6551 if (0 >= ret)
6552 {
6553 hddLog(LOGE, FL("Failed to receive disconnect event"));
6554 return -EALREADY;
6555 }
6556 }
6557 }
6558 else if(eConnectionState_Disconnecting == pHddStaCtx->conn_info.connState)
6559 {
6560 ret = wait_for_completion_interruptible_timeout(
6561 &pAdapter->disconnect_comp_var,
6562 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
6563 if (0 >= ret)
6564 {
6565 hddLog(LOGE, FL("Failed to receive disconnect event"));
6566 return -EALREADY;
6567 }
6568 }
6569
6570 return 0;
6571}
6572
6573/*
Jeff Johnson295189b2012-06-20 16:38:30 -07006574 * FUNCTION: wlan_hdd_cfg80211_set_privacy
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306575 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -07006576 * parameters during connect operation.
6577 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306578static int wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07006579 struct net_device *ndev,
6580 struct cfg80211_connect_params *req
6581 )
6582{
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306583 int status;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306584 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -07006585 VOS_STATUS exitbmpsStatus = VOS_STATUS_E_INVAL;
Rajesh Chauhana0516c62014-01-30 16:11:18 -08006586 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07006587
6588 ENTER();
6589
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05306590 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
6591 TRACE_CODE_HDD_CFG80211_CONNECT,
6592 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306593 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05306594 "%s: device_mode = %s (%d)", __func__,
6595 hdd_device_modetoString(pAdapter->device_mode),
6596 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07006597
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306598 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -08006599 if (!pHddCtx)
6600 {
6601 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6602 "%s: HDD context is null", __func__);
6603 return VOS_STATUS_E_FAILURE;
6604 }
6605
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306606 status = wlan_hdd_validate_context(pHddCtx);
6607
6608 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -07006609 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306610 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6611 "%s: HDD context is not valid", __func__);
6612 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -07006613 }
6614
6615#ifdef WLAN_BTAMP_FEATURE
6616 //Infra connect not supported when AMP traffic is on.
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306617 if( VOS_TRUE == WLANBAP_AmpSessionOn() )
Jeff Johnson295189b2012-06-20 16:38:30 -07006618 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306619 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07006620 "%s: No connection when AMP is on", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08006621 return -ECONNREFUSED;
Jeff Johnson295189b2012-06-20 16:38:30 -07006622 }
6623#endif
Vinay Krishna Eranna21042322014-01-08 19:21:39 +05306624
6625 //If Device Mode is Station Concurrent Sessions Exit BMps
6626 //P2P Mode will be taken care in Open/close adapter
6627 if((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
6628 (vos_concurrent_sessions_running()))
6629 {
6630 exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
6631 }
6632
6633 /*Try disconnecting if already in connected state*/
6634 status = wlan_hdd_try_disconnect(pAdapter);
6635 if ( 0 > status)
6636 {
6637 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
6638 " connection"));
6639 return -EALREADY;
6640 }
6641
Jeff Johnson295189b2012-06-20 16:38:30 -07006642 /*initialise security parameters*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306643 status = wlan_hdd_cfg80211_set_privacy(pAdapter, req);
Jeff Johnson295189b2012-06-20 16:38:30 -07006644
6645 if ( 0 > status)
6646 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306647 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security params",
Jeff Johnson295189b2012-06-20 16:38:30 -07006648 __func__);
6649 return status;
6650 }
6651
Mohit Khanna765234a2012-09-11 15:08:35 -07006652 if ( req->channel )
6653 {
6654 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
6655 req->ssid_len, req->bssid,
6656 req->channel->hw_value);
6657 }
6658 else
6659 {
6660 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306661 req->ssid_len, req->bssid, 0);
Mohit Khanna765234a2012-09-11 15:08:35 -07006662 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006663
6664 if (0 > status)
6665 {
6666 //ReEnable BMPS if disabled
6667 if((VOS_STATUS_SUCCESS == exitbmpsStatus) &&
6668 (NULL != pHddCtx))
6669 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306670 if (pHddCtx->hdd_wlan_suspended)
6671 {
6672 hdd_set_pwrparams(pHddCtx);
6673 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006674 //ReEnable Bmps and Imps back
6675 hdd_enable_bmps_imps(pHddCtx);
6676 }
6677
6678 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: connect failed", __func__);
6679 return status;
6680 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306681 pHddCtx->isAmpAllowed = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07006682 EXIT();
6683 return status;
6684}
6685
6686
6687/*
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05306688 * FUNCTION: wlan_hdd_disconnect
6689 * This function is used to issue a disconnect request to SME
6690 */
6691int wlan_hdd_disconnect( hdd_adapter_t *pAdapter, u16 reason )
6692{
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306693 int status;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05306694 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306695 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
6696
6697 status = wlan_hdd_validate_context(pHddCtx);
6698
6699 if (0 != status)
6700 {
6701 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6702 "%s: HDD context is not valid", __func__);
6703 return status;
6704 }
6705
6706 pHddCtx->isAmpAllowed = VOS_TRUE;
Vinay Krishna Erannab09d3e72014-03-26 21:23:55 +05306707 pHddStaCtx->conn_info.connState = eConnectionState_Disconnecting;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05306708 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306709
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05306710 /*issue disconnect*/
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +05306711
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05306712 status = sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
6713 pAdapter->sessionId, reason);
6714
6715 if ( 0 != status )
6716 {
6717 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006718 "%s csrRoamDisconnect failure, returned %d",
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05306719 __func__, (int)status );
6720 return -EINVAL;
6721 }
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +05306722 status = wait_for_completion_interruptible_timeout(
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05306723 &pAdapter->disconnect_comp_var,
6724 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +05306725 if (!status)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306726 {
6727 hddLog(VOS_TRACE_LEVEL_ERROR,
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +05306728 "%s: Failed to disconnect, timed out", __func__);
6729 return -ETIMEDOUT;
6730 }
6731 else if (status == -ERESTARTSYS)
6732 {
6733 hddLog(VOS_TRACE_LEVEL_ERROR,
6734 "%s: Failed to disconnect, wait interrupted", __func__);
6735 return status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306736 }
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05306737 /*stop tx queues*/
6738 netif_tx_disable(pAdapter->dev);
6739 netif_carrier_off(pAdapter->dev);
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +05306740 return 0;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05306741}
6742
6743
6744/*
Jeff Johnson295189b2012-06-20 16:38:30 -07006745 * FUNCTION: wlan_hdd_cfg80211_disconnect
6746 * This function is used to issue a disconnect request to SME
6747 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306748static int wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07006749 struct net_device *dev,
6750 u16 reason
6751 )
6752{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306753 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
6754 tCsrRoamProfile *pRoamProfile =
Jeff Johnson295189b2012-06-20 16:38:30 -07006755 &(WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter))->roamProfile;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306756 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07006757 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkala4327a152013-03-04 23:22:42 -08006758 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaaa353782013-05-17 20:36:22 +05306759#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08006760 tANI_U8 staIdx;
6761#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306762
Jeff Johnson295189b2012-06-20 16:38:30 -07006763 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306764
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05306765 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
6766 TRACE_CODE_HDD_CFG80211_DISCONNECT,
6767 pAdapter->sessionId, reason));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05306768 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s(%d)",
6769 __func__, hdd_device_modetoString(pAdapter->device_mode),
6770 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07006771
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306772 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Disconnect called with reason code %d",
6773 __func__, reason);
Jeff Johnson295189b2012-06-20 16:38:30 -07006774
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306775 status = wlan_hdd_validate_context(pHddCtx);
6776
6777 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -07006778 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306779 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6780 "%s: HDD context is not valid", __func__);
6781 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -07006782 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306783
Jeff Johnson295189b2012-06-20 16:38:30 -07006784 if (NULL != pRoamProfile)
6785 {
6786 /*issue disconnect request to SME, if station is in connected state*/
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +05306787 if ((pHddStaCtx->conn_info.connState == eConnectionState_Associated) ||
6788 (pHddStaCtx->conn_info.connState == eConnectionState_Connecting))
Jeff Johnson295189b2012-06-20 16:38:30 -07006789 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306790 eCsrRoamDisconnectReason reasonCode =
Jeff Johnson295189b2012-06-20 16:38:30 -07006791 eCSR_DISCONNECT_REASON_UNSPECIFIED;
Gopichand Nakkalaaa353782013-05-17 20:36:22 +05306792 hdd_scaninfo_t *pScanInfo;
Jeff Johnson295189b2012-06-20 16:38:30 -07006793 switch(reason)
6794 {
6795 case WLAN_REASON_MIC_FAILURE:
6796 reasonCode = eCSR_DISCONNECT_REASON_MIC_ERROR;
6797 break;
6798
6799 case WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY:
6800 case WLAN_REASON_DISASSOC_AP_BUSY:
6801 case WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA:
6802 reasonCode = eCSR_DISCONNECT_REASON_DISASSOC;
6803 break;
6804
6805 case WLAN_REASON_PREV_AUTH_NOT_VALID:
6806 case WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA:
6807 reasonCode = eCSR_DISCONNECT_REASON_DEAUTH;
6808 break;
6809
6810 case WLAN_REASON_DEAUTH_LEAVING:
6811 default:
6812 reasonCode = eCSR_DISCONNECT_REASON_UNSPECIFIED;
6813 break;
6814 }
Gopichand Nakkalaaa353782013-05-17 20:36:22 +05306815 pScanInfo = &pHddCtx->scan_info;
6816 if (pScanInfo->mScanPending)
6817 {
Srinivas, Dasari138af4f2014-02-07 11:13:45 +05306818 hddLog(VOS_TRACE_LEVEL_INFO, "Disconnect is in progress, "
Gopichand Nakkalaaa353782013-05-17 20:36:22 +05306819 "Aborting Scan");
Srinivas, Dasari138af4f2014-02-07 11:13:45 +05306820 hdd_abort_mac_scan(pHddCtx, pAdapter->sessionId,
6821 eCSR_SCAN_ABORT_DEFAULT);
Gopichand Nakkalaaa353782013-05-17 20:36:22 +05306822 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006823
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08006824#ifdef FEATURE_WLAN_TDLS
6825 /* First clean up the tdls peers if any */
Gopichand Nakkala4327a152013-03-04 23:22:42 -08006826 for (staIdx = 0 ; staIdx < HDD_MAX_NUM_TDLS_STA; staIdx++)
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08006827 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -08006828 if ((pHddCtx->tdlsConnInfo[staIdx].sessionId == pAdapter->sessionId) &&
6829 (pHddCtx->tdlsConnInfo[staIdx].staId))
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08006830 {
Hoonki Lee11f7dda2013-02-14 16:55:44 -08006831 uint8 *mac;
Gopichand Nakkala4327a152013-03-04 23:22:42 -08006832 mac = pHddCtx->tdlsConnInfo[staIdx].peerMac.bytes;
Hoonki Lee11f7dda2013-02-14 16:55:44 -08006833 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07006834 "%s: call sme_DeleteTdlsPeerSta staId %d sessionId %d " MAC_ADDRESS_STR,
Gopichand Nakkala4327a152013-03-04 23:22:42 -08006835 __func__, pHddCtx->tdlsConnInfo[staIdx].staId, pAdapter->sessionId,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07006836 MAC_ADDR_ARRAY(mac));
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08006837 sme_DeleteTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala4327a152013-03-04 23:22:42 -08006838 pAdapter->sessionId,
6839 mac);
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08006840 }
6841 }
6842#endif
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +05306843 hddLog(LOG1, FL("Disconnecting with reasoncode:%u"), reasonCode);
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05306844 status = wlan_hdd_disconnect(pAdapter, reasonCode);
6845 if ( 0 != status )
Jeff Johnson295189b2012-06-20 16:38:30 -07006846 {
6847 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006848 "%s wlan_hdd_disconnect failure, returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07006849 __func__, (int)status );
6850 return -EINVAL;
6851 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006852 }
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +05306853 else
6854 {
6855 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unexpected cfg disconnect API"
6856 "called while in %d state", __func__,
6857 pHddStaCtx->conn_info.connState);
6858 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006859 }
6860 else
6861 {
6862 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid roam profile", __func__);
6863 }
6864
6865 return status;
6866}
6867
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05306868
Jeff Johnson295189b2012-06-20 16:38:30 -07006869/*
6870 * FUNCTION: wlan_hdd_cfg80211_set_privacy_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306871 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -07006872 * settings in IBSS mode.
6873 */
6874static int wlan_hdd_cfg80211_set_privacy_ibss(
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306875 hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07006876 struct cfg80211_ibss_params *params
6877 )
6878{
6879 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306880 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07006881 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
6882 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306883
Jeff Johnson295189b2012-06-20 16:38:30 -07006884 ENTER();
6885
6886 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
Ravi Joshib58ca0d2013-10-29 09:50:23 -07006887 vos_mem_zero(&pHddStaCtx->ibss_enc_key, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -07006888
6889 if (params->ie_len && ( NULL != params->ie) )
6890 {
Shailender Karmuchi67edd312013-06-18 16:30:48 -07006891 if (wlan_hdd_cfg80211_get_ie_ptr (params->ie,
6892 params->ie_len, WLAN_EID_RSN ))
Jeff Johnson295189b2012-06-20 16:38:30 -07006893 {
6894 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
6895 encryptionType = eCSR_ENCRYPT_TYPE_AES;
6896 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -07006897 else if ( hdd_isWPAIEPresent (params->ie, params->ie_len ))
Jeff Johnson295189b2012-06-20 16:38:30 -07006898 {
Shailender Karmuchi642e9812013-05-30 14:34:49 -07006899 tDot11fIEWPA dot11WPAIE;
6900 tHalHandle halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
Shailender Karmuchi67edd312013-06-18 16:30:48 -07006901 u8 *ie;
Shailender Karmuchi642e9812013-05-30 14:34:49 -07006902
Wilson Yang00256342013-10-10 23:13:38 -07006903 memset(&dot11WPAIE, 0, sizeof(dot11WPAIE));
Shailender Karmuchi67edd312013-06-18 16:30:48 -07006904 ie = wlan_hdd_cfg80211_get_ie_ptr (params->ie,
6905 params->ie_len, DOT11F_EID_WPA);
6906 if ( NULL != ie )
6907 {
6908 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
6909 // Unpack the WPA IE
6910 //Skip past the EID byte and length byte - and four byte WiFi OUI
6911 dot11fUnpackIeWPA((tpAniSirGlobal) halHandle,
6912 &ie[2+4],
6913 ie[1] - 4,
6914 &dot11WPAIE);
6915 /*Extract the multicast cipher, the encType for unicast
6916 cipher for wpa-none is none*/
6917 encryptionType =
6918 hdd_TranslateWPAToCsrEncryptionType(dot11WPAIE.multicast_cipher);
6919 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006920 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -07006921
Jeff Johnson295189b2012-06-20 16:38:30 -07006922 status = wlan_hdd_cfg80211_set_ie(pAdapter, params->ie, params->ie_len);
6923
6924 if (0 > status)
6925 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306926 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -07006927 __func__);
6928 return status;
6929 }
6930 }
6931
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306932 pWextState->roamProfile.AuthType.authType[0] =
6933 pHddStaCtx->conn_info.authType =
Jeff Johnson295189b2012-06-20 16:38:30 -07006934 eCSR_AUTH_TYPE_OPEN_SYSTEM;
6935
6936 if (params->privacy)
6937 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306938 /* Security enabled IBSS, At this time there is no information available
6939 * about the security paramters, so initialise the encryption type to
Jeff Johnson295189b2012-06-20 16:38:30 -07006940 * eCSR_ENCRYPT_TYPE_WEP40_STATICKEY.
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306941 * The correct security parameters will be updated later in
Jeff Johnson295189b2012-06-20 16:38:30 -07006942 * wlan_hdd_cfg80211_add_key */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306943 /* Hal expects encryption type to be set inorder
Jeff Johnson295189b2012-06-20 16:38:30 -07006944 *enable privacy bit in beacons */
6945
6946 encryptionType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
6947 }
Shailender Karmuchi642e9812013-05-30 14:34:49 -07006948 VOS_TRACE (VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
6949 "encryptionType=%d", encryptionType);
Jeff Johnson295189b2012-06-20 16:38:30 -07006950 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
6951 pWextState->roamProfile.EncryptionType.numEntries = 1;
6952 pWextState->roamProfile.EncryptionType.encryptionType[0] = encryptionType;
Jeff Johnson295189b2012-06-20 16:38:30 -07006953 return status;
6954}
6955
6956/*
6957 * FUNCTION: wlan_hdd_cfg80211_join_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306958 * This function is used to create/join an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -07006959 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306960static int wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07006961 struct net_device *dev,
6962 struct cfg80211_ibss_params *params
6963 )
6964{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306965 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Jeff Johnson295189b2012-06-20 16:38:30 -07006966 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
6967 tCsrRoamProfile *pRoamProfile;
6968 int status;
krunal sonie9002db2013-11-25 14:24:17 -08006969 bool alloc_bssid = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07006970 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306971 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07006972
6973 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306974
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05306975 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
6976 TRACE_CODE_HDD_CFG80211_JOIN_IBSS,
6977 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306978 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05306979 "%s: device_mode = %s (%d)", __func__,
6980 hdd_device_modetoString(pAdapter->device_mode),
6981 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07006982
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306983 status = wlan_hdd_validate_context(pHddCtx);
6984
6985 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -07006986 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306987 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6988 "%s: HDD context is not valid", __func__);
6989 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -07006990 }
6991
6992 if (NULL == pWextState)
6993 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08006994 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -07006995 __func__);
6996 return -EIO;
6997 }
6998
Vinay Krishna Eranna21042322014-01-08 19:21:39 +05306999 /*Try disconnecting if already in connected state*/
7000 status = wlan_hdd_try_disconnect(pAdapter);
7001 if ( 0 > status)
7002 {
7003 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
7004 " IBSS connection"));
7005 return -EALREADY;
7006 }
7007
Jeff Johnson295189b2012-06-20 16:38:30 -07007008 pRoamProfile = &pWextState->roamProfile;
7009
7010 if ( eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType )
7011 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307012 hddLog (VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007013 "%s Interface type is not set to IBSS", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007014 return -EINVAL;
7015 }
7016
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -07007017 /* BSSID is provided by upper layers hence no need to AUTO generate */
7018 if (NULL != params->bssid) {
7019 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
7020 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) {
7021 hddLog (VOS_TRACE_LEVEL_ERROR,
7022 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
7023 return -EIO;
7024 }
7025 }
krunal sonie9002db2013-11-25 14:24:17 -08007026 else if(pHddCtx->cfg_ini->isCoalesingInIBSSAllowed == 0)
7027 {
7028 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
7029 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
7030 {
7031 hddLog (VOS_TRACE_LEVEL_ERROR,
7032 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
7033 return -EIO;
7034 }
7035 params->bssid = vos_mem_malloc(sizeof(VOS_MAC_ADDR_SIZE));
7036 if (!params->bssid)
7037 {
7038 hddLog (VOS_TRACE_LEVEL_ERROR,
7039 "%s:Failed memory allocation", __func__);
7040 return -EIO;
7041 }
7042 vos_mem_copy((v_U8_t *)params->bssid,
7043 (v_U8_t *)&pHddCtx->cfg_ini->IbssBssid.bytes[0],
7044 VOS_MAC_ADDR_SIZE);
7045 alloc_bssid = VOS_TRUE;
7046 }
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -07007047
Jeff Johnson295189b2012-06-20 16:38:30 -07007048 /* Set Channel */
Yue Maf49ba872013-08-19 12:04:25 -07007049 if (NULL !=
7050#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
7051 params->chandef.chan)
7052#else
7053 params->channel)
7054#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007055 {
7056 u8 channelNum;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07007057 v_U32_t numChans = WNI_CFG_VALID_CHANNEL_LIST_LEN;
7058 v_U8_t validChan[WNI_CFG_VALID_CHANNEL_LIST_LEN];
7059 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
7060 int indx;
Jeff Johnson295189b2012-06-20 16:38:30 -07007061
7062 /* Get channel number */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307063 channelNum =
Yue Maf49ba872013-08-19 12:04:25 -07007064 ieee80211_frequency_to_channel(
7065#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
7066 params->chandef.chan->center_freq);
7067#else
7068 params->channel->center_freq);
7069#endif
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07007070
7071 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
7072 validChan, &numChans))
Jeff Johnson295189b2012-06-20 16:38:30 -07007073 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07007074 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid channel list",
7075 __func__);
7076 return -EOPNOTSUPP;
Jeff Johnson295189b2012-06-20 16:38:30 -07007077 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07007078
7079 for (indx = 0; indx < numChans; indx++)
Jeff Johnson295189b2012-06-20 16:38:30 -07007080 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07007081 if (channelNum == validChan[indx])
7082 {
7083 break;
7084 }
7085 }
7086 if (indx >= numChans)
7087 {
7088 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Not valid Channel %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07007089 __func__, channelNum);
7090 return -EINVAL;
7091 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07007092 /* Set the Operational Channel */
7093 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: set channel %d", __func__,
7094 channelNum);
7095 pRoamProfile->ChannelInfo.numOfChannels = 1;
7096 pHddStaCtx->conn_info.operationChannel = channelNum;
7097 pRoamProfile->ChannelInfo.ChannelList =
7098 &pHddStaCtx->conn_info.operationChannel;
Jeff Johnson295189b2012-06-20 16:38:30 -07007099 }
7100
7101 /* Initialize security parameters */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307102 status = wlan_hdd_cfg80211_set_privacy_ibss(pAdapter, params);
Jeff Johnson295189b2012-06-20 16:38:30 -07007103 if (status < 0)
7104 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307105 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security parameters",
Jeff Johnson295189b2012-06-20 16:38:30 -07007106 __func__);
7107 return status;
7108 }
7109
7110 /* Issue connect start */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307111 status = wlan_hdd_cfg80211_connect_start(pAdapter, params->ssid,
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07007112 params->ssid_len, params->bssid,
7113 pHddStaCtx->conn_info.operationChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -07007114
7115 if (0 > status)
7116 {
7117 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: connect failed", __func__);
7118 return status;
7119 }
7120
krunal sonie9002db2013-11-25 14:24:17 -08007121 if (NULL != params->bssid &&
7122 pHddCtx->cfg_ini->isCoalesingInIBSSAllowed == 0 &&
7123 alloc_bssid == VOS_TRUE)
7124 {
7125 vos_mem_free(params->bssid);
7126 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007127 return 0;
7128}
7129
7130/*
7131 * FUNCTION: wlan_hdd_cfg80211_leave_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307132 * This function is used to leave an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -07007133 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307134static int wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07007135 struct net_device *dev
7136 )
7137{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307138 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Jeff Johnson295189b2012-06-20 16:38:30 -07007139 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
7140 tCsrRoamProfile *pRoamProfile;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307141 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7142 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07007143
7144 ENTER();
7145
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307146 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7147 TRACE_CODE_HDD_CFG80211_LEAVE_IBSS,
7148 pAdapter->sessionId, eCSR_DISCONNECT_REASON_IBSS_LEAVE));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307149 status = wlan_hdd_validate_context(pHddCtx);
7150
7151 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007152 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307153 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7154 "%s: HDD context is not valid", __func__);
7155 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007156 }
7157
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05307158 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)", __func__,
7159 hdd_device_modetoString(pAdapter->device_mode),
7160 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07007161 if (NULL == pWextState)
7162 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08007163 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -07007164 __func__);
7165 return -EIO;
7166 }
7167
7168 pRoamProfile = &pWextState->roamProfile;
7169
7170 /* Issue disconnect only if interface type is set to IBSS */
7171 if (eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType)
7172 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307173 hddLog (VOS_TRACE_LEVEL_ERROR, "%s: BSS Type is not set to IBSS",
Jeff Johnson295189b2012-06-20 16:38:30 -07007174 __func__);
7175 return -EINVAL;
7176 }
7177
7178 /* Issue Disconnect request */
7179 INIT_COMPLETION(pAdapter->disconnect_comp_var);
7180 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
7181 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
7182
7183 return 0;
7184}
7185
7186/*
7187 * FUNCTION: wlan_hdd_cfg80211_set_wiphy_params
7188 * This function is used to set the phy parameters
7189 * (RTS Threshold/FRAG Threshold/Retry Count etc ...)
7190 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307191static int wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07007192 u32 changed)
7193{
7194 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
7195 tHalHandle hHal = pHddCtx->hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307196 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07007197
7198 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307199 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7200 TRACE_CODE_HDD_CFG80211_SET_WIPHY_PARAMS,
7201 NO_SESSION, wiphy->rts_threshold));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307202 status = wlan_hdd_validate_context(pHddCtx);
7203
7204 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007205 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307206 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7207 "%s: HDD context is not valid", __func__);
7208 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007209 }
7210
Jeff Johnson295189b2012-06-20 16:38:30 -07007211 if (changed & WIPHY_PARAM_RTS_THRESHOLD)
7212 {
7213 u16 rts_threshold = (wiphy->rts_threshold == -1) ?
7214 WNI_CFG_RTS_THRESHOLD_STAMAX :
7215 wiphy->rts_threshold;
7216
7217 if ((WNI_CFG_RTS_THRESHOLD_STAMIN > rts_threshold) ||
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307218 (WNI_CFG_RTS_THRESHOLD_STAMAX < rts_threshold))
Jeff Johnson295189b2012-06-20 16:38:30 -07007219 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307220 hddLog(VOS_TRACE_LEVEL_ERROR,
7221 "%s: Invalid RTS Threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07007222 __func__, rts_threshold);
7223 return -EINVAL;
7224 }
7225
7226 if (0 != ccmCfgSetInt(hHal, WNI_CFG_RTS_THRESHOLD,
7227 rts_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307228 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -07007229 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307230 hddLog(VOS_TRACE_LEVEL_ERROR,
7231 "%s: ccmCfgSetInt failed for rts_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07007232 __func__, rts_threshold);
7233 return -EIO;
7234 }
7235
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307236 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set rts threshold %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07007237 rts_threshold);
7238 }
7239
7240 if (changed & WIPHY_PARAM_FRAG_THRESHOLD)
7241 {
7242 u16 frag_threshold = (wiphy->frag_threshold == -1) ?
7243 WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX :
7244 wiphy->frag_threshold;
7245
7246 if ((WNI_CFG_FRAGMENTATION_THRESHOLD_STAMIN > frag_threshold)||
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307247 (WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX < frag_threshold) )
Jeff Johnson295189b2012-06-20 16:38:30 -07007248 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307249 hddLog(VOS_TRACE_LEVEL_ERROR,
7250 "%s: Invalid frag_threshold value %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07007251 frag_threshold);
7252 return -EINVAL;
7253 }
7254
7255 if (0 != ccmCfgSetInt(hHal, WNI_CFG_FRAGMENTATION_THRESHOLD,
7256 frag_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307257 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -07007258 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307259 hddLog(VOS_TRACE_LEVEL_ERROR,
7260 "%s: ccmCfgSetInt failed for frag_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07007261 __func__, frag_threshold);
7262 return -EIO;
7263 }
7264
7265 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set frag threshold %hu", __func__,
7266 frag_threshold);
7267 }
7268
7269 if ((changed & WIPHY_PARAM_RETRY_SHORT)
7270 || (changed & WIPHY_PARAM_RETRY_LONG))
7271 {
7272 u8 retry_value = (changed & WIPHY_PARAM_RETRY_SHORT) ?
7273 wiphy->retry_short :
7274 wiphy->retry_long;
7275
7276 if ((WNI_CFG_LONG_RETRY_LIMIT_STAMIN > retry_value) ||
7277 (WNI_CFG_LONG_RETRY_LIMIT_STAMAX < retry_value))
7278 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307279 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07007280 __func__, retry_value);
7281 return -EINVAL;
7282 }
7283
7284 if (changed & WIPHY_PARAM_RETRY_SHORT)
7285 {
7286 if (0 != ccmCfgSetInt(hHal, WNI_CFG_LONG_RETRY_LIMIT,
7287 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307288 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -07007289 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307290 hddLog(VOS_TRACE_LEVEL_ERROR,
7291 "%s: ccmCfgSetInt failed for long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07007292 __func__, retry_value);
7293 return -EIO;
7294 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307295 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07007296 __func__, retry_value);
7297 }
7298 else if (changed & WIPHY_PARAM_RETRY_SHORT)
7299 {
7300 if (0 != ccmCfgSetInt(hHal, WNI_CFG_SHORT_RETRY_LIMIT,
7301 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307302 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -07007303 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307304 hddLog(VOS_TRACE_LEVEL_ERROR,
7305 "%s: ccmCfgSetInt failed for short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07007306 __func__, retry_value);
7307 return -EIO;
7308 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307309 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07007310 __func__, retry_value);
7311 }
7312 }
7313
7314 return 0;
7315}
7316
7317/*
7318 * FUNCTION: wlan_hdd_cfg80211_set_txpower
7319 * This function is used to set the txpower
7320 */
7321static int wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
Yue Maf49ba872013-08-19 12:04:25 -07007322#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
7323 struct wireless_dev *wdev,
7324#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007325#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307326 enum tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -07007327#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307328 enum nl80211_tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -07007329#endif
7330 int dbm)
7331{
7332 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307333 tHalHandle hHal = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07007334 tSirMacAddr bssid = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
7335 tSirMacAddr selfMac = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307336 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07007337
7338 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307339 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7340 TRACE_CODE_HDD_CFG80211_SET_TXPOWER,
7341 NO_SESSION, type ));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307342 status = wlan_hdd_validate_context(pHddCtx);
7343
7344 if (0 != status)
7345 {
7346 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7347 "%s: HDD context is not valid", __func__);
7348 return status;
7349 }
7350
7351 hHal = pHddCtx->hHal;
7352
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307353 if (0 != ccmCfgSetInt(hHal, WNI_CFG_CURRENT_TX_POWER_LEVEL,
7354 dbm, ccmCfgSetCallback,
7355 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -07007356 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307357 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07007358 "%s: ccmCfgSetInt failed for tx power %hu", __func__, dbm);
7359 return -EIO;
7360 }
7361
7362 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set tx power level %d dbm", __func__,
7363 dbm);
7364
7365 switch(type)
7366 {
7367 case NL80211_TX_POWER_AUTOMATIC: /*automatically determine transmit power*/
7368 /* Fall through */
7369 case NL80211_TX_POWER_LIMITED: /*limit TX power by the mBm parameter*/
7370 if( sme_SetMaxTxPower(hHal, bssid, selfMac, dbm) != eHAL_STATUS_SUCCESS )
7371 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307372 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Setting maximum tx power failed",
7373 __func__);
7374 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -07007375 }
7376 break;
7377 case NL80211_TX_POWER_FIXED: /*fix TX power to the mBm parameter*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307378 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: NL80211_TX_POWER_FIXED not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -07007379 __func__);
7380 return -EOPNOTSUPP;
7381 break;
7382 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307383 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid power setting type %d",
7384 __func__, type);
Jeff Johnson295189b2012-06-20 16:38:30 -07007385 return -EIO;
7386 }
7387
7388 return 0;
7389}
7390
7391/*
7392 * FUNCTION: wlan_hdd_cfg80211_get_txpower
7393 * This function is used to read the txpower
7394 */
Yue Maf49ba872013-08-19 12:04:25 -07007395static int wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy,
7396#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
7397 struct wireless_dev *wdev,
7398#endif
7399 int *dbm)
Jeff Johnson295189b2012-06-20 16:38:30 -07007400{
7401
7402 hdd_adapter_t *pAdapter;
7403 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307404 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07007405
Jeff Johnsone7245742012-09-05 17:12:55 -07007406 ENTER();
7407
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307408 status = wlan_hdd_validate_context(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07007409
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307410 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007411 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307412 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7413 "%s: HDD context is not valid", __func__);
7414 *dbm = 0;
7415 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007416 }
7417
Jeff Johnson295189b2012-06-20 16:38:30 -07007418 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
7419 if (NULL == pAdapter)
7420 {
7421 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Not in station context " ,__func__);
7422 return -ENOENT;
7423 }
7424
7425 wlan_hdd_get_classAstats(pAdapter);
7426 *dbm = pAdapter->hdd_stats.ClassA_stat.max_pwr;
7427
Jeff Johnsone7245742012-09-05 17:12:55 -07007428 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07007429 return 0;
7430}
7431
7432static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
7433 u8* mac, struct station_info *sinfo)
7434{
7435 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
7436 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7437 int ssidlen = pHddStaCtx->conn_info.SSID.SSID.length;
7438 tANI_U8 rate_flags;
7439
7440 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
7441 hdd_config_t *pCfg = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -07007442
7443 tANI_U8 OperationalRates[CSR_DOT11_SUPPORTED_RATES_MAX];
7444 tANI_U32 ORLeng = CSR_DOT11_SUPPORTED_RATES_MAX;
7445 tANI_U8 ExtendedRates[CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX];
7446 tANI_U32 ERLeng = CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX;
7447 tANI_U8 MCSRates[SIZE_OF_BASIC_MCS_SET];
7448 tANI_U32 MCSLeng = SIZE_OF_BASIC_MCS_SET;
7449 tANI_U16 maxRate = 0;
7450 tANI_U16 myRate;
7451 tANI_U16 currentRate = 0;
7452 tANI_U8 maxSpeedMCS = 0;
7453 tANI_U8 maxMCSIdx = 0;
7454 tANI_U8 rateFlag = 1;
7455 tANI_U8 i, j, rssidx;
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07007456 tANI_U16 temp;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307457 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07007458
Leo Chang6f8870f2013-03-26 18:11:36 -07007459#ifdef WLAN_FEATURE_11AC
7460 tANI_U32 vht_mcs_map;
7461 eDataRate11ACMaxMcs vhtMaxMcs;
7462#endif /* WLAN_FEATURE_11AC */
7463
Jeff Johnsone7245742012-09-05 17:12:55 -07007464 ENTER();
7465
Jeff Johnson295189b2012-06-20 16:38:30 -07007466 if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) ||
7467 (0 == ssidlen))
7468 {
7469 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Not associated or"
7470 " Invalid ssidlen, %d", __func__, ssidlen);
7471 /*To keep GUI happy*/
7472 return 0;
7473 }
7474
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307475 status = wlan_hdd_validate_context(pHddCtx);
7476
7477 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007478 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307479 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7480 "%s: HDD context is not valid", __func__);
7481 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007482 }
7483
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -07007484 wlan_hdd_get_station_stats(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07007485 rate_flags = pAdapter->hdd_stats.ClassA_stat.tx_rate_flags;
7486
Kiet Lam3b17fc82013-09-27 05:24:08 +05307487 wlan_hdd_get_rssi(pAdapter, &sinfo->signal);
7488 sinfo->filled |= STATION_INFO_SIGNAL;
7489
Jeff Johnson295189b2012-06-20 16:38:30 -07007490 //convert to the UI units of 100kbps
7491 myRate = pAdapter->hdd_stats.ClassA_stat.tx_rate * 5;
7492
7493#ifdef LINKSPEED_DEBUG_ENABLED
Leo Chang6f8870f2013-03-26 18:11:36 -07007494 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 -07007495 sinfo->signal,
7496 pCfg->reportMaxLinkSpeed,
7497 myRate,
7498 (int) pCfg->linkSpeedRssiHigh,
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07007499 (int) pCfg->linkSpeedRssiMid,
7500 (int) pCfg->linkSpeedRssiLow,
Leo Chang6f8870f2013-03-26 18:11:36 -07007501 (int) rate_flags,
7502 (int) pAdapter->hdd_stats.ClassA_stat.mcs_index);
Jeff Johnson295189b2012-06-20 16:38:30 -07007503#endif //LINKSPEED_DEBUG_ENABLED
7504
7505 if (eHDD_LINK_SPEED_REPORT_ACTUAL != pCfg->reportMaxLinkSpeed)
7506 {
7507 // we do not want to necessarily report the current speed
7508 if (eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed)
7509 {
7510 // report the max possible speed
7511 rssidx = 0;
7512 }
7513 else if (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed)
7514 {
7515 // report the max possible speed with RSSI scaling
7516 if (sinfo->signal >= pCfg->linkSpeedRssiHigh)
7517 {
7518 // report the max possible speed
7519 rssidx = 0;
7520 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07007521 else if (sinfo->signal >= pCfg->linkSpeedRssiMid)
Jeff Johnson295189b2012-06-20 16:38:30 -07007522 {
7523 // report middle speed
7524 rssidx = 1;
7525 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07007526 else if (sinfo->signal >= pCfg->linkSpeedRssiLow)
7527 {
7528 // report middle speed
7529 rssidx = 2;
7530 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007531 else
7532 {
7533 // report actual speed
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07007534 rssidx = 3;
Jeff Johnson295189b2012-06-20 16:38:30 -07007535 }
7536 }
7537 else
7538 {
7539 // unknown, treat as eHDD_LINK_SPEED_REPORT_MAX
7540 hddLog(VOS_TRACE_LEVEL_ERROR,
7541 "%s: Invalid value for reportMaxLinkSpeed: %u",
7542 __func__, pCfg->reportMaxLinkSpeed);
7543 rssidx = 0;
7544 }
7545
7546 maxRate = 0;
7547
7548 /* Get Basic Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +05307549 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_OPERATIONAL_RATE_SET,
7550 OperationalRates, &ORLeng))
7551 {
7552 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
7553 /*To keep GUI happy*/
7554 return 0;
7555 }
7556
Jeff Johnson295189b2012-06-20 16:38:30 -07007557 for (i = 0; i < ORLeng; i++)
7558 {
Jeff Johnsone7245742012-09-05 17:12:55 -07007559 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -07007560 {
7561 /* Validate Rate Set */
7562 if (supported_data_rate[j].beacon_rate_index == (OperationalRates[i] & 0x7F))
7563 {
7564 currentRate = supported_data_rate[j].supported_rate[rssidx];
7565 break;
7566 }
7567 }
7568 /* Update MAX rate */
7569 maxRate = (currentRate > maxRate)?currentRate:maxRate;
7570 }
7571
7572 /* Get Extended Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +05307573 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET,
7574 ExtendedRates, &ERLeng))
7575 {
7576 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
7577 /*To keep GUI happy*/
7578 return 0;
7579 }
7580
Jeff Johnson295189b2012-06-20 16:38:30 -07007581 for (i = 0; i < ERLeng; i++)
7582 {
Jeff Johnsone7245742012-09-05 17:12:55 -07007583 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -07007584 {
7585 if (supported_data_rate[j].beacon_rate_index == (ExtendedRates[i] & 0x7F))
7586 {
7587 currentRate = supported_data_rate[j].supported_rate[rssidx];
7588 break;
7589 }
7590 }
7591 /* Update MAX rate */
7592 maxRate = (currentRate > maxRate)?currentRate:maxRate;
7593 }
Kiet Lamb69f8dc2013-11-15 15:34:27 +05307594 /* Get MCS Rate Set --
Kaushik, Sushantdc304d82014-01-22 10:58:37 +05307595 Only if we are always reporting max speed (or)
Kiet Lamb69f8dc2013-11-15 15:34:27 +05307596 if we have good rssi */
Kaushik, Sushantdc304d82014-01-22 10:58:37 +05307597 if ((0 == rssidx) ||
Kiet Lamb69f8dc2013-11-15 15:34:27 +05307598 (eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed))
Jeff Johnson295189b2012-06-20 16:38:30 -07007599 {
Gopichand Nakkala05ab1322013-02-15 11:28:38 +05307600 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_CURRENT_MCS_SET,
7601 MCSRates, &MCSLeng))
7602 {
7603 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
7604 /*To keep GUI happy*/
7605 return 0;
7606 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007607 rateFlag = 0;
Leo Chang6f8870f2013-03-26 18:11:36 -07007608#ifdef WLAN_FEATURE_11AC
7609 /* VHT80 rate has seperate rate table */
Gopichand Nakkala4c705372013-04-24 13:20:33 +05307610 if (rate_flags & (eHAL_TX_RATE_VHT20|eHAL_TX_RATE_VHT40|eHAL_TX_RATE_VHT80))
Jeff Johnson295189b2012-06-20 16:38:30 -07007611 {
Leo Chang6f8870f2013-03-26 18:11:36 -07007612 ccmCfgGetInt(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_VHT_TX_MCS_MAP, &vht_mcs_map);
Gopichand Nakkala4c705372013-04-24 13:20:33 +05307613 vhtMaxMcs = (eDataRate11ACMaxMcs)(vht_mcs_map & DATA_RATE_11AC_MCS_MASK );
Leo Chang6f8870f2013-03-26 18:11:36 -07007614 if (rate_flags & eHAL_TX_RATE_SGI)
Jeff Johnson295189b2012-06-20 16:38:30 -07007615 {
Leo Chang6f8870f2013-03-26 18:11:36 -07007616 rateFlag |= 1;
Jeff Johnson295189b2012-06-20 16:38:30 -07007617 }
Leo Chang6f8870f2013-03-26 18:11:36 -07007618 if (DATA_RATE_11AC_MAX_MCS_7 == vhtMaxMcs)
Jeff Johnson295189b2012-06-20 16:38:30 -07007619 {
Leo Chang6f8870f2013-03-26 18:11:36 -07007620 maxMCSIdx = 7;
7621 }
7622 else if (DATA_RATE_11AC_MAX_MCS_8 == vhtMaxMcs)
7623 {
7624 maxMCSIdx = 8;
7625 }
7626 else if (DATA_RATE_11AC_MAX_MCS_9 == vhtMaxMcs)
7627 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +05307628 //VHT20 is supporting 0~8
7629 if (rate_flags & eHAL_TX_RATE_VHT20)
7630 maxMCSIdx = 8;
7631 else
7632 maxMCSIdx = 9;
Leo Chang6f8870f2013-03-26 18:11:36 -07007633 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +05307634
7635 if (rate_flags & eHAL_TX_RATE_VHT80)
7636 {
7637 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT80_rate[rateFlag];
7638 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT80_rate[rateFlag];
7639 }
7640 else if (rate_flags & eHAL_TX_RATE_VHT40)
7641 {
7642 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT40_rate[rateFlag];
7643 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT40_rate[rateFlag];
7644 }
7645 else if (rate_flags & eHAL_TX_RATE_VHT20)
7646 {
7647 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT20_rate[rateFlag];
7648 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT20_rate[rateFlag];
7649 }
7650
Leo Chang6f8870f2013-03-26 18:11:36 -07007651 maxSpeedMCS = 1;
7652 if (currentRate > maxRate)
7653 {
7654 maxRate = currentRate;
7655 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +05307656
Leo Chang6f8870f2013-03-26 18:11:36 -07007657 }
7658 else
7659#endif /* WLAN_FEATURE_11AC */
7660 {
7661 if (rate_flags & eHAL_TX_RATE_HT40)
7662 {
7663 rateFlag |= 1;
7664 }
7665 if (rate_flags & eHAL_TX_RATE_SGI)
7666 {
7667 rateFlag |= 2;
7668 }
7669
7670 for (i = 0; i < MCSLeng; i++)
7671 {
7672 temp = sizeof(supported_mcs_rate) / sizeof(supported_mcs_rate[0]);
7673 for (j = 0; j < temp; j++)
7674 {
7675 if (supported_mcs_rate[j].beacon_rate_index == MCSRates[i])
7676 {
7677 currentRate = supported_mcs_rate[j].supported_rate[rateFlag];
7678 break;
7679 }
7680 }
7681 if ((j < temp) && (currentRate > maxRate))
7682 {
7683 maxRate = currentRate;
7684 maxSpeedMCS = 1;
7685 maxMCSIdx = supported_mcs_rate[j].beacon_rate_index;
7686 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007687 }
7688 }
7689 }
7690
Gopichand Nakkala4c705372013-04-24 13:20:33 +05307691 else if (!(rate_flags & eHAL_TX_RATE_LEGACY))
7692 {
7693 maxRate = myRate;
7694 maxSpeedMCS = 1;
7695 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
7696 }
7697
Jeff Johnson295189b2012-06-20 16:38:30 -07007698 // make sure we report a value at least as big as our current rate
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07007699 if (((maxRate < myRate) && (0 == rssidx)) ||
7700 (0 == maxRate))
Jeff Johnson295189b2012-06-20 16:38:30 -07007701 {
7702 maxRate = myRate;
7703 if (rate_flags & eHAL_TX_RATE_LEGACY)
7704 {
7705 maxSpeedMCS = 0;
7706 }
7707 else
7708 {
7709 maxSpeedMCS = 1;
7710 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
7711 }
7712 }
7713
Gopichand Nakkala4c705372013-04-24 13:20:33 +05307714 if (rate_flags & eHAL_TX_RATE_LEGACY)
Jeff Johnson295189b2012-06-20 16:38:30 -07007715 {
7716 sinfo->txrate.legacy = maxRate;
7717#ifdef LINKSPEED_DEBUG_ENABLED
7718 pr_info("Reporting legacy rate %d\n", sinfo->txrate.legacy);
7719#endif //LINKSPEED_DEBUG_ENABLED
7720 }
7721 else
7722 {
7723 sinfo->txrate.mcs = maxMCSIdx;
Leo Chang6f8870f2013-03-26 18:11:36 -07007724#ifdef WLAN_FEATURE_11AC
7725 sinfo->txrate.nss = 1;
7726 if (rate_flags & eHAL_TX_RATE_VHT80)
7727 {
7728 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
Gopichand Nakkala4c705372013-04-24 13:20:33 +05307729 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
Leo Chang6f8870f2013-03-26 18:11:36 -07007730 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +05307731 else if (rate_flags & eHAL_TX_RATE_VHT40)
Leo Chang6f8870f2013-03-26 18:11:36 -07007732 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +05307733 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
7734 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
7735 }
7736 else if (rate_flags & eHAL_TX_RATE_VHT20)
7737 {
7738 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
7739 }
7740#endif /* WLAN_FEATURE_11AC */
7741 if (rate_flags & (eHAL_TX_RATE_HT20 | eHAL_TX_RATE_HT40))
7742 {
7743 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
7744 if (rate_flags & eHAL_TX_RATE_HT40)
7745 {
7746 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
7747 }
Leo Chang6f8870f2013-03-26 18:11:36 -07007748 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007749 if (rate_flags & eHAL_TX_RATE_SGI)
7750 {
7751 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
7752 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +05307753
Jeff Johnson295189b2012-06-20 16:38:30 -07007754#ifdef LINKSPEED_DEBUG_ENABLED
7755 pr_info("Reporting MCS rate %d flags %x\n",
7756 sinfo->txrate.mcs,
7757 sinfo->txrate.flags );
7758#endif //LINKSPEED_DEBUG_ENABLED
7759 }
7760 }
7761 else
7762 {
7763 // report current rate instead of max rate
7764
7765 if (rate_flags & eHAL_TX_RATE_LEGACY)
7766 {
7767 //provide to the UI in units of 100kbps
7768 sinfo->txrate.legacy = myRate;
7769#ifdef LINKSPEED_DEBUG_ENABLED
7770 pr_info("Reporting actual legacy rate %d\n", sinfo->txrate.legacy);
7771#endif //LINKSPEED_DEBUG_ENABLED
7772 }
7773 else
7774 {
7775 //must be MCS
7776 sinfo->txrate.mcs = pAdapter->hdd_stats.ClassA_stat.mcs_index;
Leo Chang6f8870f2013-03-26 18:11:36 -07007777#ifdef WLAN_FEATURE_11AC
7778 sinfo->txrate.nss = 1;
7779 if (rate_flags & eHAL_TX_RATE_VHT80)
7780 {
7781 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
7782 }
7783 else
7784#endif /* WLAN_FEATURE_11AC */
7785 {
7786 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
7787 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007788 if (rate_flags & eHAL_TX_RATE_SGI)
7789 {
7790 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
7791 }
7792 if (rate_flags & eHAL_TX_RATE_HT40)
7793 {
7794 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
7795 }
Leo Chang6f8870f2013-03-26 18:11:36 -07007796#ifdef WLAN_FEATURE_11AC
7797 else if (rate_flags & eHAL_TX_RATE_VHT80)
7798 {
7799 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
7800 }
7801#endif /* WLAN_FEATURE_11AC */
Jeff Johnson295189b2012-06-20 16:38:30 -07007802#ifdef LINKSPEED_DEBUG_ENABLED
7803 pr_info("Reporting actual MCS rate %d flags %x\n",
7804 sinfo->txrate.mcs,
7805 sinfo->txrate.flags );
7806#endif //LINKSPEED_DEBUG_ENABLED
7807 }
7808 }
7809 sinfo->filled |= STATION_INFO_TX_BITRATE;
7810
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -07007811 sinfo->tx_packets =
7812 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[0] +
7813 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[1] +
7814 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[2] +
7815 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[3];
7816
7817 sinfo->tx_retries =
7818 pAdapter->hdd_stats.summary_stat.retry_cnt[0] +
7819 pAdapter->hdd_stats.summary_stat.retry_cnt[1] +
7820 pAdapter->hdd_stats.summary_stat.retry_cnt[2] +
7821 pAdapter->hdd_stats.summary_stat.retry_cnt[3];
7822
7823 sinfo->tx_failed =
7824 pAdapter->hdd_stats.summary_stat.fail_cnt[0] +
7825 pAdapter->hdd_stats.summary_stat.fail_cnt[1] +
7826 pAdapter->hdd_stats.summary_stat.fail_cnt[2] +
7827 pAdapter->hdd_stats.summary_stat.fail_cnt[3];
7828
7829 sinfo->filled |=
7830 STATION_INFO_TX_PACKETS |
7831 STATION_INFO_TX_RETRIES |
7832 STATION_INFO_TX_FAILED;
7833
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307834 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7835 TRACE_CODE_HDD_CFG80211_GET_STA,
7836 pAdapter->sessionId, maxRate));
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -07007837 EXIT();
7838 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07007839}
7840
7841static int wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
Sameer Thalappilc9f26e92013-06-07 10:11:06 -07007842 struct net_device *dev, bool mode, int timeout)
Jeff Johnson295189b2012-06-20 16:38:30 -07007843{
7844 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +05307845 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07007846 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307847 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07007848
Jeff Johnsone7245742012-09-05 17:12:55 -07007849 ENTER();
7850
Jeff Johnson295189b2012-06-20 16:38:30 -07007851 if (NULL == pAdapter)
7852 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08007853 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007854 return -ENODEV;
7855 }
7856
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307857 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7858 TRACE_CODE_HDD_CFG80211_SET_POWER_MGMT,
7859 pAdapter->sessionId, timeout));
7860
Gopichand Nakkala20c4c042013-04-19 22:08:55 +05307861 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307862 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +05307863
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307864 if (0 != status)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307865 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307866 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7867 "%s: HDD context is not valid", __func__);
7868 return status;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307869 }
7870
Gopichand Nakkala20c4c042013-04-19 22:08:55 +05307871 if ((DRIVER_POWER_MODE_AUTO == !mode) &&
7872 (TRUE == pHddCtx->hdd_wlan_suspended) &&
7873 (pHddCtx->cfg_ini->fhostArpOffload) &&
7874 (eConnectionState_Associated ==
7875 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
7876 {
Amar Singhald53568e2013-09-26 11:03:45 -07007877
7878 hddLog(VOS_TRACE_LEVEL_INFO,
7879 "offload: in cfg80211_set_power_mgmt, calling arp offload");
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05307880 vos_status = hdd_conf_arp_offload(pAdapter, TRUE);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +05307881 if (!VOS_IS_STATUS_SUCCESS(vos_status))
7882 {
7883 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007884 "%s:Failed to enable ARPOFFLOAD Feature %d",
Gopichand Nakkala20c4c042013-04-19 22:08:55 +05307885 __func__, vos_status);
7886 }
7887 }
7888
Jeff Johnson295189b2012-06-20 16:38:30 -07007889 /**The get power cmd from the supplicant gets updated by the nl only
7890 *on successful execution of the function call
7891 *we are oppositely mapped w.r.t mode in the driver
7892 **/
7893 vos_status = wlan_hdd_enter_bmps(pAdapter, !mode);
7894
Jeff Johnsone7245742012-09-05 17:12:55 -07007895 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07007896 if (VOS_STATUS_E_FAILURE == vos_status)
7897 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307898 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7899 "%s: failed to enter bmps mode", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007900 return -EINVAL;
7901 }
7902 return 0;
7903}
7904
7905
7906#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
7907static int wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
7908 struct net_device *netdev,
7909 u8 key_index)
7910{
Jeff Johnsone7245742012-09-05 17:12:55 -07007911 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07007912 return 0;
7913}
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307914#endif //LINUX_VERSION_CODE
Jeff Johnson295189b2012-06-20 16:38:30 -07007915
7916#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
7917static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
7918 struct net_device *dev,
7919 struct ieee80211_txq_params *params)
7920{
Jeff Johnsone7245742012-09-05 17:12:55 -07007921 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07007922 return 0;
7923}
7924#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
7925static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
7926 struct ieee80211_txq_params *params)
7927{
Jeff Johnsone7245742012-09-05 17:12:55 -07007928 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07007929 return 0;
7930}
7931#endif //LINUX_VERSION_CODE
7932
7933static int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
7934 struct net_device *dev, u8 *mac)
7935{
7936 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307937 hdd_context_t *pHddCtx;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08007938 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307939 int status;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08007940 v_U8_t staId;
Jeff Johnson295189b2012-06-20 16:38:30 -07007941
Jeff Johnsone7245742012-09-05 17:12:55 -07007942 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307943
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307944 if ( NULL == pAdapter )
Jeff Johnson295189b2012-06-20 16:38:30 -07007945 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307946 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007947 return -EINVAL;
7948 }
7949
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307950 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7951 TRACE_CODE_HDD_CFG80211_DEL_STA,
7952 pAdapter->sessionId, pAdapter->device_mode));
7953
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307954 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7955 status = wlan_hdd_validate_context(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07007956
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307957 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007958 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307959 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7960 "%s: HDD context is not valid", __func__);
7961 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007962 }
7963
Jeff Johnson295189b2012-06-20 16:38:30 -07007964 if ( (WLAN_HDD_SOFTAP == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -07007965 || (WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -07007966 )
7967 {
7968 if( NULL == mac )
7969 {
7970 v_U16_t i;
7971 for(i = 0; i < WLAN_MAX_STA_COUNT; i++)
7972 {
Rajesh Chauhan18488fc2013-08-22 10:15:03 -07007973 if ((pAdapter->aStaInfo[i].isUsed) &&
7974 (!pAdapter->aStaInfo[i].isDeauthInProgress))
Jeff Johnson295189b2012-06-20 16:38:30 -07007975 {
7976 u8 *macAddr = pAdapter->aStaInfo[i].macAddrSTA.bytes;
7977 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -08007978 "%s: Delete STA with MAC::"
7979 MAC_ADDRESS_STR,
7980 __func__, MAC_ADDR_ARRAY(macAddr));
Rajesh Chauhan18488fc2013-08-22 10:15:03 -07007981 vos_status = hdd_softap_sta_deauth(pAdapter, macAddr);
7982 if (VOS_IS_STATUS_SUCCESS(vos_status))
7983 pAdapter->aStaInfo[i].isDeauthInProgress = TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -07007984 }
7985 }
7986 }
7987 else
7988 {
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08007989
7990 vos_status = hdd_softap_GetStaId(pAdapter,(v_MACADDR_t *)mac, &staId);
7991 if (!VOS_IS_STATUS_SUCCESS(vos_status))
7992 {
7993 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -08007994 "%s: Skip this DEL STA as this is not used::"
7995 MAC_ADDRESS_STR,
7996 __func__, MAC_ADDR_ARRAY(mac));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08007997 return -ENOENT;
7998 }
7999
8000 if( pAdapter->aStaInfo[staId].isDeauthInProgress == TRUE)
8001 {
8002 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -08008003 "%s: Skip this DEL STA as deauth is in progress::"
8004 MAC_ADDRESS_STR,
8005 __func__, MAC_ADDR_ARRAY(mac));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08008006 return -ENOENT;
8007 }
8008
8009 pAdapter->aStaInfo[staId].isDeauthInProgress = TRUE;
8010
Jeff Johnson295189b2012-06-20 16:38:30 -07008011 hddLog(VOS_TRACE_LEVEL_INFO,
8012 "%s: Delete STA with MAC::"
Arif Hussain24bafea2013-11-15 15:10:03 -08008013 MAC_ADDRESS_STR,
Jeff Johnson295189b2012-06-20 16:38:30 -07008014 __func__,
Arif Hussain24bafea2013-11-15 15:10:03 -08008015 MAC_ADDR_ARRAY(mac));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08008016
8017 vos_status = hdd_softap_sta_deauth(pAdapter, mac);
8018 if (!VOS_IS_STATUS_SUCCESS(vos_status))
8019 {
8020 pAdapter->aStaInfo[staId].isDeauthInProgress = FALSE;
8021 hddLog(VOS_TRACE_LEVEL_INFO,
8022 "%s: STA removal failed for ::"
Arif Hussain24bafea2013-11-15 15:10:03 -08008023 MAC_ADDRESS_STR,
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08008024 __func__,
Arif Hussain24bafea2013-11-15 15:10:03 -08008025 MAC_ADDR_ARRAY(mac));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08008026 return -ENOENT;
8027 }
8028
Jeff Johnson295189b2012-06-20 16:38:30 -07008029 }
8030 }
8031
8032 EXIT();
8033
8034 return 0;
8035}
8036
Hoonki Lee11f7dda2013-02-14 16:55:44 -08008037static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
8038 struct net_device *dev, u8 *mac, struct station_parameters *params)
8039{
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308040 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkalab977a972013-02-18 19:15:09 -08008041 int status = -EPERM;
Hoonki Lee11f7dda2013-02-14 16:55:44 -08008042#ifdef FEATURE_WLAN_TDLS
8043 u32 mask, set;
Hoonki Lee11f7dda2013-02-14 16:55:44 -08008044 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308045
8046 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
8047 TRACE_CODE_HDD_CFG80211_ADD_STA,
8048 pAdapter->sessionId, params->listen_interval));
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008049 mask = params->sta_flags_mask;
8050
8051 set = params->sta_flags_set;
8052
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07008053#ifdef WLAN_FEATURE_TDLS_DEBUG
8054 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8055 "%s: mask 0x%x set 0x%x " MAC_ADDRESS_STR,
8056 __func__, mask, set, MAC_ADDR_ARRAY(mac));
8057#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008058
8059 if (mask & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
8060 if (set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008061 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 0, NULL);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008062 }
8063 }
8064#endif
Gopichand Nakkalab977a972013-02-18 19:15:09 -08008065 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -07008066}
8067
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008068
8069#ifdef FEATURE_WLAN_LFR
Wilson Yang6507c4e2013-10-01 20:11:19 -07008070#define MAX_PMKSAIDS_IN_CACHE 8
8071
8072static tPmkidCacheInfo PMKIDCache[MAX_PMKSAIDS_IN_CACHE]; // HDD local cache
8073static tANI_U32 PMKIDCacheIndex; // HDD local Cache index
8074
8075
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008076static int wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
Jeff Johnsond13512a2012-07-17 11:42:19 -07008077 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008078{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308079 tANI_U32 j=0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008080 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
8081 tHalHandle halHandle;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308082 eHalStatus result;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308083 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008084 tANI_U8 BSSIDMatched = 0;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308085 hdd_context_t *pHddCtx;
Jeff Johnson0299d0a2013-10-30 12:37:43 -07008086 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: set PMKSA for " MAC_ADDRESS_STR,
8087 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
Jeff Johnsone7245742012-09-05 17:12:55 -07008088
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308089 // Validate pAdapter
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308090 if ( NULL == pAdapter )
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008091 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308092 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008093 return -EINVAL;
8094 }
8095
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308096 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8097 status = wlan_hdd_validate_context(pHddCtx);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008098
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308099 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008100 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308101 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8102 "%s: HDD context is not valid", __func__);
8103 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008104 }
8105
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308106 // Retrieve halHandle
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008107 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
8108
Wilson Yang6507c4e2013-10-01 20:11:19 -07008109 for (j = 0; j < PMKIDCacheIndex; j++)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008110 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308111 if(vos_mem_compare(PMKIDCache[j].BSSID,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008112 pmksa->bssid, WNI_CFG_BSSID_LEN))
8113 {
8114 /* BSSID matched previous entry. Overwrite it. */
8115 BSSIDMatched = 1;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308116 vos_mem_copy(PMKIDCache[j].BSSID,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008117 pmksa->bssid, WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308118 vos_mem_copy(PMKIDCache[j].PMKID,
8119 pmksa->pmkid,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008120 CSR_RSN_PMKID_SIZE);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308121 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Reusing cache entry %d.",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008122 __func__, j );
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008123 dump_bssid(pmksa->bssid);
8124 dump_pmkid(halHandle, pmksa->pmkid);
8125 break;
8126 }
8127 }
8128
Madan Mohan Koyyalamudic4b317d2012-10-18 19:43:08 -07008129 /* Check we compared all entries,if then take the first slot now */
Wilson Yang6507c4e2013-10-01 20:11:19 -07008130 if(j == MAX_PMKSAIDS_IN_CACHE) PMKIDCacheIndex=0;
Madan Mohan Koyyalamudic4b317d2012-10-18 19:43:08 -07008131
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008132 if (!BSSIDMatched)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308133 {
8134 // Now, we DON'T have a BSSID match, so take a new entry in the cache.
Wilson Yang6507c4e2013-10-01 20:11:19 -07008135 vos_mem_copy(PMKIDCache[PMKIDCacheIndex].BSSID,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308136 pmksa->bssid, ETHER_ADDR_LEN);
Wilson Yang6507c4e2013-10-01 20:11:19 -07008137 vos_mem_copy(PMKIDCache[PMKIDCacheIndex].PMKID,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308138 pmksa->pmkid,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008139 CSR_RSN_PMKID_SIZE);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308140 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Adding a new cache entry %d.",
Wilson Yang6507c4e2013-10-01 20:11:19 -07008141 __func__, PMKIDCacheIndex );
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008142 dump_bssid(pmksa->bssid);
8143 dump_pmkid(halHandle, pmksa->pmkid);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308144 // Increment the HDD Local Cache index
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008145 // The "i=0" doesn't work for the call to sme_RoamSetPMKIDCache() - LFR FIXME
Wilson Yang6507c4e2013-10-01 20:11:19 -07008146 if (PMKIDCacheIndex <= (MAX_PMKSAIDS_IN_CACHE-1)) PMKIDCacheIndex++; else PMKIDCacheIndex = 0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008147 }
8148
8149
8150 // Calling csrRoamSetPMKIDCache to configure the PMKIDs into the cache
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308151 //hddLog(LOG1, FL("%s: Calling csrRoamSetPMKIDCache with %d cache entries."),
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008152 // __func__, i );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308153 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Calling csrRoamSetPMKIDCache with %d cache entries.",
Wilson Yang6507c4e2013-10-01 20:11:19 -07008154 __func__, PMKIDCacheIndex );
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008155 // Finally set the PMKSA ID Cache in CSR
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308156 result = sme_RoamSetPMKIDCache(halHandle,pAdapter->sessionId,
8157 PMKIDCache,
Wilson Yang6507c4e2013-10-01 20:11:19 -07008158 PMKIDCacheIndex);
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308159 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
8160 TRACE_CODE_HDD_CFG80211_SET_PMKSA,
8161 pAdapter->sessionId, result));
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008162 return 0;
8163}
8164
8165
Wilson Yang6507c4e2013-10-01 20:11:19 -07008166
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008167static int wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
Wilson Yang6507c4e2013-10-01 20:11:19 -07008168 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008169{
Wilson Yang6507c4e2013-10-01 20:11:19 -07008170 tANI_U32 j=0;
8171 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
8172 tHalHandle halHandle;
Wilson Yang6507c4e2013-10-01 20:11:19 -07008173 tANI_U8 BSSIDMatched = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -07008174 hdd_context_t *pHddCtx;
Wilson Yangef657d32014-01-15 19:19:23 -08008175 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -07008176
Jeff Johnson0299d0a2013-10-30 12:37:43 -07008177 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: deleting PMKSA for " MAC_ADDRESS_STR,
8178 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
Wilson Yang6507c4e2013-10-01 20:11:19 -07008179
8180 /* Validate pAdapter */
8181 if (NULL == pAdapter)
8182 {
8183 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
8184 return -EINVAL;
8185 }
8186
8187 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8188 status = wlan_hdd_validate_context(pHddCtx);
8189
8190 if (0 != status)
8191 {
8192 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8193 "%s: HDD context is not valid", __func__);
8194 return status;
8195 }
8196
8197 /*Retrieve halHandle*/
8198 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
8199
8200 /*in case index is 0,no entry to delete*/
8201 if (0 == PMKIDCacheIndex)
8202 {
8203 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid entry to delete" ,
8204 __func__);
8205 return -EINVAL;
8206 }
8207
8208 /*find the matching PMKSA entry from j=0 to (index-1),
8209 * and delete the matched one
8210 */
8211 for (j = 0; j<PMKIDCacheIndex; j++)
8212 {
8213 if (vos_mem_compare(PMKIDCache[j].BSSID,
8214 pmksa->bssid,
8215 WNI_CFG_BSSID_LEN))
8216 {
8217 /* BSSID matched entry */
8218 BSSIDMatched = 1;
8219
8220 if (j<PMKIDCacheIndex-1)
8221 {
8222 /*replace the matching entry with the last entry in HDD local cache*/
8223 vos_mem_copy(PMKIDCache[j].BSSID,
8224 PMKIDCache[PMKIDCacheIndex-1].BSSID,
8225 WNI_CFG_BSSID_LEN);
8226 vos_mem_copy(PMKIDCache[j].PMKID,
8227 PMKIDCache[PMKIDCacheIndex-1].PMKID,
8228 CSR_RSN_PMKID_SIZE);
8229 }
8230
8231 /*clear the last entry in HDD cache ---[index-1]*/
Wilson Yang6507c4e2013-10-01 20:11:19 -07008232 vos_mem_zero(PMKIDCache[PMKIDCacheIndex-1].BSSID, WNI_CFG_BSSID_LEN);
8233 vos_mem_zero(PMKIDCache[PMKIDCacheIndex-1].PMKID, CSR_RSN_PMKID_SIZE);
8234
8235 /*reduce the PMKID array index*/
8236 PMKIDCacheIndex--;
8237
8238 /*delete the last PMKID cache in CSR*/
Wilson Yangef657d32014-01-15 19:19:23 -08008239 if (eHAL_STATUS_SUCCESS !=
8240 sme_RoamDelPMKIDfromCache(halHandle, pAdapter->sessionId, pmksa->bssid))
Wilson Yang6507c4e2013-10-01 20:11:19 -07008241 {
8242 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: cannot delete PMKSA %d CONTENT.",
8243 __func__,PMKIDCacheIndex);
Wilson Yangef657d32014-01-15 19:19:23 -08008244 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -07008245 }
8246
8247 dump_bssid(pmksa->bssid);
8248 dump_pmkid(halHandle,pmksa->pmkid);
8249
8250 break;
8251 }
8252 }
8253
8254 /* we compare all entries,but cannot find matching entry */
8255 if (j == MAX_PMKSAIDS_IN_CACHE && !BSSIDMatched)
8256 {
Jeff Johnson0299d0a2013-10-30 12:37:43 -07008257 hddLog(VOS_TRACE_LEVEL_FATAL,
8258 "%s: No such PMKSA entry existed " MAC_ADDRESS_STR,
8259 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
Wilson Yang6507c4e2013-10-01 20:11:19 -07008260 dump_bssid(pmksa->bssid);
8261 dump_pmkid(halHandle, pmksa->pmkid);
8262 return -EINVAL;
8263 }
Wilson Yangef657d32014-01-15 19:19:23 -08008264 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008265}
8266
Wilson Yang6507c4e2013-10-01 20:11:19 -07008267
8268
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008269static int wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
8270{
Wilson Yang6507c4e2013-10-01 20:11:19 -07008271 tANI_U32 j=0;
8272 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
8273 tHalHandle halHandle;
8274 hdd_context_t *pHddCtx;
8275 tANI_U8 *pBSSId;
Wilson Yangef657d32014-01-15 19:19:23 -08008276 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -07008277
8278 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: flushing PMKSA ",__func__);
8279
8280 /* Validate pAdapter */
8281 if (NULL == pAdapter)
8282 {
8283 hddLog(VOS_TRACE_LEVEL_ERROR,
8284 "%s: Invalid Adapter" ,__func__);
8285 return -EINVAL;
8286 }
8287
8288 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8289 status = wlan_hdd_validate_context(pHddCtx);
8290
8291 if (0 != status)
8292 {
8293 hddLog(VOS_TRACE_LEVEL_ERROR,
8294 "%s: HDD context is not valid", __func__);
8295 return status;
8296 }
8297
8298 /*Retrieve halHandle*/
8299 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
8300
8301 /*in case index is 0,no entry to delete*/
8302 if (0 == PMKIDCacheIndex)
8303 {
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +05308304 hddLog(VOS_TRACE_LEVEL_ERROR, FL("No entries to flush"));
Wilson Yang6507c4e2013-10-01 20:11:19 -07008305 return -EINVAL;
8306 }
8307
8308 /*delete all the PMKSA one by one */
8309 for (j = 0; j<PMKIDCacheIndex; j++)
8310 {
Wilson Yang6507c4e2013-10-01 20:11:19 -07008311 pBSSId =(tANI_U8 *)(PMKIDCache[j].BSSID);
Wilson Yang6507c4e2013-10-01 20:11:19 -07008312
8313 /*delete the PMKID in CSR*/
Wilson Yangef657d32014-01-15 19:19:23 -08008314 if (eHAL_STATUS_SUCCESS !=
8315 sme_RoamDelPMKIDfromCache(halHandle, pAdapter->sessionId, pBSSId))
Wilson Yang6507c4e2013-10-01 20:11:19 -07008316 {
8317 hddLog(VOS_TRACE_LEVEL_ERROR ,"%s cannot flush PMKIDCache %d.",
8318 __func__,j);
Wilson Yangef657d32014-01-15 19:19:23 -08008319 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -07008320 }
Kiet Lam8d21d5b2013-10-31 17:18:29 +05308321 /*clear the entry in HDD cache 0--index-1 */
8322 vos_mem_zero(PMKIDCache[j].BSSID, WNI_CFG_BSSID_LEN);
8323 vos_mem_zero(PMKIDCache[j].PMKID, CSR_RSN_PMKID_SIZE);
Wilson Yang6507c4e2013-10-01 20:11:19 -07008324 }
8325
8326 PMKIDCacheIndex = 0;
Wilson Yangef657d32014-01-15 19:19:23 -08008327 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008328}
8329#endif
8330
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07008331#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308332static int wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07008333 struct net_device *dev, struct cfg80211_update_ft_ies_params *ftie)
8334{
8335 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
8336 hdd_station_ctx_t *pHddStaCtx;
8337
8338 if (NULL == pAdapter)
8339 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08008340 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07008341 return -ENODEV;
8342 }
8343
8344 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
8345
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308346 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
8347 TRACE_CODE_HDD_CFG80211_UPDATE_FT_IES,
8348 pAdapter->sessionId, pHddStaCtx->conn_info.connState));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07008349 // Added for debug on reception of Re-assoc Req.
8350 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
8351 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08008352 hddLog(LOGE, FL("Called with Ie of length = %zu when not associated"),
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07008353 ftie->ie_len);
Arif Hussain6d2a3322013-11-17 19:50:10 -08008354 hddLog(LOGE, FL("Should be Re-assoc Req IEs"));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07008355 }
8356
8357#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG
Arif Hussain6d2a3322013-11-17 19:50:10 -08008358 hddLog(LOGE, FL("%s called with Ie of length = %zu"), __func__,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07008359 ftie->ie_len);
8360#endif
8361
8362 // Pass the received FT IEs to SME
Gopichand Nakkala356fb102013-03-06 12:34:04 +05308363 sme_SetFTIEs( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
8364 (const u8 *)ftie->ie,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07008365 ftie->ie_len);
8366 return 0;
8367}
8368#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008369
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308370#ifdef FEATURE_WLAN_SCAN_PNO
8371
8372void hdd_cfg80211_sched_scan_done_callback(void *callbackContext,
8373 tSirPrefNetworkFoundInd *pPrefNetworkFoundInd)
8374{
8375 int ret;
8376 hdd_adapter_t* pAdapter = (hdd_adapter_t*)callbackContext;
8377 hdd_context_t *pHddCtx;
8378
Nirav Shah80830bf2013-12-31 16:35:12 +05308379 ENTER();
8380
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308381 if (NULL == pAdapter)
8382 {
Agarwal Ashish971c2882013-10-30 20:11:12 +05308383 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308384 "%s: HDD adapter is Null", __func__);
8385 return ;
8386 }
8387
8388 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8389 if (NULL == pHddCtx)
8390 {
8391 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8392 "%s: HDD context is Null!!!", __func__);
8393 return ;
8394 }
8395
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05308396 spin_lock(&pHddCtx->schedScan_lock);
8397 if (TRUE == pHddCtx->isWiphySuspended)
8398 {
8399 pHddCtx->isSchedScanUpdatePending = TRUE;
8400 spin_unlock(&pHddCtx->schedScan_lock);
8401 hddLog(VOS_TRACE_LEVEL_INFO,
8402 "%s: Update cfg80211 scan database after it resume", __func__);
8403 return ;
8404 }
8405 spin_unlock(&pHddCtx->schedScan_lock);
8406
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308407 ret = wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter);
8408
8409 if (0 > ret)
8410 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
8411
8412 cfg80211_sched_scan_results(pHddCtx->wiphy);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05308413 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8414 "%s: cfg80211 scan result database updated", __func__);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308415}
8416
8417/*
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +05308418 * FUNCTION: wlan_hdd_is_pno_allowed
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +05308419 * Disallow pno if any session is active
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +05308420 */
8421static eHalStatus wlan_hdd_is_pno_allowed(hdd_adapter_t *pAdapter)
8422{
8423 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
8424 hdd_adapter_t *pTempAdapter = NULL;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +05308425 hdd_station_ctx_t *pStaCtx;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +05308426 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8427 int status = 0;
8428 status = hdd_get_front_adapter(pHddCtx, &pAdapterNode);
8429
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +05308430 /* The current firmware design does not allow PNO during any
8431 * active sessions. Hence, determine the active sessions
8432 * and return a failure.
8433 */
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +05308434 while ((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status))
8435 {
8436 pTempAdapter = pAdapterNode->pAdapter;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +05308437 pStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pTempAdapter);
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +05308438
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +05308439 if (((WLAN_HDD_INFRA_STATION == pTempAdapter->device_mode)
8440 && (eConnectionState_NotConnected != pStaCtx->conn_info.connState))
8441 || (WLAN_HDD_P2P_CLIENT == pTempAdapter->device_mode)
8442 || (WLAN_HDD_P2P_GO == pTempAdapter->device_mode)
8443 || (WLAN_HDD_SOFTAP == pTempAdapter->device_mode)
8444 )
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +05308445 {
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +05308446 return eHAL_STATUS_FAILURE;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +05308447 }
8448 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
8449 pAdapterNode = pNext;
8450 }
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +05308451 return eHAL_STATUS_SUCCESS;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +05308452}
8453
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +05308454void hdd_cfg80211_sched_scan_start_status_cb(void *callbackContext, VOS_STATUS status)
8455{
8456 hdd_adapter_t *pAdapter = callbackContext;
8457 hdd_context_t *pHddCtx;
8458
8459 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
8460 {
8461 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8462 FL("Invalid adapter or adapter has invalid magic"));
8463 return;
8464 }
8465
8466 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8467 if (0 != wlan_hdd_validate_context(pHddCtx))
8468 {
8469 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8470 FL("HDD context is not valid"));
8471 return;
8472 }
8473
8474 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8475 FL("PNO enable response status = %d"), status);
8476
8477 pAdapter->pno_req_status = (status == VOS_STATUS_SUCCESS) ? 0 : -EBUSY;
8478 complete(&pAdapter->pno_comp_var);
8479}
8480
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +05308481/*
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308482 * FUNCTION: wlan_hdd_cfg80211_sched_scan_start
8483 * NL interface to enable PNO
8484 */
8485static int wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
8486 struct net_device *dev, struct cfg80211_sched_scan_request *request)
8487{
8488 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
8489 tpSirPNOScanReq pPnoRequest = NULL;
8490 hdd_context_t *pHddCtx;
8491 tHalHandle hHal;
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +05308492 v_U32_t i, indx, num_ch, tempInterval;
Sushant Kaushikd62d9782014-02-19 15:39:40 +05308493 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
8494 u8 channels_allowed[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308495 v_U32_t num_channels_allowed = WNI_CFG_VALID_CHANNEL_LIST_LEN;
8496 eHalStatus status = eHAL_STATUS_FAILURE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308497 int ret = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308498
8499 if (NULL == pAdapter)
8500 {
8501 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
8502 "%s: HDD adapter is Null", __func__);
8503 return -ENODEV;
8504 }
8505
8506 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05308507 ret = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308508
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05308509 if (0 != ret)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308510 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05308511 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8512 "%s: HDD context is not valid", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308513 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308514 }
8515
8516 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
8517 if (NULL == hHal)
8518 {
8519 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8520 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05308521 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308522 }
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +05308523
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +05308524 if (eHAL_STATUS_SUCCESS != wlan_hdd_is_pno_allowed(pAdapter))
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +05308525 {
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +05308526 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +05308527 FL("Cannot handle sched_scan"));
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +05308528 return -EBUSY;
8529 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308530
c_hpothu37f21312014-04-09 21:49:54 +05308531 if (TRUE == pHddCtx->isPnoEnable)
8532 {
8533 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
8534 FL("already PNO is enabled"));
8535 return -EBUSY;
8536 }
8537 pHddCtx->isPnoEnable = TRUE;
8538
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308539 pPnoRequest = (tpSirPNOScanReq) vos_mem_malloc(sizeof (tSirPNOScanReq));
8540 if (NULL == pPnoRequest)
8541 {
8542 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
8543 "%s: vos_mem_malloc failed", __func__);
c_hpothu37f21312014-04-09 21:49:54 +05308544 pHddCtx->isPnoEnable = FALSE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308545 return -ENOMEM;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308546 }
8547
Madan Mohan Koyyalamudic3f04352013-09-26 19:21:48 +05308548 memset(pPnoRequest, 0, sizeof (tSirPNOScanReq));
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308549 pPnoRequest->enable = 1; /*Enable PNO */
8550 pPnoRequest->ucNetworksCount = request->n_match_sets;
8551
8552 if (( !pPnoRequest->ucNetworksCount ) ||
8553 ( pPnoRequest->ucNetworksCount > SIR_PNO_MAX_SUPP_NETWORKS ))
8554 {
8555 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +05308556 "%s: Network input is not correct %d",
8557 __func__, pPnoRequest->ucNetworksCount);
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308558 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308559 goto error;
8560 }
8561
8562 if ( SIR_PNO_MAX_NETW_CHANNELS_EX < request->n_channels )
8563 {
8564 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +05308565 "%s: Incorrect number of channels %d",
8566 __func__, request->n_channels);
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308567 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308568 goto error;
8569 }
8570
8571 /* Framework provides one set of channels(all)
8572 * common for all saved profile */
8573 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
8574 channels_allowed, &num_channels_allowed))
8575 {
8576 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8577 "%s: failed to get valid channel list", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308578 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308579 goto error;
8580 }
8581 /* Checking each channel against allowed channel list */
8582 num_ch = 0;
Nirav Shah80830bf2013-12-31 16:35:12 +05308583 if (request->n_channels)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308584 {
Nirav Shah80830bf2013-12-31 16:35:12 +05308585 char chList [(request->n_channels*5)+1];
8586 int len;
8587 for (i = 0, len = 0; i < request->n_channels; i++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308588 {
Nirav Shah80830bf2013-12-31 16:35:12 +05308589 for (indx = 0; indx < num_channels_allowed; indx++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308590 {
Nirav Shah80830bf2013-12-31 16:35:12 +05308591 if (request->channels[i]->hw_value == channels_allowed[indx])
8592 {
8593 valid_ch[num_ch++] = request->channels[i]->hw_value;
8594 len += snprintf(chList+len, 5, "%d ",
8595 request->channels[i]->hw_value);
8596 break ;
8597 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308598 }
8599 }
Nirav Shah80830bf2013-12-31 16:35:12 +05308600 hddLog(VOS_TRACE_LEVEL_INFO,"Channel-List: %s ", chList);
8601 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308602
8603 /* Filling per profile params */
8604 for (i = 0; i < pPnoRequest->ucNetworksCount; i++)
8605 {
8606 pPnoRequest->aNetworks[i].ssId.length =
8607 request->match_sets[i].ssid.ssid_len;
8608
8609 if (( 0 == pPnoRequest->aNetworks[i].ssId.length ) ||
8610 ( pPnoRequest->aNetworks[i].ssId.length > 32 ) )
8611 {
8612 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +05308613 "%s: SSID Len %d is not correct for network %d",
8614 __func__, pPnoRequest->aNetworks[i].ssId.length, i);
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308615 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308616 goto error;
8617 }
8618
8619 memcpy(pPnoRequest->aNetworks[i].ssId.ssId,
8620 request->match_sets[i].ssid.ssid,
8621 request->match_sets[i].ssid.ssid_len);
8622 pPnoRequest->aNetworks[i].authentication = 0; /*eAUTH_TYPE_ANY*/
8623 pPnoRequest->aNetworks[i].encryption = 0; /*eED_ANY*/
8624 pPnoRequest->aNetworks[i].bcastNetwType = 0; /*eBCAST_UNKNOWN*/
8625
8626 /*Copying list of valid channel into request */
8627 memcpy(pPnoRequest->aNetworks[i].aChannels, valid_ch, num_ch);
8628 pPnoRequest->aNetworks[i].ucChannelCount = num_ch;
8629
8630 pPnoRequest->aNetworks[i].rssiThreshold = 0; //Default value
8631 }
8632
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +05308633 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnson59a121e2013-11-30 09:46:08 -08008634 "request->ie_len = %zu", request->ie_len);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +05308635 if ((0 < request->ie_len) && (NULL != request->ie))
8636 {
8637 pPnoRequest->us24GProbeTemplateLen = request->ie_len;
8638 memcpy(&pPnoRequest->p24GProbeTemplate, request->ie,
8639 pPnoRequest->us24GProbeTemplateLen);
8640
8641 pPnoRequest->us5GProbeTemplateLen = request->ie_len;
8642 memcpy(&pPnoRequest->p5GProbeTemplate, request->ie,
8643 pPnoRequest->us5GProbeTemplateLen);
8644 }
8645
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +05308646 /* Driver gets only one time interval which is hardcoded in
8647 * supplicant for 10000ms. Taking power consumption into account 6 timers
8648 * will be used, Timervalue is increased exponentially i.e 10,20,40,
8649 * 80,160,320 secs. And number of scan cycle for each timer
8650 * is configurable through INI param gPNOScanTimerRepeatValue.
8651 * If it is set to 0 only one timer will be used and PNO scan cycle
8652 * will be repeated after each interval specified by supplicant
8653 * till PNO is disabled.
8654 */
8655 if (0 == pHddCtx->cfg_ini->configPNOScanTimerRepeatValue)
8656 pPnoRequest->scanTimers.ucScanTimersCount = HDD_PNO_SCAN_TIMERS_SET_ONE;
8657 else
8658 pPnoRequest->scanTimers.ucScanTimersCount =
8659 HDD_PNO_SCAN_TIMERS_SET_MULTIPLE;
8660
8661 tempInterval = (request->interval)/1000;
8662 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8663 "Base scan interval = %d PNOScanTimerRepeatValue = %d",
8664 tempInterval, pHddCtx->cfg_ini->configPNOScanTimerRepeatValue);
8665 for ( i = 0; i < pPnoRequest->scanTimers.ucScanTimersCount; i++)
8666 {
8667 pPnoRequest->scanTimers.aTimerValues[i].uTimerRepeat =
8668 pHddCtx->cfg_ini->configPNOScanTimerRepeatValue;
8669 pPnoRequest->scanTimers.aTimerValues[i].uTimerValue = tempInterval;
8670 tempInterval *= 2;
8671 }
8672 //Repeat last timer until pno disabled.
8673 pPnoRequest->scanTimers.aTimerValues[i-1].uTimerRepeat = 0;
8674
Madan Mohan Koyyalamudid206c7b2013-09-26 22:54:51 +05308675 pPnoRequest->modePNO = SIR_PNO_MODE_IMMEDIATE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308676
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +05308677 INIT_COMPLETION(pAdapter->pno_comp_var);
8678 pPnoRequest->statusCallback = hdd_cfg80211_sched_scan_start_status_cb;
8679 pPnoRequest->callbackContext = pAdapter;
8680 pAdapter->pno_req_status = 0;
8681
Nirav Shah80830bf2013-12-31 16:35:12 +05308682 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8683 "SessionId %d, enable %d, modePNO %d, ucScanTimersCount %d",
8684 pAdapter->sessionId, pPnoRequest->enable, pPnoRequest->modePNO,
8685 pPnoRequest->scanTimers.ucScanTimersCount);
8686
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308687 status = sme_SetPreferredNetworkList(WLAN_HDD_GET_HAL_CTX(pAdapter),
8688 pPnoRequest, pAdapter->sessionId,
8689 hdd_cfg80211_sched_scan_done_callback, pAdapter);
8690 if (eHAL_STATUS_SUCCESS != status)
8691 {
8692 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +05308693 "%s: Failed to enable PNO", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308694 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308695 goto error;
8696 }
8697
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +05308698 ret = wait_for_completion_timeout(
8699 &pAdapter->pno_comp_var,
8700 msecs_to_jiffies(WLAN_WAIT_TIME_PNO));
8701 if (0 >= ret)
8702 {
8703 // Did not receive the response for PNO enable in time.
8704 // Assuming the PNO enable was success.
8705 // Returning error from here, because we timeout, results
8706 // in side effect of Wifi (Wifi Setting) not to work.
8707 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8708 FL("Timed out waiting for PNO to be Enabled"));
8709 ret = 0;
8710 goto error;
8711 }
8712
8713 ret = pAdapter->pno_req_status;
c_hpothu37f21312014-04-09 21:49:54 +05308714 return ret;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05308715
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308716error:
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +05308717 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8718 FL("PNO scanRequest offloaded ret = %d"), ret);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308719 vos_mem_free(pPnoRequest);
c_hpothu37f21312014-04-09 21:49:54 +05308720 pHddCtx->isPnoEnable = FALSE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308721 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308722}
8723
8724/*
8725 * FUNCTION: wlan_hdd_cfg80211_sched_scan_stop
8726 * NL interface to disable PNO
8727 */
8728static int wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
8729 struct net_device *dev)
8730{
8731 eHalStatus status = eHAL_STATUS_FAILURE;
8732 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
8733 hdd_context_t *pHddCtx;
8734 tHalHandle hHal;
8735 tpSirPNOScanReq pPnoRequest = NULL;
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308736 int ret = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308737
8738 ENTER();
8739
8740 if (NULL == pAdapter)
8741 {
8742 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
8743 "%s: HDD adapter is Null", __func__);
8744 return -ENODEV;
8745 }
8746
8747 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308748
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308749 if (NULL == pHddCtx)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308750 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05308751 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308752 "%s: HDD context is Null", __func__);
8753 return -ENODEV;
8754 }
8755
8756 /* The return 0 is intentional when isLogpInProgress and
8757 * isLoadUnloadInProgress. We did observe a crash due to a return of
8758 * failure in sched_scan_stop , especially for a case where the unload
8759 * of the happens at the same time. The function __cfg80211_stop_sched_scan
8760 * was clearing rdev->sched_scan_req only when the sched_scan_stop returns
8761 * success. If it returns a failure , then its next invocation due to the
8762 * clean up of the second interface will have the dev pointer corresponding
8763 * to the first one leading to a crash.
8764 */
8765 if (pHddCtx->isLogpInProgress)
8766 {
8767 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8768 "%s: LOGP in Progress. Ignore!!!", __func__);
8769 return ret;
8770 }
8771
Mihir Shete18156292014-03-11 15:38:30 +05308772 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308773 {
8774 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8775 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
8776 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308777 }
8778
8779 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
8780 if (NULL == hHal)
8781 {
8782 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8783 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05308784 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308785 }
8786
8787 pPnoRequest = (tpSirPNOScanReq) vos_mem_malloc(sizeof (tSirPNOScanReq));
8788 if (NULL == pPnoRequest)
8789 {
8790 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
8791 "%s: vos_mem_malloc failed", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308792 return -ENOMEM;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308793 }
8794
8795 memset(pPnoRequest, 0, sizeof (tSirPNOScanReq));
8796 pPnoRequest->enable = 0; /* Disable PNO */
8797 pPnoRequest->ucNetworksCount = 0;
8798
8799 status = sme_SetPreferredNetworkList(hHal, pPnoRequest,
8800 pAdapter->sessionId,
8801 NULL, pAdapter);
8802 if (eHAL_STATUS_SUCCESS != status)
8803 {
8804 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8805 "Failed to disabled PNO");
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308806 ret = -EINVAL;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +05308807 goto error;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308808 }
c_hpothu37f21312014-04-09 21:49:54 +05308809 pHddCtx->isPnoEnable = FALSE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308810
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +05308811error:
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05308812 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +05308813 FL("PNO scan disabled ret = %d"), ret);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308814 vos_mem_free(pPnoRequest);
8815
8816 EXIT();
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308817 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308818}
8819
8820#endif /*FEATURE_WLAN_SCAN_PNO*/
8821
8822
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008823#ifdef FEATURE_WLAN_TDLS
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +05308824#if TDLS_MGMT_VERSION2
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008825static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
8826 u8 *peer, u8 action_code, u8 dialog_token,
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +05308827 u16 status_code, u32 peer_capability, const u8 *buf, size_t len)
8828#else
8829static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
8830 u8 *peer, u8 action_code, u8 dialog_token,
8831 u16 status_code, const u8 *buf, size_t len)
8832#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008833{
8834
8835 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
8836 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008837 u8 peerMac[6];
8838 VOS_STATUS status;
Gopichand Nakkala05922802013-03-14 12:23:19 -07008839 int max_sta_failed = 0;
Hoonki Leea34dd892013-02-05 22:56:02 -08008840 int responder;
Hoonki Leed37cbb32013-04-20 00:31:14 -07008841 long rc;
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +05308842#if !(TDLS_MGMT_VERSION2)
8843 u32 peer_capability = 0;
8844#endif
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05308845 tANI_U16 numCurrTdlsPeers;
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008846
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308847 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
8848 TRACE_CODE_HDD_CFG80211_TDLS_MGMT,
8849 pAdapter->sessionId, action_code));
Hoonki Lee11f7dda2013-02-14 16:55:44 -08008850 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008851 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308852 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008853 "Invalid arguments");
8854 return -EINVAL;
8855 }
8856
Sameer Thalappil75ea31a2013-02-21 19:38:16 -08008857 if (pHddCtx->isLogpInProgress)
8858 {
8859 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8860 "%s:LOGP in Progress. Ignore!!!", __func__);
Gopichand Nakkala05922802013-03-14 12:23:19 -07008861 wlan_hdd_tdls_set_link_status(pAdapter, peer, eTDLS_LINK_IDLE);
Sameer Thalappil75ea31a2013-02-21 19:38:16 -08008862 return -EBUSY;
8863 }
8864
Hoonki Lee27511902013-03-14 18:19:06 -07008865 if (eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode)
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008866 {
Hoonki Lee27511902013-03-14 18:19:06 -07008867 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
8868 "%s: TDLS mode is disabled OR not enabled in FW."
8869 MAC_ADDRESS_STR " action %d declined.",
8870 __func__, MAC_ADDR_ARRAY(peer), action_code);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008871 return -ENOTSUPP;
8872 }
Lee Hoonkic1262f22013-01-24 21:59:00 -08008873
Hoonki Lee27511902013-03-14 18:19:06 -07008874 /* other than teardown frame, other mgmt frames are not sent if disabled */
8875 if (SIR_MAC_TDLS_TEARDOWN != action_code)
8876 {
8877 /* if tdls_mode is disabled to respond to peer's request */
8878 if (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode)
8879 {
8880 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
8881 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07008882 " TDLS mode is disabled. action %d declined.",
8883 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee27511902013-03-14 18:19:06 -07008884
8885 return -ENOTSUPP;
8886 }
8887 }
8888
Gopichand Nakkalab977a972013-02-18 19:15:09 -08008889 if (WLAN_IS_TDLS_SETUP_ACTION(action_code))
8890 {
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308891 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, peer, TRUE))
Gopichand Nakkalab977a972013-02-18 19:15:09 -08008892 {
8893 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07008894 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07008895 " TDLS setup is ongoing. action %d declined.",
8896 __func__, MAC_ADDR_ARRAY(peer), action_code);
8897 return -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -08008898 }
8899 }
8900
Hoonki Lee11f7dda2013-02-14 16:55:44 -08008901 if (SIR_MAC_TDLS_SETUP_REQ == action_code ||
8902 SIR_MAC_TDLS_SETUP_RSP == action_code )
Lee Hoonkic1262f22013-01-24 21:59:00 -08008903 {
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05308904 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
8905 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Lee Hoonkic1262f22013-01-24 21:59:00 -08008906 {
8907 /* supplicant still sends tdls_mgmt(SETUP_REQ) even after
8908 we return error code at 'add_station()'. Hence we have this
8909 check again in addtion to add_station().
8910 Anyway, there is no hard to double-check. */
Hoonki Lee11f7dda2013-02-14 16:55:44 -08008911 if (SIR_MAC_TDLS_SETUP_REQ == action_code)
Lee Hoonkic1262f22013-01-24 21:59:00 -08008912 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07008913 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8914 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05308915 " TDLS Max peer already connected. action (%d) declined. Num of peers (%d), Max allowed (%d).",
8916 __func__, MAC_ADDR_ARRAY(peer), action_code,
8917 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Sunil Dutt388ac8f2013-11-28 18:06:52 +05308918 return -EINVAL;
Lee Hoonkic1262f22013-01-24 21:59:00 -08008919 }
8920 else
8921 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -08008922 /* maximum reached. tweak to send error code to peer and return
8923 error code to supplicant */
Lee Hoonkic1262f22013-01-24 21:59:00 -08008924 status_code = eSIR_MAC_UNSPEC_FAILURE_STATUS;
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07008925 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8926 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05308927 " TDLS Max peer already connected, send response status (%d). Num of peers (%d), Max allowed (%d).",
8928 __func__, MAC_ADDR_ARRAY(peer), status_code,
8929 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -07008930 max_sta_failed = -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -08008931 /* fall through to send setup resp with failure status
8932 code */
Lee Hoonkic1262f22013-01-24 21:59:00 -08008933 }
8934 }
Hoonki Lee11f7dda2013-02-14 16:55:44 -08008935 else
8936 {
8937 hddTdlsPeer_t *pTdlsPeer;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308938 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008939 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Hoonki Lee11f7dda2013-02-14 16:55:44 -08008940 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07008941 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07008942 "%s:" MAC_ADDRESS_STR " already connected. action %d declined.",
8943 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee11f7dda2013-02-14 16:55:44 -08008944 return -EPERM;
8945 }
8946 }
Lee Hoonkic1262f22013-01-24 21:59:00 -08008947 }
Hoonki Lee11f7dda2013-02-14 16:55:44 -08008948 vos_mem_copy(peerMac, peer, 6);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008949
Hoonki Lee1090c6a2013-01-16 17:40:54 -08008950#ifdef WLAN_FEATURE_TDLS_DEBUG
8951 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +05308952 "%s: " MAC_ADDRESS_STR " action %d, dialog_token %d status %d, len = %zu",
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07008953 "tdls_mgmt", MAC_ADDR_ARRAY(peer),
8954 action_code, dialog_token, status_code, len);
Hoonki Lee1090c6a2013-01-16 17:40:54 -08008955#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008956
Hoonki Leea34dd892013-02-05 22:56:02 -08008957 /*Except teardown responder will not be used so just make 0*/
8958 responder = 0;
Hoonki Lee11f7dda2013-02-14 16:55:44 -08008959 if (SIR_MAC_TDLS_TEARDOWN == action_code)
Hoonki Leea34dd892013-02-05 22:56:02 -08008960 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -07008961
8962 hddTdlsPeer_t *pTdlsPeer;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308963 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peerMac, TRUE);
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -07008964
8965 if(pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
8966 responder = pTdlsPeer->is_responder;
8967 else
Hoonki Leea34dd892013-02-05 22:56:02 -08008968 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -07008969 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +05308970 "%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 -07008971 __func__, MAC_ADDR_ARRAY(peer), (NULL == pTdlsPeer) ? -1 : pTdlsPeer->link_status,
8972 dialog_token, status_code, len);
8973 return -EPERM;
Hoonki Leea34dd892013-02-05 22:56:02 -08008974 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008975 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008976
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +05308977 /* For explicit trigger of DIS_REQ come out of BMPS for
8978 successfully receiving DIS_RSP from peer. */
Hoonki Lee14621352013-04-16 17:51:19 -07008979 if ((SIR_MAC_TDLS_SETUP_RSP == action_code) ||
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +05308980 (SIR_MAC_TDLS_DIS_RSP == action_code) ||
8981 (SIR_MAC_TDLS_DIS_REQ == action_code))
Hoonki Lee14621352013-04-16 17:51:19 -07008982 {
8983 if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter)))
8984 {
8985 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +05308986 "%s: Sending frame action_code %u.Disable BMPS", __func__, action_code);
Hoonki Lee14621352013-04-16 17:51:19 -07008987 hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
8988 }
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +05308989 if (SIR_MAC_TDLS_DIS_REQ != action_code)
8990 wlan_hdd_tdls_set_cap(pAdapter, peerMac, eTDLS_CAP_SUPPORTED);
Hoonki Lee14621352013-04-16 17:51:19 -07008991 }
8992
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008993 /* make sure doesn't call send_mgmt() while it is pending */
8994 if (TDLS_CTX_MAGIC == pAdapter->mgmtTxCompletionStatus)
8995 {
8996 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008997 "%s: " MAC_ADDRESS_STR " action %d couldn't sent, as one is pending. return EBUSY",
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008998 __func__, MAC_ADDR_ARRAY(peer), action_code);
8999 return -EBUSY;
9000 }
9001
9002 pAdapter->mgmtTxCompletionStatus = TDLS_CTX_MAGIC;
Gopichand Nakkalab977a972013-02-18 19:15:09 -08009003 INIT_COMPLETION(pAdapter->tdls_mgmt_comp);
9004
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009005 status = sme_SendTdlsMgmtFrame(WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
Pradeep Reddy POTTETIca171f82014-03-21 14:17:35 +05309006 peerMac, action_code, dialog_token, status_code, peer_capability, (tANI_U8 *)buf, len, responder);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009007
Gopichand Nakkalab977a972013-02-18 19:15:09 -08009008 if (VOS_STATUS_SUCCESS != status)
9009 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009010 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9011 "%s: sme_SendTdlsMgmtFrame failed!", __func__);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07009012 pAdapter->mgmtTxCompletionStatus = FALSE;
Hoonki Lee14621352013-04-16 17:51:19 -07009013 wlan_hdd_tdls_check_bmps(pAdapter);
Sunil Dutt388ac8f2013-11-28 18:06:52 +05309014 return -EINVAL;
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009015 }
9016
Hoonki Leed37cbb32013-04-20 00:31:14 -07009017 rc = wait_for_completion_interruptible_timeout(&pAdapter->tdls_mgmt_comp,
9018 msecs_to_jiffies(WAIT_TIME_TDLS_MGMT));
9019
9020 if ((rc <= 0) || (TRUE != pAdapter->mgmtTxCompletionStatus))
Gopichand Nakkalab977a972013-02-18 19:15:09 -08009021 {
Hoonki Leed37cbb32013-04-20 00:31:14 -07009022 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07009023 "%s: Mgmt Tx Completion failed status %ld TxCompletion %u",
Hoonki Leed37cbb32013-04-20 00:31:14 -07009024 __func__, rc, pAdapter->mgmtTxCompletionStatus);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07009025 pAdapter->mgmtTxCompletionStatus = FALSE;
Yue Ma4f55ef32014-01-23 16:45:33 -08009026
9027 if (pHddCtx->isLogpInProgress)
9028 {
9029 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9030 "%s: LOGP in Progress. Ignore!!!", __func__);
9031 return -EAGAIN;
9032 }
9033
Hoonki Leed37cbb32013-04-20 00:31:14 -07009034 wlan_hdd_tdls_check_bmps(pAdapter);
Sunil Dutt388ac8f2013-11-28 18:06:52 +05309035 return -EINVAL;
Gopichand Nakkalab977a972013-02-18 19:15:09 -08009036 }
9037
Gopichand Nakkala05922802013-03-14 12:23:19 -07009038 if (max_sta_failed)
Hoonki Lee14621352013-04-16 17:51:19 -07009039 {
9040 wlan_hdd_tdls_check_bmps(pAdapter);
Gopichand Nakkala05922802013-03-14 12:23:19 -07009041 return max_sta_failed;
Hoonki Lee14621352013-04-16 17:51:19 -07009042 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -08009043
Hoonki Leea34dd892013-02-05 22:56:02 -08009044 if (SIR_MAC_TDLS_SETUP_RSP == action_code)
9045 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -08009046 wlan_hdd_tdls_set_responder(pAdapter, peerMac, TRUE);
Hoonki Leea34dd892013-02-05 22:56:02 -08009047 }
9048 else if (SIR_MAC_TDLS_SETUP_CNF == action_code)
9049 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -08009050 wlan_hdd_tdls_set_responder(pAdapter, peerMac, FALSE);
Hoonki Leea34dd892013-02-05 22:56:02 -08009051 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009052
9053 return 0;
9054}
9055
9056static int wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
9057 u8 *peer, enum nl80211_tdls_operation oper)
9058{
9059 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
9060 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309061 int status;
Hoonki Lee5305c3a2013-04-29 23:28:59 -07009062 hddTdlsPeer_t *pTdlsPeer;
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009063
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309064 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
9065 TRACE_CODE_HDD_CFG80211_TDLS_OPER,
9066 pAdapter->sessionId, oper));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309067 if ( NULL == peer )
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009068 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -08009069 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chilam Ngc4244af2013-04-01 15:37:32 -07009070 "%s: Invalid arguments", __func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009071 return -EINVAL;
9072 }
Hoonki Lee1090c6a2013-01-16 17:40:54 -08009073
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309074 status = wlan_hdd_validate_context(pHddCtx);
9075
9076 if (0 != status)
Sameer Thalappil75ea31a2013-02-21 19:38:16 -08009077 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309078 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9079 "%s: HDD context is not valid", __func__);
9080 return status;
Sameer Thalappil75ea31a2013-02-21 19:38:16 -08009081 }
9082
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009083
9084 if( FALSE == pHddCtx->cfg_ini->fEnableTDLSSupport ||
Hoonki Lee1090c6a2013-01-16 17:40:54 -08009085 FALSE == sme_IsFeatureSupportedByFW(TDLS))
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009086 {
Hoonki Lee1090c6a2013-01-16 17:40:54 -08009087 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chilam Ngc4244af2013-04-01 15:37:32 -07009088 "TDLS Disabled in INI OR not enabled in FW. "
9089 "Cannot process TDLS commands");
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009090 return -ENOTSUPP;
9091 }
9092
9093 switch (oper) {
9094 case NL80211_TDLS_ENABLE_LINK:
9095 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009096 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309097 long ret;
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05309098 tCsrTdlsLinkEstablishParams tdlsLinkEstablishParams;
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009099
Sunil Dutt41de4e22013-11-14 18:09:02 +05309100 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
9101
9102 if ( NULL == pTdlsPeer ) {
9103 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
9104 " (oper %d) not exsting. ignored",
9105 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
9106 return -EINVAL;
9107 }
9108
9109 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9110 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
9111 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
9112 "NL80211_TDLS_ENABLE_LINK");
9113
Gopichand Nakkala2f4a2822013-04-17 11:22:01 -07009114 if (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
9115 {
9116 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Staion Index %u "
9117 MAC_ADDRESS_STR " failed",
9118 __func__, pTdlsPeer->staId, MAC_ADDR_ARRAY(peer));
9119 return -EINVAL;
9120 }
9121
Hoonki Lee5305c3a2013-04-29 23:28:59 -07009122 if (eTDLS_LINK_CONNECTED != pTdlsPeer->link_status)
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07009123 {
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +05309124 if (IS_ADVANCE_TDLS_ENABLE) {
Gopichand Nakkala24be5312013-07-02 16:47:12 +05309125
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +05309126 if (0 != wlan_hdd_tdls_get_link_establish_params(
9127 pAdapter, peer,&tdlsLinkEstablishParams)) {
9128 return -EINVAL;
9129 }
9130 INIT_COMPLETION(pAdapter->tdls_link_establish_req_comp);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05309131
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +05309132 sme_SendTdlsLinkEstablishParams(WLAN_HDD_GET_HAL_CTX(pAdapter),
9133 pAdapter->sessionId, peer, &tdlsLinkEstablishParams);
9134 /* Send TDLS peer UAPSD capabilities to the firmware and
9135 * register with the TL on after the response for this operation
9136 * is received .
9137 */
9138 ret = wait_for_completion_interruptible_timeout(
9139 &pAdapter->tdls_link_establish_req_comp,
9140 msecs_to_jiffies(WAIT_TIME_TDLS_LINK_ESTABLISH_REQ));
9141 if (ret <= 0)
9142 {
9143 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9144 "%s: Link Establish Request Faled Status %ld",
9145 __func__, ret);
9146 return -EINVAL;
9147 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05309148 }
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -07009149 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer, eTDLS_LINK_CONNECTED);
Gopichand Nakkala471708b2013-06-04 20:03:01 +05309150 /* Mark TDLS client Authenticated .*/
9151 status = WLANTL_ChangeSTAState( pHddCtx->pvosContext,
9152 pTdlsPeer->staId,
9153 WLANTL_STA_AUTHENTICATED);
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -07009154 if (VOS_STATUS_SUCCESS == status)
9155 {
Hoonki Lee14621352013-04-16 17:51:19 -07009156 if (pTdlsPeer->is_responder == 0)
9157 {
9158 v_U8_t staId = (v_U8_t)pTdlsPeer->staId;
9159
9160 wlan_hdd_tdls_timer_restart(pAdapter,
9161 &pTdlsPeer->initiatorWaitTimeoutTimer,
9162 WAIT_TIME_TDLS_INITIATOR);
9163 /* suspend initiator TX until it receives direct packet from the
9164 reponder or WAIT_TIME_TDLS_INITIATOR timer expires */
9165 WLANTL_SuspendDataTx( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
9166 &staId, NULL);
9167 }
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -07009168 wlan_hdd_tdls_increment_peer_count(pAdapter);
9169 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07009170 wlan_hdd_tdls_check_bmps(pAdapter);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05309171
9172 /* Update TL about the UAPSD masks , to route the packets to firmware */
Gopichand Nakkala574f6d12013-06-27 19:38:43 +05309173 if ((TRUE == pHddCtx->cfg_ini->fEnableTDLSBufferSta)
9174 || pHddCtx->cfg_ini->fTDLSUapsdMask )
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05309175 {
Gopichand Nakkala574f6d12013-06-27 19:38:43 +05309176 int ac;
9177 uint8 ucAc[4] = { WLANTL_AC_VO,
9178 WLANTL_AC_VI,
9179 WLANTL_AC_BK,
9180 WLANTL_AC_BE };
9181 uint8 tlTid[4] = { 7, 5, 2, 3 } ;
9182 for(ac=0; ac < 4; ac++)
9183 {
9184 status = WLANTL_EnableUAPSDForAC( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
9185 pTdlsPeer->staId, ucAc[ac],
9186 tlTid[ac], tlTid[ac], 0, 0,
9187 WLANTL_BI_DIR );
9188 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05309189 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07009190 }
9191
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009192 }
9193 break;
9194 case NL80211_TDLS_DISABLE_LINK:
Lee Hoonkic1262f22013-01-24 21:59:00 -08009195 {
Sunil Dutt41de4e22013-11-14 18:09:02 +05309196 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
9197
9198 if ( NULL == pTdlsPeer ) {
9199 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
9200 " (oper %d) not exsting. ignored",
9201 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
9202 return -EINVAL;
9203 }
9204
9205 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9206 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
9207 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
9208 "NL80211_TDLS_DISABLE_LINK");
9209
Hoonki Lee5305c3a2013-04-29 23:28:59 -07009210 if(TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
Lee Hoonkic1262f22013-01-24 21:59:00 -08009211 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009212 long status;
9213
9214 INIT_COMPLETION(pAdapter->tdls_del_station_comp);
9215
Lee Hoonkic1262f22013-01-24 21:59:00 -08009216 sme_DeleteTdlsPeerSta( WLAN_HDD_GET_HAL_CTX(pAdapter),
9217 pAdapter->sessionId, peer );
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009218
9219 status = wait_for_completion_interruptible_timeout(&pAdapter->tdls_del_station_comp,
9220 msecs_to_jiffies(WAIT_TIME_TDLS_DEL_STA));
9221 if (status <= 0)
9222 {
Hoonki Lee5305c3a2013-04-29 23:28:59 -07009223 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer, eTDLS_LINK_IDLE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009224 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9225 "%s: Del station failed status %ld",
9226 __func__, status);
9227 return -EPERM;
9228 }
Hoonki Lee5305c3a2013-04-29 23:28:59 -07009229 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer, eTDLS_LINK_IDLE);
Lee Hoonkic1262f22013-01-24 21:59:00 -08009230 }
9231 else
9232 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07009233 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9234 "%s: TDLS Peer Station doesn't exist.", __func__);
Lee Hoonkic1262f22013-01-24 21:59:00 -08009235 }
Lee Hoonkic1262f22013-01-24 21:59:00 -08009236 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07009237 break;
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009238 case NL80211_TDLS_TEARDOWN:
Sunil Dutt41de4e22013-11-14 18:09:02 +05309239 {
9240 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9241 " %s : NL80211_TDLS_TEARDOWN for " MAC_ADDRESS_STR,
9242 __func__, MAC_ADDR_ARRAY(peer));
9243
9244 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
9245 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
9246
9247 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9248 " %s TDLS External control and Implicit Trigger not enabled ",
9249 __func__);
9250 return -ENOTSUPP;
9251 }
9252
Sunil Dutt41de4e22013-11-14 18:09:02 +05309253
9254 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
9255
9256 if ( NULL == pTdlsPeer ) {
9257 hddLog(VOS_TRACE_LEVEL_INFO, "%s: " MAC_ADDRESS_STR
9258 " peer not exsting",
9259 __func__, MAC_ADDR_ARRAY(peer));
Naresh Jayaram937abdf2013-11-26 19:50:25 +05309260 return -EINVAL;
Sunil Dutt41de4e22013-11-14 18:09:02 +05309261 }
9262 else {
9263 wlan_hdd_tdls_indicate_teardown(pAdapter, pTdlsPeer,
9264 eSIR_MAC_TDLS_TEARDOWN_UNSPEC_REASON);
9265 }
Naresh Jayaram937abdf2013-11-26 19:50:25 +05309266
9267 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, FALSE) )
9268 return -EINVAL;
Sunil Dutt41de4e22013-11-14 18:09:02 +05309269 break;
9270 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009271 case NL80211_TDLS_SETUP:
Sunil Dutt41de4e22013-11-14 18:09:02 +05309272 {
Naresh Jayaramdb4514b2013-11-25 18:08:10 +05309273 hddTdlsPeer_t *pTdlsPeer;
Sunil Dutt41de4e22013-11-14 18:09:02 +05309274 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9275 " %s : NL80211_TDLS_SETUP for " MAC_ADDRESS_STR,
9276 __func__, MAC_ADDR_ARRAY(peer));
9277
9278 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
9279 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
9280
9281 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9282 " %s TDLS External control and Implicit Trigger not enabled ",
9283 __func__);
9284 return -ENOTSUPP;
9285 }
9286
Naresh Jayaramdb4514b2013-11-25 18:08:10 +05309287 /* To cater the requirement of establishing the TDLS link
9288 * irrespective of the data traffic , get an entry of TDLS peer.
9289 */
9290 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, peer);
9291 if (pTdlsPeer == NULL) {
9292 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9293 "%s: peer " MAC_ADDRESS_STR " not existing",
9294 __func__, MAC_ADDR_ARRAY(peer));
9295 return -EINVAL;
9296 }
Naresh Jayaram937abdf2013-11-26 19:50:25 +05309297
9298 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, TRUE) ) {
9299
9300 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9301 " %s TDLS Add Force Peer Failed",
9302 __func__);
9303 return -EINVAL;
9304 }
Naresh Jayaramdb4514b2013-11-25 18:08:10 +05309305 break;
Sunil Dutt41de4e22013-11-14 18:09:02 +05309306 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009307 case NL80211_TDLS_DISCOVERY_REQ:
9308 /* We don't support in-driver setup/teardown/discovery */
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309309 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
9310 "%s: We don't support in-driver setup/teardown/discovery "
9311 ,__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009312 return -ENOTSUPP;
9313 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309314 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9315 "%s: unsupported event",__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009316 return -ENOTSUPP;
9317 }
9318 return 0;
9319}
Chilam NG571c65a2013-01-19 12:27:36 +05309320
9321int wlan_hdd_cfg80211_send_tdls_discover_req(struct wiphy *wiphy,
9322 struct net_device *dev, u8 *peer)
9323{
Arif Hussaina7c8e412013-11-20 11:06:42 -08009324 hddLog(VOS_TRACE_LEVEL_INFO,
9325 "tdls send discover req: "MAC_ADDRESS_STR,
9326 MAC_ADDR_ARRAY(peer));
Chilam NG571c65a2013-01-19 12:27:36 +05309327
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +05309328#if TDLS_MGMT_VERSION2
9329 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
9330 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
9331#else
Chilam NG571c65a2013-01-19 12:27:36 +05309332 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
9333 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, NULL, 0);
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +05309334#endif
Chilam NG571c65a2013-01-19 12:27:36 +05309335}
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009336#endif
9337
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309338#ifdef WLAN_FEATURE_GTK_OFFLOAD
9339/*
9340 * FUNCTION: wlan_hdd_cfg80211_update_replayCounterCallback
9341 * Callback rountine called upon receiving response for
9342 * get offload info
9343 */
9344void wlan_hdd_cfg80211_update_replayCounterCallback(void *callbackContext,
9345 tpSirGtkOffloadGetInfoRspParams pGtkOffloadGetInfoRsp)
9346{
9347
9348 hdd_adapter_t *pAdapter = (hdd_adapter_t *)callbackContext;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05309349 tANI_U8 tempReplayCounter[8];
9350 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309351
9352 ENTER();
9353
9354 if (NULL == pAdapter)
9355 {
Agarwal Ashish971c2882013-10-30 20:11:12 +05309356 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309357 "%s: HDD adapter is Null", __func__);
9358 return ;
9359 }
9360
9361 if (NULL == pGtkOffloadGetInfoRsp)
9362 {
9363 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9364 "%s: pGtkOffloadGetInfoRsp is Null", __func__);
9365 return ;
9366 }
9367
9368 if (VOS_STATUS_SUCCESS != pGtkOffloadGetInfoRsp->ulStatus)
9369 {
9370 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9371 "%s: wlan Failed to get replay counter value",
9372 __func__);
9373 return ;
9374 }
9375
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05309376 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9377 /* Update replay counter */
9378 pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter =
9379 pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
9380
9381 {
9382 /* changing from little to big endian since supplicant
9383 * works on big endian format
9384 */
9385 int i;
9386 tANI_U8 *p = (tANI_U8 *)&pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
9387
9388 for (i = 0; i < 8; i++)
9389 {
9390 tempReplayCounter[7-i] = (tANI_U8)p[i];
9391 }
9392 }
9393
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309394 /* Update replay counter to NL */
9395 cfg80211_gtk_rekey_notify(pAdapter->dev, pGtkOffloadGetInfoRsp->bssId,
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05309396 tempReplayCounter, GFP_KERNEL);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309397}
9398
9399/*
9400 * FUNCTION: wlan_hdd_cfg80211_set_rekey_data
9401 * This function is used to offload GTK rekeying job to the firmware.
9402 */
9403int wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
9404 struct cfg80211_gtk_rekey_data *data)
9405{
9406 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
9407 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
9408 hdd_station_ctx_t *pHddStaCtx;
9409 tHalHandle hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309410 int result;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05309411 tSirGtkOffloadParams hddGtkOffloadReqParams;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309412 eHalStatus status = eHAL_STATUS_FAILURE;
9413
9414 ENTER();
9415
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309416
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309417 if (NULL == pAdapter)
9418 {
9419 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
9420 "%s: HDD adapter is Null", __func__);
9421 return -ENODEV;
9422 }
9423
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309424 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
9425 TRACE_CODE_HDD_CFG80211_SET_REKEY_DATA,
9426 pAdapter->sessionId, pAdapter->device_mode));
9427
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309428 result = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309429
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309430 if (0 != result)
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309431 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309432 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9433 "%s: HDD context is not valid", __func__);
9434 return result;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309435 }
9436
9437 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9438 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
9439 if (NULL == hHal)
9440 {
9441 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9442 "%s: HAL context is Null!!!", __func__);
9443 return -EAGAIN;
9444 }
9445
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05309446 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_ENABLE;
9447 memcpy(pHddStaCtx->gtkOffloadReqParams.aKCK, data->kck, NL80211_KCK_LEN);
9448 memcpy(pHddStaCtx->gtkOffloadReqParams.aKEK, data->kek, NL80211_KEK_LEN);
9449 memcpy(pHddStaCtx->gtkOffloadReqParams.bssId, &pHddStaCtx->conn_info.bssId,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309450 WNI_CFG_BSSID_LEN);
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05309451 {
9452 /* changing from big to little endian since driver
9453 * works on little endian format
9454 */
9455 tANI_U8 *p =
9456 (tANI_U8 *)&pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter;
9457 int i;
9458
9459 for (i = 0; i < 8; i++)
9460 {
9461 p[7-i] = data->replay_ctr[i];
9462 }
9463 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309464
9465 if (TRUE == pHddCtx->hdd_wlan_suspended)
9466 {
9467 /* if wlan is suspended, enable GTK offload directly from here */
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05309468 memcpy(&hddGtkOffloadReqParams, &pHddStaCtx->gtkOffloadReqParams,
9469 sizeof (tSirGtkOffloadParams));
9470 status = sme_SetGTKOffload(hHal, &hddGtkOffloadReqParams,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309471 pAdapter->sessionId);
9472
9473 if (eHAL_STATUS_SUCCESS != status)
9474 {
9475 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9476 "%s: sme_SetGTKOffload failed, returned %d",
9477 __func__, status);
9478 return status;
9479 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309480 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9481 "%s: sme_SetGTKOffload successfull", __func__);
9482 }
9483 else
9484 {
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309485 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9486 "%s: wlan not suspended GTKOffload request is stored",
9487 __func__);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309488 }
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05309489
9490 return eHAL_STATUS_SUCCESS;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309491}
9492#endif /*WLAN_FEATURE_GTK_OFFLOAD*/
9493
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05309494/*
9495 * FUNCTION: wlan_hdd_cfg80211_set_mac_acl
9496 * This function is used to set access control policy
9497 */
9498static int wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy,
9499 struct net_device *dev, const struct cfg80211_acl_data *params)
9500{
9501 int i;
9502 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
9503 hdd_hostapd_state_t *pHostapdState;
9504 tsap_Config_t *pConfig;
9505 v_CONTEXT_t pVosContext = NULL;
9506 hdd_context_t *pHddCtx;
9507 int status;
9508
9509 ENTER();
9510
9511 if (NULL == pAdapter)
9512 {
9513 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
9514 "%s: HDD adapter is Null", __func__);
9515 return -ENODEV;
9516 }
9517
9518 if (NULL == params)
9519 {
9520 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
9521 "%s: params is Null", __func__);
9522 return -EINVAL;
9523 }
9524
9525 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9526 status = wlan_hdd_validate_context(pHddCtx);
9527
9528 if (0 != status)
9529 {
9530 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9531 "%s: HDD context is not valid", __func__);
9532 return status;
9533 }
9534
9535 pVosContext = pHddCtx->pvosContext;
9536 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
9537
9538 if (NULL == pHostapdState)
9539 {
9540 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
9541 "%s: pHostapdState is Null", __func__);
9542 return -EINVAL;
9543 }
9544
9545 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"acl policy: = %d"
9546 "no acl entries = %d", params->acl_policy, params->n_acl_entries);
9547
9548 if (WLAN_HDD_SOFTAP == pAdapter->device_mode)
9549 {
9550 pConfig = &pAdapter->sessionCtx.ap.sapConfig;
9551
9552 /* default value */
9553 pConfig->num_accept_mac = 0;
9554 pConfig->num_deny_mac = 0;
9555
9556 /**
9557 * access control policy
9558 * @NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED: Deny stations which are
9559 * listed in hostapd.deny file.
9560 * @NL80211_ACL_POLICY_DENY_UNLESS_LISTED: Allow stations which are
9561 * listed in hostapd.accept file.
9562 */
9563 if (NL80211_ACL_POLICY_DENY_UNLESS_LISTED == params->acl_policy)
9564 {
9565 pConfig->SapMacaddr_acl = eSAP_DENY_UNLESS_ACCEPTED;
9566 }
9567 else if (NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED == params->acl_policy)
9568 {
9569 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
9570 }
9571 else
9572 {
9573 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9574 "%s:Acl Policy : %d is not supported",
9575 __func__, params->acl_policy);
9576 return -ENOTSUPP;
9577 }
9578
9579 if (eSAP_DENY_UNLESS_ACCEPTED == pConfig->SapMacaddr_acl)
9580 {
9581 pConfig->num_accept_mac = params->n_acl_entries;
9582 for (i = 0; i < params->n_acl_entries; i++)
9583 {
9584 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9585 "** Add ACL MAC entry %i in WhiletList :"
9586 MAC_ADDRESS_STR, i,
9587 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
9588
9589 vos_mem_copy(&pConfig->accept_mac[i], params->mac_addrs[i].addr,
9590 sizeof(qcmacaddr));
9591 }
9592 }
9593 else if (eSAP_ACCEPT_UNLESS_DENIED == pConfig->SapMacaddr_acl)
9594 {
9595 pConfig->num_deny_mac = params->n_acl_entries;
9596 for (i = 0; i < params->n_acl_entries; i++)
9597 {
9598 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9599 "** Add ACL MAC entry %i in BlackList :"
9600 MAC_ADDRESS_STR, i,
9601 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
9602
9603 vos_mem_copy(&pConfig->deny_mac[i], params->mac_addrs[i].addr,
9604 sizeof(qcmacaddr));
9605 }
9606 }
9607
9608 if (VOS_STATUS_SUCCESS != WLANSAP_SetMacACL(pVosContext, pConfig))
9609 {
9610 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9611 "%s: SAP Set Mac Acl fail", __func__);
9612 return -EINVAL;
9613 }
9614 }
9615 else
9616 {
9617 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309618 "%s: Invalid device_mode = %s (%d)",
9619 __func__, hdd_device_modetoString(pAdapter->device_mode),
9620 pAdapter->device_mode);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05309621 return -EINVAL;
9622 }
9623
9624 return 0;
9625}
9626
Leo Chang9056f462013-08-01 19:21:11 -07009627#ifdef WLAN_NL80211_TESTMODE
9628#ifdef FEATURE_WLAN_LPHB
Leo Changd9df8aa2013-09-26 13:32:26 -07009629void wlan_hdd_cfg80211_lphb_ind_handler
Leo Chang9056f462013-08-01 19:21:11 -07009630(
9631 void *pAdapter,
9632 void *indCont
9633)
9634{
Leo Changd9df8aa2013-09-26 13:32:26 -07009635 tSirLPHBInd *lphbInd;
9636 struct sk_buff *skb;
c_hpothu73f35e62014-04-18 13:40:08 +05309637 hdd_context_t *pHddCtxt;
Leo Chang9056f462013-08-01 19:21:11 -07009638
9639 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -07009640 "LPHB indication arrived");
Leo Chang9056f462013-08-01 19:21:11 -07009641
c_hpothu73f35e62014-04-18 13:40:08 +05309642 if (pAdapter == NULL)
9643 {
9644 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9645 "%s: pAdapter is NULL\n",__func__);
9646 return;
9647 }
9648
Leo Chang9056f462013-08-01 19:21:11 -07009649 if (NULL == indCont)
9650 {
9651 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -07009652 "LPHB IND, invalid argument");
Leo Chang9056f462013-08-01 19:21:11 -07009653 return;
9654 }
9655
c_hpothu73f35e62014-04-18 13:40:08 +05309656 pHddCtxt = (hdd_context_t *)pAdapter;
Leo Changd9df8aa2013-09-26 13:32:26 -07009657 lphbInd = (tSirLPHBInd *)indCont;
Leo Chang9056f462013-08-01 19:21:11 -07009658 skb = cfg80211_testmode_alloc_event_skb(
c_hpothu73f35e62014-04-18 13:40:08 +05309659 pHddCtxt->wiphy,
Leo Changd9df8aa2013-09-26 13:32:26 -07009660 sizeof(tSirLPHBInd),
Leo Chang9056f462013-08-01 19:21:11 -07009661 GFP_ATOMIC);
9662 if (!skb)
9663 {
9664 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9665 "LPHB timeout, NL buffer alloc fail");
9666 return;
9667 }
9668
Leo Changac3ba772013-10-07 09:47:04 -07009669 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_CMD, WLAN_HDD_TM_CMD_WLAN_HB))
Leo Changd9df8aa2013-09-26 13:32:26 -07009670 {
9671 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9672 "WLAN_HDD_TM_ATTR_CMD put fail");
9673 goto nla_put_failure;
9674 }
Leo Changac3ba772013-10-07 09:47:04 -07009675 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_TYPE, lphbInd->protocolType))
Leo Changd9df8aa2013-09-26 13:32:26 -07009676 {
9677 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9678 "WLAN_HDD_TM_ATTR_TYPE put fail");
9679 goto nla_put_failure;
9680 }
Leo Changac3ba772013-10-07 09:47:04 -07009681 if(nla_put(skb, WLAN_HDD_TM_ATTR_DATA,
Leo Changd9df8aa2013-09-26 13:32:26 -07009682 sizeof(tSirLPHBInd), lphbInd))
9683 {
9684 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9685 "WLAN_HDD_TM_ATTR_DATA put fail");
9686 goto nla_put_failure;
9687 }
Leo Chang9056f462013-08-01 19:21:11 -07009688 cfg80211_testmode_event(skb, GFP_ATOMIC);
9689 return;
9690
9691nla_put_failure:
9692 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9693 "NLA Put fail");
9694 kfree_skb(skb);
9695
9696 return;
9697}
9698#endif /* FEATURE_WLAN_LPHB */
9699
9700static int wlan_hdd_cfg80211_testmode(struct wiphy *wiphy, void *data, int len)
9701{
9702 struct nlattr *tb[WLAN_HDD_TM_ATTR_MAX + 1];
9703 int err = 0;
9704#ifdef FEATURE_WLAN_LPHB
9705 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Leo Changd9df8aa2013-09-26 13:32:26 -07009706 eHalStatus smeStatus;
Leo Chang9056f462013-08-01 19:21:11 -07009707#endif /* FEATURE_WLAN_LPHB */
9708
9709 err = nla_parse(tb, WLAN_HDD_TM_ATTR_MAX, data, len, wlan_hdd_tm_policy);
9710 if (err)
9711 {
9712 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9713 "%s Testmode INV ATTR", __func__);
9714 return err;
9715 }
9716
9717 if (!tb[WLAN_HDD_TM_ATTR_CMD])
9718 {
9719 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9720 "%s Testmode INV CMD", __func__);
9721 return -EINVAL;
9722 }
9723
9724 switch (nla_get_u32(tb[WLAN_HDD_TM_ATTR_CMD]))
9725 {
9726#ifdef FEATURE_WLAN_LPHB
9727 /* Low Power Heartbeat configuration request */
9728 case WLAN_HDD_TM_CMD_WLAN_HB:
9729 {
9730 int buf_len;
9731 void *buf;
9732 tSirLPHBReq *hb_params = NULL;
Amar Singhal05852702014-02-04 14:40:00 -08009733 tSirLPHBReq *hb_params_temp = NULL;
Leo Chang9056f462013-08-01 19:21:11 -07009734
9735 if (!tb[WLAN_HDD_TM_ATTR_DATA])
9736 {
9737 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9738 "%s Testmode INV DATA", __func__);
9739 return -EINVAL;
9740 }
9741
9742 buf = nla_data(tb[WLAN_HDD_TM_ATTR_DATA]);
9743 buf_len = nla_len(tb[WLAN_HDD_TM_ATTR_DATA]);
Amar Singhal05852702014-02-04 14:40:00 -08009744
9745 hb_params_temp =(tSirLPHBReq *)buf;
9746 if ((hb_params_temp->cmd == LPHB_SET_TCP_PARAMS_INDID) &&
9747 (hb_params_temp->params.lphbTcpParamReq.timePeriodSec == 0))
9748 return -EINVAL;
9749
Leo Chang9056f462013-08-01 19:21:11 -07009750 hb_params = (tSirLPHBReq *)vos_mem_malloc(sizeof(tSirLPHBReq));
9751 if (NULL == hb_params)
9752 {
9753 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9754 "%s Request Buffer Alloc Fail", __func__);
9755 return -EINVAL;
9756 }
9757
9758 vos_mem_copy(hb_params, buf, buf_len);
Leo Changd9df8aa2013-09-26 13:32:26 -07009759 smeStatus = sme_LPHBConfigReq((tHalHandle)(pHddCtx->hHal),
9760 hb_params,
9761 wlan_hdd_cfg80211_lphb_ind_handler);
9762 if (eHAL_STATUS_SUCCESS != smeStatus)
Leo Chang9056f462013-08-01 19:21:11 -07009763 {
Leo Changd9df8aa2013-09-26 13:32:26 -07009764 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9765 "LPHB Config Fail, disable");
Leo Chang9056f462013-08-01 19:21:11 -07009766 vos_mem_free(hb_params);
9767 }
Leo Chang9056f462013-08-01 19:21:11 -07009768 return 0;
9769 }
9770#endif /* FEATURE_WLAN_LPHB */
9771 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309772 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9773 "%s: unsupported event",__func__);
Leo Chang9056f462013-08-01 19:21:11 -07009774 return -EOPNOTSUPP;
9775 }
9776
9777 return err;
9778}
9779#endif /* CONFIG_NL80211_TESTMODE */
9780
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +05309781static int wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
9782 struct net_device *dev,
9783 int idx, struct survey_info *survey)
9784{
9785 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
9786 hdd_context_t *pHddCtx;
Mihir Sheted9072e02013-08-21 17:02:29 +05309787 hdd_station_ctx_t *pHddStaCtx;
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +05309788 tHalHandle halHandle;
Mihir Sheted9072e02013-08-21 17:02:29 +05309789 v_U32_t channel = 0, freq = 0; /* Initialization Required */
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +05309790 v_S7_t snr,rssi;
9791 int status, i, j, filled = 0;
9792
9793 ENTER();
9794
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +05309795 if (NULL == pAdapter)
9796 {
9797 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
9798 "%s: HDD adapter is Null", __func__);
9799 return -ENODEV;
9800 }
9801
9802 if (NULL == wiphy)
9803 {
9804 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
9805 "%s: wiphy is Null", __func__);
9806 return -ENODEV;
9807 }
9808
9809 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9810 status = wlan_hdd_validate_context(pHddCtx);
9811
9812 if (0 != status)
9813 {
9814 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9815 "%s: HDD context is not valid", __func__);
9816 return status;
9817 }
9818
Mihir Sheted9072e02013-08-21 17:02:29 +05309819 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9820
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +05309821 if (0 == pHddCtx->cfg_ini->fEnableSNRMonitoring ||
Mihir Sheted9072e02013-08-21 17:02:29 +05309822 0 != pAdapter->survey_idx ||
9823 eConnectionState_Associated != pHddStaCtx->conn_info.connState)
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +05309824 {
9825 /* The survey dump ops when implemented completely is expected to
9826 * return a survey of all channels and the ops is called by the
9827 * kernel with incremental values of the argument 'idx' till it
9828 * returns -ENONET. But we can only support the survey for the
9829 * operating channel for now. survey_idx is used to track
9830 * that the ops is called only once and then return -ENONET for
9831 * the next iteration
9832 */
9833 pAdapter->survey_idx = 0;
9834 return -ENONET;
9835 }
9836
9837 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
9838
9839 wlan_hdd_get_snr(pAdapter, &snr);
9840 wlan_hdd_get_rssi(pAdapter, &rssi);
9841
9842 sme_GetOperationChannel(halHandle, &channel, pAdapter->sessionId);
9843 hdd_wlan_get_freq(channel, &freq);
9844
9845
9846 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
9847 {
9848 if (NULL == wiphy->bands[i])
9849 {
9850 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
9851 "%s: wiphy->bands[i] is NULL, i = %d", __func__, i);
9852 continue;
9853 }
9854
9855 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
9856 {
9857 struct ieee80211_supported_band *band = wiphy->bands[i];
9858
9859 if (band->channels[j].center_freq == (v_U16_t)freq)
9860 {
9861 survey->channel = &band->channels[j];
9862 /* The Rx BDs contain SNR values in dB for the received frames
9863 * while the supplicant expects noise. So we calculate and
9864 * return the value of noise (dBm)
9865 * SNR (dB) = RSSI (dBm) - NOISE (dBm)
9866 */
9867 survey->noise = rssi - snr;
9868 survey->filled = SURVEY_INFO_NOISE_DBM;
9869 filled = 1;
9870 }
9871 }
9872 }
9873
9874 if (filled)
9875 pAdapter->survey_idx = 1;
9876 else
9877 {
9878 pAdapter->survey_idx = 0;
9879 return -ENONET;
9880 }
9881
9882 return 0;
9883}
9884
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05309885/*
9886 * FUNCTION: wlan_hdd_cfg80211_resume_wlan
9887 * this is called when cfg80211 driver resume
9888 * driver updates latest sched_scan scan result(if any) to cfg80211 database
9889 */
9890int wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
9891{
9892 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
9893 hdd_adapter_t *pAdapter;
9894 hdd_adapter_list_node_t *pAdapterNode, *pNext;
9895 VOS_STATUS status = VOS_STATUS_SUCCESS;
9896
9897 ENTER();
9898
9899 if ( NULL == pHddCtx )
9900 {
9901 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
9902 "%s: HddCtx validation failed", __func__);
9903 return 0;
9904 }
9905
9906 if (pHddCtx->isLogpInProgress)
9907 {
9908 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9909 "%s: LOGP in Progress. Ignore!!!", __func__);
9910 return 0;
9911 }
9912
Mihir Shete18156292014-03-11 15:38:30 +05309913 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05309914 {
9915 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9916 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
9917 return 0;
9918 }
9919
9920 spin_lock(&pHddCtx->schedScan_lock);
9921 pHddCtx->isWiphySuspended = FALSE;
9922 if (TRUE != pHddCtx->isSchedScanUpdatePending)
9923 {
9924 spin_unlock(&pHddCtx->schedScan_lock);
9925 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9926 "%s: Return resume is not due to PNO indication", __func__);
9927 return 0;
9928 }
9929 // Reset flag to avoid updatating cfg80211 data old results again
9930 pHddCtx->isSchedScanUpdatePending = FALSE;
9931 spin_unlock(&pHddCtx->schedScan_lock);
9932
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +05309933
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05309934 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
9935
9936 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
9937 {
9938 pAdapter = pAdapterNode->pAdapter;
9939 if ( (NULL != pAdapter) &&
9940 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) )
9941 {
9942 if (0 != wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter))
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +05309943 {
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05309944 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
9945 "%s: NO SCAN result", __func__);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +05309946 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05309947 else
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +05309948 {
9949 /* Acquire wakelock to handle the case where APP's tries to
9950 * suspend immediately after updating the scan results. Whis
9951 * results in app's is in suspended state and not able to
9952 * process the connect request to AP
9953 */
9954 hdd_prevent_suspend_timeout(2000);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05309955 cfg80211_sched_scan_results(pHddCtx->wiphy);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +05309956 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05309957
9958 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9959 "%s : cfg80211 scan result database updated", __func__);
9960
9961 return 0;
9962
9963 }
9964 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
9965 pAdapterNode = pNext;
9966 }
9967
9968 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9969 "%s: Failed to find Adapter", __func__);
9970 return 0;
9971}
9972
9973/*
9974 * FUNCTION: wlan_hdd_cfg80211_suspend_wlan
9975 * this is called when cfg80211 driver suspends
9976 */
9977int wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
9978 struct cfg80211_wowlan *wow)
9979{
9980 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
9981
9982 ENTER();
9983 if (NULL == pHddCtx)
9984 {
9985 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
9986 "%s: HddCtx validation failed", __func__);
9987 return 0;
9988 }
9989
9990 pHddCtx->isWiphySuspended = TRUE;
9991
9992 EXIT();
9993
9994 return 0;
9995}
9996
Jeff Johnson295189b2012-06-20 16:38:30 -07009997/* cfg80211_ops */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309998static struct cfg80211_ops wlan_hdd_cfg80211_ops =
Jeff Johnson295189b2012-06-20 16:38:30 -07009999{
10000 .add_virtual_intf = wlan_hdd_add_virtual_intf,
10001 .del_virtual_intf = wlan_hdd_del_virtual_intf,
10002 .change_virtual_intf = wlan_hdd_cfg80211_change_iface,
10003 .change_station = wlan_hdd_change_station,
10004#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
10005 .add_beacon = wlan_hdd_cfg80211_add_beacon,
10006 .del_beacon = wlan_hdd_cfg80211_del_beacon,
10007 .set_beacon = wlan_hdd_cfg80211_set_beacon,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010008#else
10009 .start_ap = wlan_hdd_cfg80211_start_ap,
10010 .change_beacon = wlan_hdd_cfg80211_change_beacon,
10011 .stop_ap = wlan_hdd_cfg80211_stop_ap,
Jeff Johnson295189b2012-06-20 16:38:30 -070010012#endif
10013 .change_bss = wlan_hdd_cfg80211_change_bss,
10014 .add_key = wlan_hdd_cfg80211_add_key,
10015 .get_key = wlan_hdd_cfg80211_get_key,
10016 .del_key = wlan_hdd_cfg80211_del_key,
10017 .set_default_key = wlan_hdd_cfg80211_set_default_key,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080010018#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
Jeff Johnson295189b2012-06-20 16:38:30 -070010019 .set_channel = wlan_hdd_cfg80211_set_channel,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080010020#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010021 .scan = wlan_hdd_cfg80211_scan,
10022 .connect = wlan_hdd_cfg80211_connect,
10023 .disconnect = wlan_hdd_cfg80211_disconnect,
10024 .join_ibss = wlan_hdd_cfg80211_join_ibss,
10025 .leave_ibss = wlan_hdd_cfg80211_leave_ibss,
10026 .set_wiphy_params = wlan_hdd_cfg80211_set_wiphy_params,
10027 .set_tx_power = wlan_hdd_cfg80211_set_txpower,
10028 .get_tx_power = wlan_hdd_cfg80211_get_txpower,
Jeff Johnson295189b2012-06-20 16:38:30 -070010029 .remain_on_channel = wlan_hdd_cfg80211_remain_on_channel,
10030 .cancel_remain_on_channel = wlan_hdd_cfg80211_cancel_remain_on_channel,
DARAM SUDHA39eede62014-02-12 11:16:40 +053010031 .mgmt_tx = wlan_hdd_mgmt_tx,
Jeff Johnson295189b2012-06-20 16:38:30 -070010032#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
10033 .mgmt_tx_cancel_wait = wlan_hdd_cfg80211_mgmt_tx_cancel_wait,
10034 .set_default_mgmt_key = wlan_hdd_set_default_mgmt_key,
10035 .set_txq_params = wlan_hdd_set_txq_params,
10036#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010037 .get_station = wlan_hdd_cfg80211_get_station,
10038 .set_power_mgmt = wlan_hdd_cfg80211_set_power_mgmt,
10039 .del_station = wlan_hdd_cfg80211_del_station,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010040 .add_station = wlan_hdd_cfg80211_add_station,
10041#ifdef FEATURE_WLAN_LFR
10042 .set_pmksa = wlan_hdd_cfg80211_set_pmksa,
10043 .del_pmksa = wlan_hdd_cfg80211_del_pmksa,
10044 .flush_pmksa = wlan_hdd_cfg80211_flush_pmksa,
10045#endif
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070010046#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
10047 .update_ft_ies = wlan_hdd_cfg80211_update_ft_ies,
10048#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080010049#ifdef FEATURE_WLAN_TDLS
10050 .tdls_mgmt = wlan_hdd_cfg80211_tdls_mgmt,
10051 .tdls_oper = wlan_hdd_cfg80211_tdls_oper,
10052#endif
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053010053#ifdef WLAN_FEATURE_GTK_OFFLOAD
10054 .set_rekey_data = wlan_hdd_cfg80211_set_rekey_data,
10055#endif /* WLAN_FEATURE_GTK_OFFLOAD */
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053010056#ifdef FEATURE_WLAN_SCAN_PNO
10057 .sched_scan_start = wlan_hdd_cfg80211_sched_scan_start,
10058 .sched_scan_stop = wlan_hdd_cfg80211_sched_scan_stop,
10059#endif /*FEATURE_WLAN_SCAN_PNO */
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053010060 .resume = wlan_hdd_cfg80211_resume_wlan,
10061 .suspend = wlan_hdd_cfg80211_suspend_wlan,
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053010062 .set_mac_acl = wlan_hdd_cfg80211_set_mac_acl,
Leo Chang9056f462013-08-01 19:21:11 -070010063#ifdef WLAN_NL80211_TESTMODE
10064 .testmode_cmd = wlan_hdd_cfg80211_testmode,
10065#endif
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053010066 .dump_survey = wlan_hdd_cfg80211_dump_survey,
Jeff Johnson295189b2012-06-20 16:38:30 -070010067};
10068