blob: d77afe116e3700a174ad3ac19c5dc03e8da9140a [file] [log] [blame]
Jeff Johnson295189b2012-06-20 16:38:30 -07001/*
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302 * Copyright (c) 2012-2013, 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*/
Jeff Johnson295189b2012-06-20 16:38:30 -070021
22/**========================================================================
23
24 \file wlan_hdd_cfg80211.c
25
26 \brief WLAN Host Device Driver implementation
27
Gopichand Nakkala747461f2013-04-24 19:24:45 +053028 Copyright 2008 (c) Qualcomm Technologies, Inc. All Rights Reserved.
Jeff Johnson295189b2012-06-20 16:38:30 -070029
Gopichand Nakkala747461f2013-04-24 19:24:45 +053030 Qualcomm Technologies Confidential and Proprietary.
Jeff Johnson295189b2012-06-20 16:38:30 -070031
32 ========================================================================*/
33
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070034/**=========================================================================
Jeff Johnson295189b2012-06-20 16:38:30 -070035
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070036 EDIT HISTORY FOR FILE
Jeff Johnson295189b2012-06-20 16:38:30 -070037
38
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070039 This section contains comments describing changes made to the module.
40 Notice that changes are listed in reverse chronological order.
Jeff Johnson295189b2012-06-20 16:38:30 -070041
42
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070043 $Header:$ $DateTime: $ $Author: $
Jeff Johnson295189b2012-06-20 16:38:30 -070044
45
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070046 when who what, where, why
Jeff Johnson295189b2012-06-20 16:38:30 -070047 -------- --- --------------------------------------------------------
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070048 21/12/09 Ashwani Created module.
Jeff Johnson295189b2012-06-20 16:38:30 -070049
50 07/06/10 Kumar Deepak Implemented cfg80211 callbacks for ANDROID
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070051 Ganesh K
Jeff Johnson295189b2012-06-20 16:38:30 -070052 ==========================================================================*/
53
Jeff Johnson295189b2012-06-20 16:38:30 -070054
55#include <linux/version.h>
56#include <linux/module.h>
57#include <linux/kernel.h>
58#include <linux/init.h>
59#include <linux/wireless.h>
60#include <wlan_hdd_includes.h>
61#include <net/arp.h>
62#include <net/cfg80211.h>
63#include <linux/wireless.h>
64#include <wlan_hdd_wowl.h>
65#include <aniGlobal.h>
66#include "ccmApi.h"
67#include "sirParams.h"
68#include "dot11f.h"
69#include "wlan_hdd_assoc.h"
70#include "wlan_hdd_wext.h"
71#include "sme_Api.h"
72#include "wlan_hdd_p2p.h"
73#include "wlan_hdd_cfg80211.h"
74#include "wlan_hdd_hostapd.h"
75#include "sapInternal.h"
76#include "wlan_hdd_softap_tx_rx.h"
77#include "wlan_hdd_main.h"
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053078#include "wlan_hdd_assoc.h"
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053079#include "wlan_hdd_power.h"
Jeff Johnson295189b2012-06-20 16:38:30 -070080#ifdef WLAN_BTAMP_FEATURE
81#include "bap_hdd_misc.h"
82#endif
83#include <qc_sap_ioctl.h>
Mohit Khanna698ba2a2012-12-04 15:08:18 -080084#ifdef FEATURE_WLAN_TDLS
85#include "wlan_hdd_tdls.h"
86#endif
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +053087#include "wlan_nv.h"
Jeff Johnson295189b2012-06-20 16:38:30 -070088
89#define g_mode_rates_size (12)
90#define a_mode_rates_size (8)
91#define FREQ_BASE_80211G (2407)
92#define FREQ_BAND_DIFF_80211G (5)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070093#define MAX_SCAN_SSID 9
Jeff Johnson295189b2012-06-20 16:38:30 -070094#define GET_IE_LEN_IN_BSS_DESC(lenInBss) ( lenInBss + sizeof(lenInBss) - \
95 ((int) OFFSET_OF( tSirBssDescription, ieFields)))
96
97#define HDD2GHZCHAN(freq, chan, flag) { \
98 .band = IEEE80211_BAND_2GHZ, \
99 .center_freq = (freq), \
100 .hw_value = (chan),\
101 .flags = (flag), \
102 .max_antenna_gain = 0 ,\
103 .max_power = 30, \
104}
105
106#define HDD5GHZCHAN(freq, chan, flag) { \
107 .band = IEEE80211_BAND_5GHZ, \
108 .center_freq = (freq), \
109 .hw_value = (chan),\
110 .flags = (flag), \
111 .max_antenna_gain = 0 ,\
112 .max_power = 30, \
113}
114
115#define HDD_G_MODE_RATETAB(rate, rate_id, flag)\
116{\
117 .bitrate = rate, \
118 .hw_value = rate_id, \
119 .flags = flag, \
120}
121
Lee Hoonkic1262f22013-01-24 21:59:00 -0800122#ifndef WLAN_FEATURE_TDLS_DEBUG
123#define TDLS_LOG_LEVEL VOS_TRACE_LEVEL_INFO
124#else
125#define TDLS_LOG_LEVEL VOS_TRACE_LEVEL_ERROR
126#endif
127
Gopichand Nakkala356fb102013-03-06 12:34:04 +0530128#ifdef WLAN_FEATURE_VOWIFI_11R
129#define WLAN_AKM_SUITE_FT_8021X 0x000FAC03
130#define WLAN_AKM_SUITE_FT_PSK 0x000FAC04
131#endif
132
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530133static const u32 hdd_cipher_suites[] =
Jeff Johnson295189b2012-06-20 16:38:30 -0700134{
135 WLAN_CIPHER_SUITE_WEP40,
136 WLAN_CIPHER_SUITE_WEP104,
137 WLAN_CIPHER_SUITE_TKIP,
138#ifdef FEATURE_WLAN_CCX
139#define WLAN_CIPHER_SUITE_KRK 0x004096ff /* use for KRK */
140 WLAN_CIPHER_SUITE_KRK,
141 WLAN_CIPHER_SUITE_CCMP,
142#else
143 WLAN_CIPHER_SUITE_CCMP,
144#endif
145#ifdef FEATURE_WLAN_WAPI
146 WLAN_CIPHER_SUITE_SMS4,
147#endif
Chet Lanctot186b5732013-03-18 10:26:30 -0700148#ifdef WLAN_FEATURE_11W
149 WLAN_CIPHER_SUITE_AES_CMAC,
150#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700151};
152
153static inline int is_broadcast_ether_addr(const u8 *addr)
154{
155 return ((addr[0] == 0xff) && (addr[1] == 0xff) && (addr[2] == 0xff) &&
156 (addr[3] == 0xff) && (addr[4] == 0xff) && (addr[5] == 0xff));
157}
158
159static struct ieee80211_channel hdd_channels_2_4_GHZ[] =
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530160{
Jeff Johnson295189b2012-06-20 16:38:30 -0700161 HDD2GHZCHAN(2412, 1, 0) ,
162 HDD2GHZCHAN(2417, 2, 0) ,
163 HDD2GHZCHAN(2422, 3, 0) ,
164 HDD2GHZCHAN(2427, 4, 0) ,
165 HDD2GHZCHAN(2432, 5, 0) ,
166 HDD2GHZCHAN(2437, 6, 0) ,
167 HDD2GHZCHAN(2442, 7, 0) ,
168 HDD2GHZCHAN(2447, 8, 0) ,
169 HDD2GHZCHAN(2452, 9, 0) ,
170 HDD2GHZCHAN(2457, 10, 0) ,
171 HDD2GHZCHAN(2462, 11, 0) ,
172 HDD2GHZCHAN(2467, 12, 0) ,
173 HDD2GHZCHAN(2472, 13, 0) ,
174 HDD2GHZCHAN(2484, 14, 0) ,
175};
176
Jeff Johnson295189b2012-06-20 16:38:30 -0700177static struct ieee80211_channel hdd_social_channels_2_4_GHZ[] =
178{
179 HDD2GHZCHAN(2412, 1, 0) ,
180 HDD2GHZCHAN(2437, 6, 0) ,
181 HDD2GHZCHAN(2462, 11, 0) ,
182};
Jeff Johnson295189b2012-06-20 16:38:30 -0700183
184static struct ieee80211_channel hdd_channels_5_GHZ[] =
185{
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -0700186 HDD5GHZCHAN(4920, 240, 0) ,
187 HDD5GHZCHAN(4940, 244, 0) ,
188 HDD5GHZCHAN(4960, 248, 0) ,
189 HDD5GHZCHAN(4980, 252, 0) ,
190 HDD5GHZCHAN(5040, 208, 0) ,
191 HDD5GHZCHAN(5060, 212, 0) ,
192 HDD5GHZCHAN(5080, 216, 0) ,
Jeff Johnson295189b2012-06-20 16:38:30 -0700193 HDD5GHZCHAN(5180, 36, 0) ,
194 HDD5GHZCHAN(5200, 40, 0) ,
195 HDD5GHZCHAN(5220, 44, 0) ,
196 HDD5GHZCHAN(5240, 48, 0) ,
197 HDD5GHZCHAN(5260, 52, 0) ,
198 HDD5GHZCHAN(5280, 56, 0) ,
199 HDD5GHZCHAN(5300, 60, 0) ,
200 HDD5GHZCHAN(5320, 64, 0) ,
201 HDD5GHZCHAN(5500,100, 0) ,
202 HDD5GHZCHAN(5520,104, 0) ,
203 HDD5GHZCHAN(5540,108, 0) ,
204 HDD5GHZCHAN(5560,112, 0) ,
205 HDD5GHZCHAN(5580,116, 0) ,
206 HDD5GHZCHAN(5600,120, 0) ,
207 HDD5GHZCHAN(5620,124, 0) ,
208 HDD5GHZCHAN(5640,128, 0) ,
209 HDD5GHZCHAN(5660,132, 0) ,
210 HDD5GHZCHAN(5680,136, 0) ,
211 HDD5GHZCHAN(5700,140, 0) ,
212 HDD5GHZCHAN(5745,149, 0) ,
213 HDD5GHZCHAN(5765,153, 0) ,
214 HDD5GHZCHAN(5785,157, 0) ,
215 HDD5GHZCHAN(5805,161, 0) ,
216 HDD5GHZCHAN(5825,165, 0) ,
217};
218
219static struct ieee80211_rate g_mode_rates[] =
220{
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530221 HDD_G_MODE_RATETAB(10, 0x1, 0),
222 HDD_G_MODE_RATETAB(20, 0x2, 0),
223 HDD_G_MODE_RATETAB(55, 0x4, 0),
224 HDD_G_MODE_RATETAB(110, 0x8, 0),
225 HDD_G_MODE_RATETAB(60, 0x10, 0),
226 HDD_G_MODE_RATETAB(90, 0x20, 0),
227 HDD_G_MODE_RATETAB(120, 0x40, 0),
228 HDD_G_MODE_RATETAB(180, 0x80, 0),
229 HDD_G_MODE_RATETAB(240, 0x100, 0),
230 HDD_G_MODE_RATETAB(360, 0x200, 0),
231 HDD_G_MODE_RATETAB(480, 0x400, 0),
Jeff Johnson295189b2012-06-20 16:38:30 -0700232 HDD_G_MODE_RATETAB(540, 0x800, 0),
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530233};
Jeff Johnson295189b2012-06-20 16:38:30 -0700234
235static struct ieee80211_rate a_mode_rates[] =
236{
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530237 HDD_G_MODE_RATETAB(60, 0x10, 0),
238 HDD_G_MODE_RATETAB(90, 0x20, 0),
239 HDD_G_MODE_RATETAB(120, 0x40, 0),
240 HDD_G_MODE_RATETAB(180, 0x80, 0),
241 HDD_G_MODE_RATETAB(240, 0x100, 0),
242 HDD_G_MODE_RATETAB(360, 0x200, 0),
243 HDD_G_MODE_RATETAB(480, 0x400, 0),
Jeff Johnson295189b2012-06-20 16:38:30 -0700244 HDD_G_MODE_RATETAB(540, 0x800, 0),
245};
246
247static struct ieee80211_supported_band wlan_hdd_band_2_4_GHZ =
248{
249 .channels = hdd_channels_2_4_GHZ,
250 .n_channels = ARRAY_SIZE(hdd_channels_2_4_GHZ),
251 .band = IEEE80211_BAND_2GHZ,
252 .bitrates = g_mode_rates,
253 .n_bitrates = g_mode_rates_size,
254 .ht_cap.ht_supported = 1,
255 .ht_cap.cap = IEEE80211_HT_CAP_SGI_20
256 | IEEE80211_HT_CAP_GRN_FLD
257 | IEEE80211_HT_CAP_DSSSCCK40
258 | IEEE80211_HT_CAP_LSIG_TXOP_PROT,
259 .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
260 .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
261 .ht_cap.mcs.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
262 .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ),
263 .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
264};
265
Jeff Johnson295189b2012-06-20 16:38:30 -0700266static struct ieee80211_supported_band wlan_hdd_band_p2p_2_4_GHZ =
267{
268 .channels = hdd_social_channels_2_4_GHZ,
269 .n_channels = ARRAY_SIZE(hdd_social_channels_2_4_GHZ),
270 .band = IEEE80211_BAND_2GHZ,
271 .bitrates = g_mode_rates,
272 .n_bitrates = g_mode_rates_size,
273 .ht_cap.ht_supported = 1,
274 .ht_cap.cap = IEEE80211_HT_CAP_SGI_20
275 | IEEE80211_HT_CAP_GRN_FLD
276 | IEEE80211_HT_CAP_DSSSCCK40
277 | IEEE80211_HT_CAP_LSIG_TXOP_PROT,
278 .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
279 .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
280 .ht_cap.mcs.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
281 .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ),
282 .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
283};
Jeff Johnson295189b2012-06-20 16:38:30 -0700284
285static struct ieee80211_supported_band wlan_hdd_band_5_GHZ =
286{
287 .channels = hdd_channels_5_GHZ,
288 .n_channels = ARRAY_SIZE(hdd_channels_5_GHZ),
289 .band = IEEE80211_BAND_5GHZ,
290 .bitrates = a_mode_rates,
291 .n_bitrates = a_mode_rates_size,
292 .ht_cap.ht_supported = 1,
293 .ht_cap.cap = IEEE80211_HT_CAP_SGI_20
294 | IEEE80211_HT_CAP_GRN_FLD
295 | IEEE80211_HT_CAP_DSSSCCK40
296 | IEEE80211_HT_CAP_LSIG_TXOP_PROT
297 | IEEE80211_HT_CAP_SGI_40
298 | IEEE80211_HT_CAP_SUP_WIDTH_20_40,
299 .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
300 .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
301 .ht_cap.mcs.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
302 .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ),
303 .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
304};
305
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530306/* This structure contain information what kind of frame are expected in
Jeff Johnson295189b2012-06-20 16:38:30 -0700307 TX/RX direction for each kind of interface */
308static const struct ieee80211_txrx_stypes
309wlan_hdd_txrx_stypes[NUM_NL80211_IFTYPES] = {
310 [NL80211_IFTYPE_STATION] = {
311 .tx = 0xffff,
312 .rx = BIT(SIR_MAC_MGMT_ACTION) |
313 BIT(SIR_MAC_MGMT_PROBE_REQ),
314 },
315 [NL80211_IFTYPE_AP] = {
316 .tx = 0xffff,
317 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
318 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
319 BIT(SIR_MAC_MGMT_PROBE_REQ) |
320 BIT(SIR_MAC_MGMT_DISASSOC) |
321 BIT(SIR_MAC_MGMT_AUTH) |
322 BIT(SIR_MAC_MGMT_DEAUTH) |
323 BIT(SIR_MAC_MGMT_ACTION),
324 },
Jeff Johnsonbc006202013-04-29 14:05:30 -0700325 [NL80211_IFTYPE_ADHOC] = {
326 .tx = 0xffff,
327 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
328 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
329 BIT(SIR_MAC_MGMT_PROBE_REQ) |
330 BIT(SIR_MAC_MGMT_DISASSOC) |
331 BIT(SIR_MAC_MGMT_AUTH) |
332 BIT(SIR_MAC_MGMT_DEAUTH) |
333 BIT(SIR_MAC_MGMT_ACTION),
334 },
Jeff Johnson295189b2012-06-20 16:38:30 -0700335 [NL80211_IFTYPE_P2P_CLIENT] = {
336 .tx = 0xffff,
337 .rx = BIT(SIR_MAC_MGMT_ACTION) |
338 BIT(SIR_MAC_MGMT_PROBE_REQ),
339 },
340 [NL80211_IFTYPE_P2P_GO] = {
341 /* This is also same as for SoftAP */
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};
352
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800353#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800354static const struct ieee80211_iface_limit
355wlan_hdd_iface_limit[] = {
356 {
Sunil Ravia72c3992013-01-31 06:12:22 -0800357 /* max = 3 ; Our driver create two interfaces during driver init
358 * wlan0 and p2p0 interfaces. p2p0 is considered as station
359 * interface until a group is formed. In JB architecture, once the
360 * group is formed, interface type of p2p0 is changed to P2P GO or
361 * Client.
362 * When supplicant remove the group, it first issue a set interface
363 * cmd to change the mode back to Station. In JB this works fine as
364 * we advertize two station type interface during driver init.
365 * Some vendors create separate interface for P2P GO/Client,
366 * after group formation(Third one). But while group remove
367 * supplicant first tries to change the mode(3rd interface) to STATION
368 * But as we advertized only two sta type interfaces nl80211 was
369 * returning error for the third one which was leading to failure in
370 * delete interface. Ideally while removing the group, supplicant
371 * should not try to change the 3rd interface mode to Station type.
372 * Till we get a fix in wpa_supplicant, we advertize max STA
373 * interface type to 3
374 */
375 .max = 3,
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800376 .types = BIT(NL80211_IFTYPE_STATION),
377 },
378 {
379 .max = 1,
Jeff Johnsonbc006202013-04-29 14:05:30 -0700380 .types = BIT(NL80211_IFTYPE_ADHOC) | BIT(NL80211_IFTYPE_AP),
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800381 },
382 {
383 .max = 1,
384 .types = BIT(NL80211_IFTYPE_P2P_GO) |
385 BIT(NL80211_IFTYPE_P2P_CLIENT),
386 },
387};
388
389/* By default, only single channel concurrency is allowed */
390static struct ieee80211_iface_combination
391wlan_hdd_iface_combination = {
392 .limits = wlan_hdd_iface_limit,
393 .num_different_channels = 1,
Sunil Ravia72c3992013-01-31 06:12:22 -0800394 /*
395 * max = WLAN_MAX_INTERFACES ; JellyBean architecture creates wlan0
396 * and p2p0 interfaces during driver init
397 * Some vendors create separate interface for P2P operations.
398 * wlan0: STA interface
399 * p2p0: P2P Device interface, action frames goes
400 * through this interface.
401 * p2p-xx: P2P interface, After GO negotiation this interface is
402 * created for p2p operations(GO/CLIENT interface).
403 */
404 .max_interfaces = WLAN_MAX_INTERFACES,
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800405 .n_limits = ARRAY_SIZE(wlan_hdd_iface_limit),
406 .beacon_int_infra_match = false,
407};
408#endif
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800409
Jeff Johnson295189b2012-06-20 16:38:30 -0700410static struct cfg80211_ops wlan_hdd_cfg80211_ops;
411
412/* Data rate 100KBPS based on IE Index */
413struct index_data_rate_type
414{
415 v_U8_t beacon_rate_index;
416 v_U16_t supported_rate[4];
417};
418
419/* 11B, 11G Rate table include Basic rate and Extended rate
420 The IDX field is the rate index
421 The HI field is the rate when RSSI is strong or being ignored
422 (in this case we report actual rate)
423 The MID field is the rate when RSSI is moderate
424 (in this case we cap 11b rates at 5.5 and 11g rates at 24)
425 The LO field is the rate when RSSI is low
426 (in this case we don't report rates, actual current rate used)
427 */
428static const struct
429{
430 v_U8_t beacon_rate_index;
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -0700431 v_U16_t supported_rate[4];
Jeff Johnson295189b2012-06-20 16:38:30 -0700432} supported_data_rate[] =
433{
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -0700434/* IDX HI HM LM LO (RSSI-based index */
435 {2, { 10, 10, 10, 0}},
436 {4, { 20, 20, 10, 0}},
437 {11, { 55, 20, 10, 0}},
438 {12, { 60, 55, 20, 0}},
439 {18, { 90, 55, 20, 0}},
440 {22, {110, 55, 20, 0}},
441 {24, {120, 90, 60, 0}},
442 {36, {180, 120, 60, 0}},
443 {44, {220, 180, 60, 0}},
444 {48, {240, 180, 90, 0}},
445 {66, {330, 180, 90, 0}},
446 {72, {360, 240, 90, 0}},
447 {96, {480, 240, 120, 0}},
448 {108, {540, 240, 120, 0}}
Jeff Johnson295189b2012-06-20 16:38:30 -0700449};
450
451/* MCS Based rate table */
452static struct index_data_rate_type supported_mcs_rate[] =
453{
454/* MCS L20 L40 S20 S40 */
455 {0, {65, 135, 72, 150}},
456 {1, {130, 270, 144, 300}},
457 {2, {195, 405, 217, 450}},
458 {3, {260, 540, 289, 600}},
459 {4, {390, 810, 433, 900}},
460 {5, {520, 1080, 578, 1200}},
461 {6, {585, 1215, 650, 1350}},
462 {7, {650, 1350, 722, 1500}}
463};
464
Leo Chang6f8870f2013-03-26 18:11:36 -0700465#ifdef WLAN_FEATURE_11AC
466
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530467#define DATA_RATE_11AC_MCS_MASK 0x03
Leo Chang6f8870f2013-03-26 18:11:36 -0700468
469struct index_vht_data_rate_type
470{
471 v_U8_t beacon_rate_index;
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530472 v_U16_t supported_VHT80_rate[2];
473 v_U16_t supported_VHT40_rate[2];
474 v_U16_t supported_VHT20_rate[2];
Leo Chang6f8870f2013-03-26 18:11:36 -0700475};
476
477typedef enum
478{
479 DATA_RATE_11AC_MAX_MCS_7,
480 DATA_RATE_11AC_MAX_MCS_8,
481 DATA_RATE_11AC_MAX_MCS_9,
482 DATA_RATE_11AC_MAX_MCS_NA
483} eDataRate11ACMaxMcs;
484
485/* MCS Based VHT rate table */
486static struct index_vht_data_rate_type supported_vht_mcs_rate[] =
487{
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530488/* MCS L80 S80 L40 S40 L20 S40*/
489 {0, {293, 325}, {135, 150}, {65, 72}},
490 {1, {585, 650}, {270, 300}, {130, 144}},
491 {2, {878, 975}, {405, 450}, {195, 217}},
492 {3, {1170, 1300}, {540, 600}, {260, 289}},
493 {4, {1755, 1950}, {810, 900}, {390, 433}},
494 {5, {2340, 2600}, {1080, 1200}, {520, 578}},
495 {6, {2633, 2925}, {1215, 1350}, {585, 650}},
496 {7, {2925, 3250}, {1350, 1500}, {650, 722}},
497 {8, {3510, 3900}, {1620, 1800}, {780, 867}},
498 {9, {3900, 4333}, {1800, 2000}, {780, 867}}
Leo Chang6f8870f2013-03-26 18:11:36 -0700499};
500#endif /* WLAN_FEATURE_11AC */
501
Jeff Johnson295189b2012-06-20 16:38:30 -0700502extern struct net_device_ops net_ops_struct;
503
504/*
505 * FUNCTION: wlan_hdd_cfg80211_init
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530506 * This function is called by hdd_wlan_startup()
507 * during initialization.
Jeff Johnson295189b2012-06-20 16:38:30 -0700508 * This function is used to initialize and register wiphy structure.
509 */
510struct wiphy *wlan_hdd_cfg80211_init(int priv_size)
511{
512 struct wiphy *wiphy;
513 ENTER();
514
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530515 /*
516 * Create wiphy device
Jeff Johnson295189b2012-06-20 16:38:30 -0700517 */
518 wiphy = wiphy_new(&wlan_hdd_cfg80211_ops, priv_size);
519
520 if (!wiphy)
521 {
522 /* Print error and jump into err label and free the memory */
523 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wiphy init failed", __func__);
524 return NULL;
525 }
526
527 return wiphy;
528}
529
530/*
531 * FUNCTION: wlan_hdd_cfg80211_update_band
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530532 * This function is called from the supplicant through a
Jeff Johnson295189b2012-06-20 16:38:30 -0700533 * private ioctl to change the band value
534 */
535int wlan_hdd_cfg80211_update_band(struct wiphy *wiphy, eCsrBand eBand)
536{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +0530537 int i, j;
538 eNVChannelEnabledType channelEnabledState;
539
Jeff Johnsone7245742012-09-05 17:12:55 -0700540 ENTER();
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +0530541 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
Jeff Johnson295189b2012-06-20 16:38:30 -0700542 {
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +0530543
544 if (NULL == wiphy->bands[i])
545 {
546 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[i] is NULL, i = %d",
547 __func__, i);
548 continue;
549 }
550
551 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
552 {
553 struct ieee80211_supported_band *band = wiphy->bands[i];
554
555 channelEnabledState = vos_nv_getChannelEnabledState(
556 band->channels[j].hw_value);
557
558 if (IEEE80211_BAND_2GHZ == i && eCSR_BAND_5G == eBand) // 5G only
559 {
560 // Enable Social channels for P2P
561 if (WLAN_HDD_IS_SOCIAL_CHANNEL(band->channels[j].center_freq) &&
562 NV_CHANNEL_ENABLE == channelEnabledState)
563 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
564 else
565 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
566 continue;
567 }
568 else if (IEEE80211_BAND_5GHZ == i && eCSR_BAND_24 == eBand) // 2G only
569 {
570 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
571 continue;
572 }
573
574 if (NV_CHANNEL_DISABLE == channelEnabledState ||
575 NV_CHANNEL_INVALID == channelEnabledState)
576 {
577 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
578 }
579 else if (NV_CHANNEL_DFS == channelEnabledState)
580 {
581 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
582 band->channels[j].flags |= IEEE80211_CHAN_RADAR;
583 }
584 else
585 {
586 band->channels[j].flags &= ~(IEEE80211_CHAN_DISABLED
587 |IEEE80211_CHAN_RADAR);
588 }
589 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700590 }
591 return 0;
592}
593/*
594 * FUNCTION: wlan_hdd_cfg80211_init
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530595 * This function is called by hdd_wlan_startup()
596 * during initialization.
Jeff Johnson295189b2012-06-20 16:38:30 -0700597 * This function is used to initialize and register wiphy structure.
598 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530599int wlan_hdd_cfg80211_register(struct device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -0700600 struct wiphy *wiphy,
601 hdd_config_t *pCfg
602 )
603{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +0530604
605 int i, j;
606
Jeff Johnsone7245742012-09-05 17:12:55 -0700607 ENTER();
608
Jeff Johnson295189b2012-06-20 16:38:30 -0700609 /* Now bind the underlying wlan device with wiphy */
610 set_wiphy_dev(wiphy, dev);
611
612 wiphy->mgmt_stypes = wlan_hdd_txrx_stypes;
613
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -0700614 wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY;
Jeff Johnson295189b2012-06-20 16:38:30 -0700615
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700616#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -0700617 wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME
618 | WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD
619 | WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL
Jeff Johnsone7245742012-09-05 17:12:55 -0700620 | WIPHY_FLAG_OFFCHAN_TX;
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700621#endif
Srinivas Girigowda640728a2013-03-28 12:21:54 -0700622#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_CCX) || defined(FEATURE_WLAN_LFR)
623 if (pCfg->isFastTransitionEnabled
James Zmuda77fb5ae2013-01-29 08:00:17 -0800624#ifdef FEATURE_WLAN_LFR
Srinivas Girigowda640728a2013-03-28 12:21:54 -0700625 || pCfg->isFastRoamIniFeatureEnabled
626#endif
627#ifdef FEATURE_WLAN_CCX
628 || pCfg->isCcxIniFeatureEnabled
629#endif
630 )
631 {
632 wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM;
633 }
James Zmuda77fb5ae2013-01-29 08:00:17 -0800634#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -0800635#ifdef FEATURE_WLAN_TDLS
636 wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS
637 | WIPHY_FLAG_TDLS_EXTERNAL_SETUP;
638#endif
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +0530639#ifdef FEATURE_WLAN_SCAN_PNO
640 wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN;
641 wiphy->max_sched_scan_ssids = MAX_SCAN_SSID;
642 wiphy->max_match_sets = SIR_PNO_MAX_SUPP_NETWORKS;
643#endif/*FEATURE_WLAN_SCAN_PNO*/
Mohit Khanna698ba2a2012-12-04 15:08:18 -0800644
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -0700645 /* even with WIPHY_FLAG_CUSTOM_REGULATORY,
646 driver can still register regulatory callback and
647 it will get CRDA setting in wiphy->band[], but
648 driver need to determine what to do with both
649 regulatory settings */
650 wiphy->reg_notifier = wlan_hdd_crda_reg_notifier;
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700651
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530652 wiphy->max_scan_ssids = MAX_SCAN_SSID;
653
Jeff Johnson295189b2012-06-20 16:38:30 -0700654 wiphy->max_scan_ie_len = 200 ; //TODO: define a macro
655
656 /* Supports STATION & AD-HOC modes right now */
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530657 wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -0700658 | BIT(NL80211_IFTYPE_ADHOC)
Jeff Johnson295189b2012-06-20 16:38:30 -0700659 | BIT(NL80211_IFTYPE_P2P_CLIENT)
660 | BIT(NL80211_IFTYPE_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -0700661 | BIT(NL80211_IFTYPE_AP);
662
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800663#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800664 if( pCfg->enableMCC )
665 {
666 /* Currently, supports up to two channels */
667 wlan_hdd_iface_combination.num_different_channels = 2;
668
669 if( !pCfg->allowMCCGODiffBI )
670 wlan_hdd_iface_combination.beacon_int_infra_match = true;
671
672 }
673 wiphy->iface_combinations = &wlan_hdd_iface_combination;
674 wiphy->n_iface_combinations = 1;
675#endif
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800676
Jeff Johnson295189b2012-06-20 16:38:30 -0700677 /* Before registering we need to update the ht capabilitied based
678 * on ini values*/
679 if( !pCfg->ShortGI20MhzEnable )
680 {
681 wlan_hdd_band_2_4_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
682 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
683 wlan_hdd_band_p2p_2_4_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
684 }
685
686 if( !pCfg->ShortGI40MhzEnable )
687 {
688 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_40;
689 }
690
691 if( !pCfg->nChannelBondingMode5GHz )
692 {
693 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
694 }
695
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +0530696 wiphy->bands[IEEE80211_BAND_2GHZ] = &wlan_hdd_band_2_4_GHZ;
697 wiphy->bands[IEEE80211_BAND_5GHZ] = &wlan_hdd_band_5_GHZ;
698
699 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
700 {
701
702 if (NULL == wiphy->bands[i])
703 {
704 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[i] is NULL, i = %d",
705 __func__, i);
706 continue;
707 }
708
709 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
710 {
711 struct ieee80211_supported_band *band = wiphy->bands[i];
712
713 if (IEEE80211_BAND_2GHZ == i && eCSR_BAND_5G == pCfg->nBandCapability) // 5G only
714 {
715 // Enable social channels for P2P
716 if (WLAN_HDD_IS_SOCIAL_CHANNEL(band->channels[j].center_freq))
717 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
718 else
719 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
720 continue;
721 }
722 else if (IEEE80211_BAND_5GHZ == i && eCSR_BAND_24 == pCfg->nBandCapability) // 2G only
723 {
724 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
725 continue;
726 }
727 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700728 }
729 /*Initialise the supported cipher suite details*/
730 wiphy->cipher_suites = hdd_cipher_suites;
731 wiphy->n_cipher_suites = ARRAY_SIZE(hdd_cipher_suites);
732
733 /*signal strength in mBm (100*dBm) */
734 wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
735
736#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Jeff Johnson295189b2012-06-20 16:38:30 -0700737 wiphy->max_remain_on_channel_duration = 1000;
738#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700739
740 /* Register our wiphy dev with cfg80211 */
741 if (0 > wiphy_register(wiphy))
742 {
743 /* print eror */
744 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
745 return -EIO;
746 }
747
748 EXIT();
749 return 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530750}
Jeff Johnson295189b2012-06-20 16:38:30 -0700751
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -0700752/* In this function we will try to get default country code from crda.
753 If the gCrdaDefaultCountryCode is configured in ini file,
754 we will try to call user space crda to get the regulatory settings for
755 that country. We will timeout if we can't get it from crda.
756 It's called by hdd_wlan_startup() after wlan_hdd_cfg80211_register.
757*/
758int wlan_hdd_get_crda_regd_entry(struct wiphy *wiphy, hdd_config_t *pCfg)
759{
760 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
761 if (memcmp(pCfg->crdaDefaultCountryCode,
762 CFG_CRDA_DEFAULT_COUNTRY_CODE_DEFAULT , 2) != 0)
763 {
764 init_completion(&pHddCtx->driver_crda_req);
765 regulatory_hint(wiphy, pCfg->crdaDefaultCountryCode);
766 wait_for_completion_interruptible_timeout(&pHddCtx->driver_crda_req,
767 CRDA_WAIT_TIME);
Yunsen Wange3ba1fb2013-04-05 15:04:43 -0700768 /* if the country is not found from current regulatory.bin,
769 fall back to world domain */
770 if (is_crda_regulatory_entry_valid() == VOS_FALSE)
771 crda_regulatory_entry_default(pCfg->crdaDefaultCountryCode, NUM_REG_DOMAINS-1);
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -0700772 }
773 return 0;
774}
775
Jeff Johnson295189b2012-06-20 16:38:30 -0700776/* In this function we will do all post VOS start initialization.
777 In this function we will register for all frame in which supplicant
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530778 is interested.
Jeff Johnson295189b2012-06-20 16:38:30 -0700779*/
780void wlan_hdd_cfg80211_post_voss_start(hdd_adapter_t* pAdapter)
781{
Jeff Johnson295189b2012-06-20 16:38:30 -0700782 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
783 /* Register for all P2P action, public action etc frames */
784 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
785
Jeff Johnsone7245742012-09-05 17:12:55 -0700786 ENTER();
787
Jeff Johnson295189b2012-06-20 16:38:30 -0700788 /* Right now we are registering these frame when driver is getting
789 initialized. Once we will move to 2.6.37 kernel, in which we have
790 frame register ops, we will move this code as a part of that */
791 /* GAS Initial Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530792 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Jeff Johnson295189b2012-06-20 16:38:30 -0700793 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
794
795 /* GAS Initial Response */
796 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
797 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530798
Jeff Johnson295189b2012-06-20 16:38:30 -0700799 /* GAS Comeback Request */
800 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
801 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
802
803 /* GAS Comeback Response */
804 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
805 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
806
807 /* P2P Public Action */
808 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530809 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -0700810 P2P_PUBLIC_ACTION_FRAME_SIZE );
811
812 /* P2P Action */
813 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
814 (v_U8_t*)P2P_ACTION_FRAME,
815 P2P_ACTION_FRAME_SIZE );
Chet Lanctot186b5732013-03-18 10:26:30 -0700816
Gopichand Nakkalae3d56e72013-04-21 23:33:32 +0530817 /* WNM BSS Transition Request frame */
818 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
819 (v_U8_t*)WNM_BSS_ACTION_FRAME,
820 WNM_BSS_ACTION_FRAME_SIZE );
821
Chet Lanctot186b5732013-03-18 10:26:30 -0700822#ifdef WLAN_FEATURE_11W
823 /* SA Query Response Action Frame */
824 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
825 (v_U8_t*)SA_QUERY_FRAME_RSP,
826 SA_QUERY_FRAME_RSP_SIZE );
827#endif /* WLAN_FEATURE_11W */
Jeff Johnson295189b2012-06-20 16:38:30 -0700828}
829
830void wlan_hdd_cfg80211_pre_voss_stop(hdd_adapter_t* pAdapter)
831{
Jeff Johnson295189b2012-06-20 16:38:30 -0700832 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
833 /* Register for all P2P action, public action etc frames */
834 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
835
Jeff Johnsone7245742012-09-05 17:12:55 -0700836 ENTER();
837
Jeff Johnson295189b2012-06-20 16:38:30 -0700838 /* Right now we are registering these frame when driver is getting
839 initialized. Once we will move to 2.6.37 kernel, in which we have
840 frame register ops, we will move this code as a part of that */
841 /* GAS Initial Request */
842
843 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
844 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
845
846 /* GAS Initial Response */
847 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
848 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530849
Jeff Johnson295189b2012-06-20 16:38:30 -0700850 /* GAS Comeback Request */
851 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
852 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
853
854 /* GAS Comeback Response */
855 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
856 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
857
858 /* P2P Public Action */
859 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530860 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -0700861 P2P_PUBLIC_ACTION_FRAME_SIZE );
862
863 /* P2P Action */
864 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
865 (v_U8_t*)P2P_ACTION_FRAME,
866 P2P_ACTION_FRAME_SIZE );
Chet Lanctot186b5732013-03-18 10:26:30 -0700867
868#ifdef WLAN_FEATURE_11W
869 /* SA Query Response Action Frame */
870 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
871 (v_U8_t*)SA_QUERY_FRAME_RSP,
872 SA_QUERY_FRAME_RSP_SIZE );
873#endif /* WLAN_FEATURE_11W */
Jeff Johnson295189b2012-06-20 16:38:30 -0700874}
875
876#ifdef FEATURE_WLAN_WAPI
877void wlan_hdd_cfg80211_set_key_wapi(hdd_adapter_t* pAdapter, u8 key_index,
878 const u8 *mac_addr, u8 *key , int key_Len)
879{
880 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
881 tCsrRoamSetKey setKey;
882 v_BOOL_t isConnected = TRUE;
883 int status = 0;
884 v_U32_t roamId= 0xFF;
885 tANI_U8 *pKeyPtr = NULL;
886 int n = 0;
887
888 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",
889 __func__,pAdapter->device_mode);
890
Gopichand Nakkalae7480202013-02-11 15:24:22 +0530891 vos_mem_zero(&setKey, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -0700892 setKey.keyId = key_index; // Store Key ID
893 setKey.encType = eCSR_ENCRYPT_TYPE_WPI; // SET WAPI Encryption
894 setKey.keyDirection = eSIR_TX_RX; // Key Directionn both TX and RX
895 setKey.paeRole = 0 ; // the PAE role
896 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
897 {
898 vos_set_macaddr_broadcast( (v_MACADDR_t *)setKey.peerMac );
899 }
900 else
901 {
902 isConnected = hdd_connIsConnected(pHddStaCtx);
903 vos_mem_copy(setKey.peerMac,&pHddStaCtx->conn_info.bssId,WNI_CFG_BSSID_LEN);
904 }
905 setKey.keyLength = key_Len;
906 pKeyPtr = setKey.Key;
907 memcpy( pKeyPtr, key, key_Len);
908
909 hddLog(VOS_TRACE_LEVEL_INFO,"\n%s: WAPI KEY LENGTH:0x%04x",
910 __func__, key_Len);
911 for (n = 0 ; n < key_Len; n++)
912 hddLog(VOS_TRACE_LEVEL_INFO, "%s WAPI KEY Data[%d]:%02x ",
913 __func__,n,setKey.Key[n]);
914
915 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
916 if ( isConnected )
917 {
918 status= sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
919 pAdapter->sessionId, &setKey, &roamId );
920 }
921 if ( status != 0 )
922 {
923 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
924 "[%4d] sme_RoamSetKey returned ERROR status= %d",
925 __LINE__, status );
926 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
927 }
928}
929#endif /* FEATURE_WLAN_WAPI*/
930
931#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530932int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -0700933 beacon_data_t **ppBeacon,
934 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700935#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530936int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700937 beacon_data_t **ppBeacon,
938 struct cfg80211_beacon_data *params,
939 int dtim_period)
940#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530941{
Jeff Johnson295189b2012-06-20 16:38:30 -0700942 int size;
943 beacon_data_t *beacon = NULL;
944 beacon_data_t *old = NULL;
945 int head_len,tail_len;
946
Jeff Johnsone7245742012-09-05 17:12:55 -0700947 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -0700948 if (params->head && !params->head_len)
949 return -EINVAL;
950
951 old = pAdapter->sessionCtx.ap.beacon;
952
953 if (!params->head && !old)
954 return -EINVAL;
955
956 if (params->tail && !params->tail_len)
957 return -EINVAL;
958
959#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,38))
960 /* Kernel 3.0 is not updating dtim_period for set beacon */
961 if (!params->dtim_period)
962 return -EINVAL;
963#endif
964
965 if(params->head)
966 head_len = params->head_len;
967 else
968 head_len = old->head_len;
969
970 if(params->tail || !old)
971 tail_len = params->tail_len;
972 else
973 tail_len = old->tail_len;
974
975 size = sizeof(beacon_data_t) + head_len + tail_len;
976
977 beacon = kzalloc(size, GFP_KERNEL);
978
979 if( beacon == NULL )
980 return -ENOMEM;
981
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700982#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -0700983 if(params->dtim_period || !old )
984 beacon->dtim_period = params->dtim_period;
985 else
986 beacon->dtim_period = old->dtim_period;
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700987#else
988 if(dtim_period || !old )
989 beacon->dtim_period = dtim_period;
990 else
991 beacon->dtim_period = old->dtim_period;
992#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530993
Jeff Johnson295189b2012-06-20 16:38:30 -0700994 beacon->head = ((u8 *) beacon) + sizeof(beacon_data_t);
995 beacon->tail = beacon->head + head_len;
996 beacon->head_len = head_len;
997 beacon->tail_len = tail_len;
998
999 if(params->head) {
1000 memcpy (beacon->head,params->head,beacon->head_len);
1001 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301002 else {
Jeff Johnson295189b2012-06-20 16:38:30 -07001003 if(old)
1004 memcpy (beacon->head,old->head,beacon->head_len);
1005 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301006
Jeff Johnson295189b2012-06-20 16:38:30 -07001007 if(params->tail) {
1008 memcpy (beacon->tail,params->tail,beacon->tail_len);
1009 }
1010 else {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301011 if(old)
Jeff Johnson295189b2012-06-20 16:38:30 -07001012 memcpy (beacon->tail,old->tail,beacon->tail_len);
1013 }
1014
1015 *ppBeacon = beacon;
1016
1017 kfree(old);
1018
1019 return 0;
1020
1021}
Jeff Johnson295189b2012-06-20 16:38:30 -07001022
1023v_U8_t* wlan_hdd_cfg80211_get_ie_ptr(v_U8_t *pIes, int length, v_U8_t eid)
1024{
1025 int left = length;
1026 v_U8_t *ptr = pIes;
1027 v_U8_t elem_id,elem_len;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301028
Jeff Johnson295189b2012-06-20 16:38:30 -07001029 while(left >= 2)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301030 {
Jeff Johnson295189b2012-06-20 16:38:30 -07001031 elem_id = ptr[0];
1032 elem_len = ptr[1];
1033 left -= 2;
1034 if(elem_len > left)
1035 {
1036 hddLog(VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07001037 FL("****Invalid IEs eid = %d elem_len=%d left=%d*****"),
Jeff Johnson295189b2012-06-20 16:38:30 -07001038 eid,elem_len,left);
1039 return NULL;
1040 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301041 if (elem_id == eid)
Jeff Johnson295189b2012-06-20 16:38:30 -07001042 {
1043 return ptr;
1044 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301045
Jeff Johnson295189b2012-06-20 16:38:30 -07001046 left -= elem_len;
1047 ptr += (elem_len + 2);
1048 }
1049 return NULL;
1050}
1051
Jeff Johnson295189b2012-06-20 16:38:30 -07001052/* Check if rate is 11g rate or not */
1053static int wlan_hdd_rate_is_11g(u8 rate)
1054{
1055 u8 gRateArray[8] = {12, 18, 24, 36, 48, 72, 96, 104}; /* actual rate * 2 */
1056 u8 i;
1057 for (i = 0; i < 8; i++)
1058 {
1059 if(rate == gRateArray[i])
1060 return TRUE;
1061 }
1062 return FALSE;
1063}
1064
1065/* Check for 11g rate and set proper 11g only mode */
1066static void wlan_hdd_check_11gmode(u8 *pIe, u8* require_ht,
1067 u8* pCheckRatesfor11g, eSapPhyMode* pSapHw_mode)
1068{
1069 u8 i, num_rates = pIe[0];
1070
1071 pIe += 1;
1072 for ( i = 0; i < num_rates; i++)
1073 {
1074 if( *pCheckRatesfor11g && (TRUE == wlan_hdd_rate_is_11g(pIe[i] & RATE_MASK)))
1075 {
1076 /* If rate set have 11g rate than change the mode to 11G */
1077 *pSapHw_mode = eSAP_DOT11_MODE_11g;
1078 if (pIe[i] & BASIC_RATE_MASK)
1079 {
1080 /* If we have 11g rate as basic rate, it means mode
1081 is 11g only mode.
1082 */
1083 *pSapHw_mode = eSAP_DOT11_MODE_11g_ONLY;
1084 *pCheckRatesfor11g = FALSE;
1085 }
1086 }
1087 else if((BASIC_RATE_MASK | WLAN_BSS_MEMBERSHIP_SELECTOR_HT_PHY) == pIe[i])
1088 {
1089 *require_ht = TRUE;
1090 }
1091 }
1092 return;
1093}
1094
1095static void wlan_hdd_set_sapHwmode(hdd_adapter_t *pHostapdAdapter)
1096{
1097 tsap_Config_t *pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
1098 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
1099 struct ieee80211_mgmt *pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
1100 u8 checkRatesfor11g = TRUE;
1101 u8 require_ht = FALSE;
1102 u8 *pIe=NULL;
1103
1104 pConfig->SapHw_mode= eSAP_DOT11_MODE_11b;
1105
1106 pIe = wlan_hdd_cfg80211_get_ie_ptr(&pMgmt_frame->u.beacon.variable[0],
1107 pBeacon->head_len, WLAN_EID_SUPP_RATES);
1108 if (pIe != NULL)
1109 {
1110 pIe += 1;
1111 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
1112 &pConfig->SapHw_mode);
1113 }
1114
1115 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
1116 WLAN_EID_EXT_SUPP_RATES);
1117 if (pIe != NULL)
1118 {
1119
1120 pIe += 1;
1121 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
1122 &pConfig->SapHw_mode);
1123 }
1124
1125 if( pConfig->channel > 14 )
1126 {
1127 pConfig->SapHw_mode= eSAP_DOT11_MODE_11a;
1128 }
1129
1130 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
1131 WLAN_EID_HT_CAPABILITY);
1132
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301133 if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07001134 {
1135 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n;
1136 if(require_ht)
1137 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n_ONLY;
1138 }
1139}
1140
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05301141static int wlan_hdd_add_ie(hdd_adapter_t* pHostapdAdapter, v_U8_t *genie,
1142 v_U8_t *total_ielen, v_U8_t *oui, v_U8_t oui_size)
1143{
1144 v_U8_t ielen = 0;
1145 v_U8_t *pIe = NULL;
1146 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
1147
1148 pIe = wlan_hdd_get_vendor_oui_ie_ptr(oui, oui_size,
1149 pBeacon->tail, pBeacon->tail_len);
1150
1151 if (pIe)
1152 {
1153 ielen = pIe[1] + 2;
1154 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
1155 {
1156 vos_mem_copy(&genie[*total_ielen], pIe, ielen);
1157 }
1158 else
1159 {
1160 hddLog( VOS_TRACE_LEVEL_ERROR, "**Ie Length is too big***");
1161 return -EINVAL;
1162 }
1163 *total_ielen += ielen;
1164 }
1165 return 0;
1166}
1167
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001168#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07001169static int wlan_hdd_cfg80211_update_apies(hdd_adapter_t* pHostapdAdapter,
1170 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001171#else
1172static int wlan_hdd_cfg80211_update_apies(hdd_adapter_t* pHostapdAdapter,
1173 struct cfg80211_beacon_data *params)
1174#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07001175{
1176 v_U8_t *genie;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05301177 v_U8_t total_ielen = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07001178 v_U8_t addIE[1] = {0};
Jeff Johnsone7245742012-09-05 17:12:55 -07001179 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07001180
1181 genie = vos_mem_malloc(MAX_GENIE_LEN);
1182
1183 if(genie == NULL) {
1184
1185 return -ENOMEM;
1186 }
1187
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05301188 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
1189 &total_ielen, WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07001190 {
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05301191 ret = -EINVAL;
1192 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001193 }
1194
1195#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05301196 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
1197 &total_ielen, WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE))
1198 {
1199 ret = -EINVAL;
1200 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001201 }
1202#endif
1203
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05301204 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
1205 &total_ielen, P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07001206 {
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05301207 ret = -EINVAL;
1208 goto done;
1209 }
1210
1211 if (WLAN_HDD_SOFTAP == pHostapdAdapter->device_mode)
1212 {
1213 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
1214 &total_ielen, SS_OUI_TYPE, SS_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07001215 {
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05301216 ret = -EINVAL;
1217 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001218 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001219 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001220
1221 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1222 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, genie, total_ielen, NULL,
1223 eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
1224 {
1225 hddLog(LOGE,
1226 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001227 ret = -EINVAL;
1228 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001229 }
1230
1231 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1232 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
1233 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
1234 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
1235 ==eHAL_STATUS_FAILURE)
1236 {
1237 hddLog(LOGE,
1238 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001239 ret = -EINVAL;
1240 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001241 }
1242
1243 // Added for ProResp IE
1244 if ( (params->proberesp_ies != NULL) && (params->proberesp_ies_len != 0) )
1245 {
1246 u16 rem_probe_resp_ie_len = params->proberesp_ies_len;
1247 u8 probe_rsp_ie_len[3] = {0};
1248 u8 counter = 0;
1249 /* Check Probe Resp Length if it is greater then 255 then Store
1250 Probe Resp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1 &
1251 WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are not able
1252 Store More then 255 bytes into One Variable.
1253 */
1254 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
1255 {
1256 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
1257 {
1258 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
1259 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
1260 }
1261 else
1262 {
1263 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
1264 rem_probe_resp_ie_len = 0;
1265 }
1266 }
1267
1268 rem_probe_resp_ie_len = 0;
1269
1270 if (probe_rsp_ie_len[0] > 0)
1271 {
1272 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1273 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
1274 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
1275 probe_rsp_ie_len[0], NULL,
1276 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
1277 {
1278 hddLog(LOGE,
1279 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001280 ret = -EINVAL;
1281 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001282 }
1283 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
1284 }
1285
1286 if (probe_rsp_ie_len[1] > 0)
1287 {
1288 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1289 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
1290 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
1291 probe_rsp_ie_len[1], NULL,
1292 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
1293 {
1294 hddLog(LOGE,
1295 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001296 ret = -EINVAL;
1297 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001298 }
1299 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
1300 }
1301
1302 if (probe_rsp_ie_len[2] > 0)
1303 {
1304 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1305 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
1306 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
1307 probe_rsp_ie_len[2], NULL,
1308 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
1309 {
1310 hddLog(LOGE,
1311 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001312 ret = -EINVAL;
1313 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001314 }
1315 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
1316 }
1317
1318 if (probe_rsp_ie_len[1] == 0 )
1319 {
1320 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1321 WNI_CFG_PROBE_RSP_ADDNIE_DATA2, (tANI_U8*)addIE, 0, NULL,
1322 eANI_BOOLEAN_FALSE) )
1323 {
1324 hddLog(LOGE,
1325 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM\n");
1326 }
1327 }
1328
1329 if (probe_rsp_ie_len[2] == 0 )
1330 {
1331 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1332 WNI_CFG_PROBE_RSP_ADDNIE_DATA3, (tANI_U8*)addIE, 0, NULL,
1333 eANI_BOOLEAN_FALSE) )
1334 {
1335 hddLog(LOGE,
1336 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM\n");
1337 }
1338 }
1339
1340 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1341 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
1342 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
1343 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
1344 == eHAL_STATUS_FAILURE)
1345 {
1346 hddLog(LOGE,
1347 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001348 ret = -EINVAL;
1349 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001350 }
1351 }
1352 else
1353 {
1354 // Reset WNI_CFG_PROBE_RSP Flags
1355 wlan_hdd_reset_prob_rspies(pHostapdAdapter);
1356
1357 hddLog(VOS_TRACE_LEVEL_INFO,
1358 "%s: No Probe Response IE received in set beacon",
1359 __func__);
1360 }
1361
1362 // Added for AssocResp IE
1363 if ( (params->assocresp_ies != NULL) && (params->assocresp_ies_len != 0) )
1364 {
1365 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1366 WNI_CFG_ASSOC_RSP_ADDNIE_DATA, (tANI_U8*)params->assocresp_ies,
1367 params->assocresp_ies_len, NULL,
1368 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
1369 {
1370 hddLog(LOGE,
1371 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001372 ret = -EINVAL;
1373 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001374 }
1375
1376 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1377 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 1, NULL,
1378 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
1379 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
1380 == eHAL_STATUS_FAILURE)
1381 {
1382 hddLog(LOGE,
1383 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001384 ret = -EINVAL;
1385 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001386 }
1387 }
1388 else
1389 {
1390 hddLog(VOS_TRACE_LEVEL_INFO,
1391 "%s: No Assoc Response IE received in set beacon",
1392 __func__);
1393
1394 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1395 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
1396 eANI_BOOLEAN_FALSE) )
1397 {
1398 hddLog(LOGE,
1399 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM\n");
1400 }
1401 }
1402
Jeff Johnsone7245742012-09-05 17:12:55 -07001403done:
Jeff Johnson295189b2012-06-20 16:38:30 -07001404 vos_mem_free(genie);
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05301405 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07001406}
Jeff Johnson295189b2012-06-20 16:38:30 -07001407
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301408/*
Jeff Johnson295189b2012-06-20 16:38:30 -07001409 * FUNCTION: wlan_hdd_validate_operation_channel
1410 * called by wlan_hdd_cfg80211_start_bss() and
1411 * wlan_hdd_cfg80211_set_channel()
1412 * This function validates whether given channel is part of valid
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301413 * channel list.
1414 */
Jeff Johnson295189b2012-06-20 16:38:30 -07001415static VOS_STATUS wlan_hdd_validate_operation_channel(hdd_adapter_t *pAdapter,int channel)
1416{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301417
Jeff Johnson295189b2012-06-20 16:38:30 -07001418 v_U32_t num_ch = 0;
1419 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN];
1420 u32 indx = 0;
1421 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05301422 v_U8_t fValidChannel = FALSE, count = 0;
1423 hdd_config_t *hdd_pConfig_ini= (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301424
Jeff Johnson295189b2012-06-20 16:38:30 -07001425 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
1426
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05301427 if ( hdd_pConfig_ini->sapAllowAllChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -07001428 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05301429 /* Validate the channel */
1430 for (count = RF_CHAN_1 ; count <= RF_CHAN_165 ; count++)
Jeff Johnson295189b2012-06-20 16:38:30 -07001431 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05301432 if ( channel == rfChannels[count].channelNum )
1433 {
1434 fValidChannel = TRUE;
1435 break;
1436 }
1437 }
1438 if (fValidChannel != TRUE)
1439 {
1440 hddLog(VOS_TRACE_LEVEL_ERROR,
1441 "%s: Invalid Channel [%d]", __func__, channel);
1442 return VOS_STATUS_E_FAILURE;
Jeff Johnson295189b2012-06-20 16:38:30 -07001443 }
1444 }
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05301445 else
Jeff Johnson295189b2012-06-20 16:38:30 -07001446 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05301447 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
1448 valid_ch, &num_ch))
1449 {
1450 hddLog(VOS_TRACE_LEVEL_ERROR,
1451 "%s: failed to get valid channel list", __func__);
1452 return VOS_STATUS_E_FAILURE;
1453 }
1454 for (indx = 0; indx < num_ch; indx++)
1455 {
1456 if (channel == valid_ch[indx])
1457 {
1458 break;
1459 }
1460 }
1461
1462 if (indx >= num_ch)
1463 {
1464 hddLog(VOS_TRACE_LEVEL_ERROR,
1465 "%s: Invalid Channel [%d]", __func__, channel);
1466 return VOS_STATUS_E_FAILURE;
1467 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001468 }
1469 return VOS_STATUS_SUCCESS;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301470
Jeff Johnson295189b2012-06-20 16:38:30 -07001471}
1472
Viral Modi3a32cc52013-02-08 11:14:52 -08001473/**
1474 * FUNCTION: wlan_hdd_cfg80211_set_channel
1475 * This function is used to set the channel number
1476 */
1477static int wlan_hdd_cfg80211_set_channel( struct wiphy *wiphy, struct net_device *dev,
1478 struct ieee80211_channel *chan,
1479 enum nl80211_channel_type channel_type
1480 )
1481{
1482 v_U32_t num_ch = 0;
Jeff Johnson4416a782013-03-25 14:17:50 -07001483 int channel = 0;
Viral Modi3a32cc52013-02-08 11:14:52 -08001484 hdd_adapter_t *pAdapter = NULL;
1485 int freq = chan->center_freq; /* freq is in MHZ */
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05301486 hdd_context_t *pHddCtx;
1487 int status;
Viral Modi3a32cc52013-02-08 11:14:52 -08001488
1489 ENTER();
1490
1491 if( NULL == dev )
1492 {
1493 hddLog(VOS_TRACE_LEVEL_ERROR,
1494 "%s: Called with dev = NULL.\n", __func__);
1495 return -ENODEV;
1496 }
1497 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
1498
1499 hddLog(VOS_TRACE_LEVEL_INFO,
1500 "%s: device_mode = %d freq = %d \n",__func__,
1501 pAdapter->device_mode, chan->center_freq);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05301502
1503 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1504 status = wlan_hdd_validate_context(pHddCtx);
1505
1506 if (0 != status)
Viral Modi3a32cc52013-02-08 11:14:52 -08001507 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05301508 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1509 "%s: HDD context is not valid", __func__);
1510 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -08001511 }
1512
1513 /*
1514 * Do freq to chan conversion
1515 * TODO: for 11a
1516 */
1517
1518 channel = ieee80211_frequency_to_channel(freq);
1519
1520 /* Check freq range */
1521 if ((WNI_CFG_CURRENT_CHANNEL_STAMIN > channel) ||
1522 (WNI_CFG_CURRENT_CHANNEL_STAMAX < channel))
1523 {
1524 hddLog(VOS_TRACE_LEVEL_ERROR,
1525 "%s: Channel [%d] is outside valid range from %d to %d\n",
1526 __func__, channel, WNI_CFG_CURRENT_CHANNEL_STAMIN,
1527 WNI_CFG_CURRENT_CHANNEL_STAMAX);
1528 return -EINVAL;
1529 }
1530
1531 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
1532
Gopichand Nakkala6ab19562013-03-07 13:59:42 +05301533 if ((WLAN_HDD_SOFTAP != pAdapter->device_mode) &&
1534 (WLAN_HDD_P2P_GO != pAdapter->device_mode))
Viral Modi3a32cc52013-02-08 11:14:52 -08001535 {
1536 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pAdapter,channel))
1537 {
1538 hddLog(VOS_TRACE_LEVEL_ERROR,
1539 "%s: Invalid Channel [%d] \n", __func__, channel);
1540 return -EINVAL;
1541 }
1542 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
1543 "%s: set channel to [%d] for device mode =%d",
1544 __func__, channel,pAdapter->device_mode);
1545 }
1546 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Viral Modi3a32cc52013-02-08 11:14:52 -08001547 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Viral Modi3a32cc52013-02-08 11:14:52 -08001548 )
1549 {
1550 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
1551 tCsrRoamProfile * pRoamProfile = &pWextState->roamProfile;
1552 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
1553
1554 if (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState)
1555 {
1556 /* Link is up then return cant set channel*/
1557 hddLog( VOS_TRACE_LEVEL_ERROR,
1558 "%s: IBSS Associated, can't set the channel\n", __func__);
1559 return -EINVAL;
1560 }
1561
1562 num_ch = pRoamProfile->ChannelInfo.numOfChannels = 1;
1563 pHddStaCtx->conn_info.operationChannel = channel;
1564 pRoamProfile->ChannelInfo.ChannelList =
1565 &pHddStaCtx->conn_info.operationChannel;
1566 }
1567 else if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Viral Modi3a32cc52013-02-08 11:14:52 -08001568 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Viral Modi3a32cc52013-02-08 11:14:52 -08001569 )
1570 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05301571 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
1572 {
1573 if(VOS_STATUS_SUCCESS !=
1574 wlan_hdd_validate_operation_channel(pAdapter,channel))
1575 {
1576 hddLog(VOS_TRACE_LEVEL_ERROR,
1577 "%s: Invalid Channel [%d] \n", __func__, channel);
1578 return -EINVAL;
1579 }
1580 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
1581 }
1582 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
Viral Modi3a32cc52013-02-08 11:14:52 -08001583 {
1584 hdd_config_t *cfg_param = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
1585
1586 /* If auto channel selection is configured as enable/ 1 then ignore
1587 channel set by supplicant
1588 */
1589 if ( cfg_param->apAutoChannelSelection )
1590 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05301591 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel =
1592 AUTO_CHANNEL_SELECT;
Viral Modi3a32cc52013-02-08 11:14:52 -08001593 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
1594 "%s: set channel to auto channel (0) for device mode =%d",
1595 __func__, pAdapter->device_mode);
1596 }
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05301597 else
1598 {
1599 if(VOS_STATUS_SUCCESS !=
1600 wlan_hdd_validate_operation_channel(pAdapter,channel))
1601 {
1602 hddLog(VOS_TRACE_LEVEL_ERROR,
1603 "%s: Invalid Channel [%d] \n", __func__, channel);
1604 return -EINVAL;
1605 }
1606 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
1607 }
Viral Modi3a32cc52013-02-08 11:14:52 -08001608 }
1609 }
1610 else
1611 {
1612 hddLog(VOS_TRACE_LEVEL_FATAL,
1613 "%s: Invalid device mode failed to set valid channel", __func__);
1614 return -EINVAL;
1615 }
1616 EXIT();
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05301617 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -08001618}
1619
Jeff Johnson295189b2012-06-20 16:38:30 -07001620#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
1621static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
1622 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001623#else
1624static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
1625 struct cfg80211_beacon_data *params,
1626 const u8 *ssid, size_t ssid_len,
1627 enum nl80211_hidden_ssid hidden_ssid)
1628#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07001629{
1630 tsap_Config_t *pConfig;
1631 beacon_data_t *pBeacon = NULL;
1632 struct ieee80211_mgmt *pMgmt_frame;
1633 v_U8_t *pIe=NULL;
1634 v_U16_t capab_info;
1635 eCsrAuthType RSNAuthType;
1636 eCsrEncryptionType RSNEncryptType;
1637 eCsrEncryptionType mcRSNEncryptType;
1638 int status = VOS_STATUS_SUCCESS;
1639 tpWLAN_SAPEventCB pSapEventCallback;
1640 hdd_hostapd_state_t *pHostapdState;
1641 v_U8_t wpaRsnIEdata[(SIR_MAC_MAX_IE_LENGTH * 2)+4]; //Max ie length 255 * 2(WPA+RSN) + 2 bytes (vendor specific ID) * 2
1642 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05301643 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07001644 struct qc_mac_acl_entry *acl_entry = NULL;
1645 v_SINT_t i;
Madan Mohan Koyyalamudi543172b2012-12-05 16:40:18 -08001646 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07001647
1648 ENTER();
1649
1650 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter);
1651
1652 pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
1653
1654 pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
1655
1656 pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
1657
1658 pConfig->beacon_int = pMgmt_frame->u.beacon.beacon_int;
1659
1660 //channel is already set in the set_channel Call back
1661 //pConfig->channel = pCommitConfig->channel;
1662
1663 /*Protection parameter to enable or disable*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301664 pConfig->protEnabled =
Jeff Johnson295189b2012-06-20 16:38:30 -07001665 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtEnabled;
1666
1667 pConfig->dtim_period = pBeacon->dtim_period;
1668
1669 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"****pConfig->dtim_period=%d***\n",
1670 pConfig->dtim_period);
1671
1672
Madan Mohan Koyyalamudie0ca11f2012-11-27 15:57:52 -08001673 if (pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson32d95a32012-09-10 13:15:23 -07001674 {
1675 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -07001676 WLAN_EID_COUNTRY);
Jeff Johnson32d95a32012-09-10 13:15:23 -07001677 if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07001678 {
Jeff Johnson32d95a32012-09-10 13:15:23 -07001679 tANI_BOOLEAN restartNeeded;
Jeff Johnson32d95a32012-09-10 13:15:23 -07001680 pConfig->ieee80211d = 1;
1681 vos_mem_copy(pConfig->countryCode, &pIe[2], 3);
1682 sme_setRegInfo(hHal, pConfig->countryCode);
1683 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
Jeff Johnson295189b2012-06-20 16:38:30 -07001684 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07001685 else
1686 {
1687 pConfig->ieee80211d = 0;
1688 }
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05301689 /*
1690 * If auto channel is configured i.e. channel is 0,
1691 * so skip channel validation.
1692 */
1693 if( AUTO_CHANNEL_SELECT != pConfig->channel )
1694 {
1695 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pHostapdAdapter,pConfig->channel))
1696 {
1697 hddLog(VOS_TRACE_LEVEL_ERROR,
1698 "%s: Invalid Channel [%d] \n", __func__, pConfig->channel);
1699 return -EINVAL;
1700 }
1701 }
1702 else
1703 {
1704 if(1 != pHddCtx->is_dynamic_channel_range_set)
1705 {
1706 hdd_config_t *hdd_pConfig= (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini;
1707 WLANSAP_SetChannelRange(hHal, hdd_pConfig->apStartChannelNum,
1708 hdd_pConfig->apEndChannelNum,hdd_pConfig->apOperatingBand);
1709 }
1710 pHddCtx->is_dynamic_channel_range_set = 0;
1711 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001712 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07001713 else
Jeff Johnson295189b2012-06-20 16:38:30 -07001714 {
1715 pConfig->ieee80211d = 0;
1716 }
1717 pConfig->authType = eSAP_AUTO_SWITCH;
1718
1719 capab_info = pMgmt_frame->u.beacon.capab_info;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301720
1721 pConfig->privacy = (pMgmt_frame->u.beacon.capab_info &
Jeff Johnson295189b2012-06-20 16:38:30 -07001722 WLAN_CAPABILITY_PRIVACY) ? VOS_TRUE : VOS_FALSE;
1723
1724 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uPrivacy = pConfig->privacy;
1725
1726 /*Set wps station to configured*/
1727 pIe = wlan_hdd_get_wps_ie_ptr(pBeacon->tail, pBeacon->tail_len);
1728
1729 if(pIe)
1730 {
1731 if(pIe[1] < (2 + WPS_OUI_TYPE_SIZE))
1732 {
1733 hddLog( VOS_TRACE_LEVEL_ERROR, "**Wps Ie Length is too small***\n");
1734 return -EINVAL;
1735 }
1736 else if(memcmp(&pIe[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) == 0)
1737 {
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07001738 hddLog( VOS_TRACE_LEVEL_INFO, "** WPS IE(len %d) ***", (pIe[1]+2));
Jeff Johnson295189b2012-06-20 16:38:30 -07001739 /* Check 15 bit of WPS IE as it contain information for wps state
1740 * WPS state
1741 */
1742 if(SAP_WPS_ENABLED_UNCONFIGURED == pIe[15])
1743 {
1744 pConfig->wps_state = SAP_WPS_ENABLED_UNCONFIGURED;
1745 } else if(SAP_WPS_ENABLED_CONFIGURED == pIe[15])
1746 {
1747 pConfig->wps_state = SAP_WPS_ENABLED_CONFIGURED;
1748 }
1749 }
1750 }
1751 else
1752 {
1753 pConfig->wps_state = SAP_WPS_DISABLED;
1754 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301755 pConfig->fwdWPSPBCProbeReq = 1; // Forward WPS PBC probe request frame up
Jeff Johnson295189b2012-06-20 16:38:30 -07001756
1757 pConfig->RSNWPAReqIELength = 0;
1758 pConfig->pRSNWPAReqIE = NULL;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301759 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -07001760 WLAN_EID_RSN);
1761 if(pIe && pIe[1])
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301762 {
Jeff Johnson295189b2012-06-20 16:38:30 -07001763 pConfig->RSNWPAReqIELength = pIe[1] + 2;
1764 memcpy(&wpaRsnIEdata[0], pIe, pConfig->RSNWPAReqIELength);
1765 pConfig->pRSNWPAReqIE = &wpaRsnIEdata[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301766 /* The actual processing may eventually be more extensive than
1767 * this. Right now, just consume any PMKIDs that are sent in
Jeff Johnson295189b2012-06-20 16:38:30 -07001768 * by the app.
1769 * */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301770 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -07001771 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
1772 &RSNEncryptType,
1773 &mcRSNEncryptType,
1774 &RSNAuthType,
1775 pConfig->pRSNWPAReqIE[1]+2,
1776 pConfig->pRSNWPAReqIE );
1777
1778 if( VOS_STATUS_SUCCESS == status )
1779 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301780 /* Now copy over all the security attributes you have
1781 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -07001782 * */
1783 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
1784 pConfig->mcRSNEncryptType = mcRSNEncryptType;
1785 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
1786 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05301787 hddLog( LOG1, FL("CSR AuthType = %d, "
Jeff Johnson295189b2012-06-20 16:38:30 -07001788 "EncryptionType = %d mcEncryptionType = %d\n"),
1789 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
1790 }
1791 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301792
Jeff Johnson295189b2012-06-20 16:38:30 -07001793 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE,
1794 pBeacon->tail, pBeacon->tail_len);
1795
1796 if(pIe && pIe[1] && (pIe[0] == DOT11F_EID_WPA))
1797 {
1798 if (pConfig->pRSNWPAReqIE)
1799 {
1800 /*Mixed mode WPA/WPA2*/
1801 memcpy((&wpaRsnIEdata[0] + pConfig->RSNWPAReqIELength), pIe, pIe[1] + 2);
1802 pConfig->RSNWPAReqIELength += pIe[1] + 2;
1803 }
1804 else
1805 {
1806 pConfig->RSNWPAReqIELength = pIe[1] + 2;
1807 memcpy(&wpaRsnIEdata[0], pIe, pConfig->RSNWPAReqIELength);
1808 pConfig->pRSNWPAReqIE = &wpaRsnIEdata[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301809 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -07001810 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
1811 &RSNEncryptType,
1812 &mcRSNEncryptType,
1813 &RSNAuthType,
1814 pConfig->pRSNWPAReqIE[1]+2,
1815 pConfig->pRSNWPAReqIE );
1816
1817 if( VOS_STATUS_SUCCESS == status )
1818 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301819 /* Now copy over all the security attributes you have
1820 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -07001821 * */
1822 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
1823 pConfig->mcRSNEncryptType = mcRSNEncryptType;
1824 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
1825 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05301826 hddLog( LOG1, FL("CSR AuthType = %d, "
Jeff Johnson295189b2012-06-20 16:38:30 -07001827 "EncryptionType = %d mcEncryptionType = %d\n"),
1828 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
1829 }
1830 }
1831 }
1832
Jeff Johnson4416a782013-03-25 14:17:50 -07001833 if (pConfig->RSNWPAReqIELength > sizeof wpaRsnIEdata) {
1834 hddLog( VOS_TRACE_LEVEL_ERROR, "**RSNWPAReqIELength is too large***");
1835 return -EINVAL;
1836 }
1837
Jeff Johnson295189b2012-06-20 16:38:30 -07001838 pConfig->SSIDinfo.ssidHidden = VOS_FALSE;
1839
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001840#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07001841 if (params->ssid != NULL)
1842 {
1843 memcpy(pConfig->SSIDinfo.ssid.ssId, params->ssid, params->ssid_len);
1844 pConfig->SSIDinfo.ssid.length = params->ssid_len;
1845 if (params->hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
1846 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
1847 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001848#else
1849 if (ssid != NULL)
1850 {
1851 memcpy(pConfig->SSIDinfo.ssid.ssId, ssid, ssid_len);
1852 pConfig->SSIDinfo.ssid.length = ssid_len;
1853 if (hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
1854 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
1855 }
1856#endif
1857
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301858 vos_mem_copy(pConfig->self_macaddr.bytes,
Jeff Johnson295189b2012-06-20 16:38:30 -07001859 pHostapdAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301860
Jeff Johnson295189b2012-06-20 16:38:30 -07001861 /* default value */
1862 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
1863 pConfig->num_accept_mac = 0;
1864 pConfig->num_deny_mac = 0;
1865
1866 pIe = wlan_hdd_get_vendor_oui_ie_ptr(BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
1867 pBeacon->tail, pBeacon->tail_len);
1868
1869 /* pIe for black list is following form:
1870 type : 1 byte
1871 length : 1 byte
1872 OUI : 4 bytes
1873 acl type : 1 byte
1874 no of mac addr in black list: 1 byte
1875 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301876 */
1877 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07001878 {
1879 pConfig->SapMacaddr_acl = pIe[6];
1880 pConfig->num_deny_mac = pIe[7];
1881 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no deny mac = %d\n",
1882 pIe[6], pIe[7]);
1883 if (pConfig->num_deny_mac > MAX_MAC_ADDRESS_DENIED)
1884 pConfig->num_deny_mac = MAX_MAC_ADDRESS_DENIED;
1885 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
1886 for (i = 0; i < pConfig->num_deny_mac; i++)
1887 {
1888 vos_mem_copy(&pConfig->deny_mac[i], acl_entry->addr, sizeof(qcmacaddr));
1889 acl_entry++;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301890 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001891 }
1892 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
1893 pBeacon->tail, pBeacon->tail_len);
1894
1895 /* pIe for white list is following form:
1896 type : 1 byte
1897 length : 1 byte
1898 OUI : 4 bytes
1899 acl type : 1 byte
1900 no of mac addr in white list: 1 byte
1901 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301902 */
1903 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07001904 {
1905 pConfig->SapMacaddr_acl = pIe[6];
1906 pConfig->num_accept_mac = pIe[7];
1907 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no accept mac = %d\n",
1908 pIe[6], pIe[7]);
1909 if (pConfig->num_accept_mac > MAX_MAC_ADDRESS_ACCEPTED)
1910 pConfig->num_accept_mac = MAX_MAC_ADDRESS_ACCEPTED;
1911 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
1912 for (i = 0; i < pConfig->num_accept_mac; i++)
1913 {
1914 vos_mem_copy(&pConfig->accept_mac[i], acl_entry->addr, sizeof(qcmacaddr));
1915 acl_entry++;
1916 }
1917 }
1918 wlan_hdd_set_sapHwmode(pHostapdAdapter);
1919
Jeff Johnsone7245742012-09-05 17:12:55 -07001920#ifdef WLAN_FEATURE_11AC
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -08001921 /* Overwrite the hostapd setting for HW mode only for 11ac.
1922 * This is valid only if mode is set to 11n in hostapd and either AUTO or 11ac in .ini .
1923 * Otherwise, leave whatever is set in hostapd (a OR b OR g OR n mode) */
1924 if( ((pConfig->SapHw_mode == eSAP_DOT11_MODE_11n) ||
1925 (pConfig->SapHw_mode == eSAP_DOT11_MODE_11n_ONLY)) &&
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301926 (((WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->dot11Mode == eHDD_DOT11_MODE_AUTO) ||
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -08001927 ((WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->dot11Mode == eHDD_DOT11_MODE_11ac) ||
1928 ((WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->dot11Mode == eHDD_DOT11_MODE_11ac_ONLY)) )
Jeff Johnsone7245742012-09-05 17:12:55 -07001929 {
1930 pConfig->SapHw_mode = eSAP_DOT11_MODE_11ac;
1931 }
1932#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301933
Ravi Joshiaeb7d9e2013-05-02 12:28:14 -07001934 if ( AUTO_CHANNEL_SELECT != pConfig->channel )
1935 {
1936 sme_SelectCBMode(hHal,
1937 sapConvertSapPhyModeToCsrPhyMode(pConfig->SapHw_mode),
1938 pConfig->channel);
1939 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001940 // ht_capab is not what the name conveys,this is used for protection bitmap
1941 pConfig->ht_capab =
1942 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtection;
1943
1944 if ( 0 != wlan_hdd_cfg80211_update_apies(pHostapdAdapter, params) )
1945 {
1946 hddLog(LOGE, FL("SAP Not able to set AP IEs"));
1947 return -EINVAL;
1948 }
1949
1950 //Uapsd Enabled Bit
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301951 pConfig->UapsdEnable =
Jeff Johnson295189b2012-06-20 16:38:30 -07001952 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apUapsdEnabled;
1953 //Enable OBSS protection
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301954 pConfig->obssProtEnabled =
1955 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apOBSSProtEnabled;
Jeff Johnson295189b2012-06-20 16:38:30 -07001956
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301957 hddLog(LOGW, FL("SOftAP macaddress : "MAC_ADDRESS_STR"\n"),
Jeff Johnson295189b2012-06-20 16:38:30 -07001958 MAC_ADDR_ARRAY(pHostapdAdapter->macAddressCurrent.bytes));
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301959 hddLog(LOGW,FL("ssid =%s\n"), pConfig->SSIDinfo.ssid.ssId);
Jeff Johnson295189b2012-06-20 16:38:30 -07001960 hddLog(LOGW,FL("beaconint=%d, channel=%d\n"), (int)pConfig->beacon_int,
1961 (int)pConfig->channel);
1962 hddLog(LOGW,FL("hw_mode=%x\n"), pConfig->SapHw_mode);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301963 hddLog(LOGW,FL("privacy=%d, authType=%d\n"), pConfig->privacy,
1964 pConfig->authType);
Jeff Johnson295189b2012-06-20 16:38:30 -07001965 hddLog(LOGW,FL("RSN/WPALen=%d, \n"),(int)pConfig->RSNWPAReqIELength);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301966 hddLog(LOGW,FL("Uapsd = %d\n"),pConfig->UapsdEnable);
Jeff Johnson295189b2012-06-20 16:38:30 -07001967 hddLog(LOGW,FL("ProtEnabled = %d, OBSSProtEnabled = %d\n"),
1968 pConfig->protEnabled, pConfig->obssProtEnabled);
1969
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301970 if(test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -07001971 {
1972 //Bss already started. just return.
1973 //TODO Probably it should update some beacon params.
1974 hddLog( LOGE, "Bss Already started...Ignore the request");
1975 EXIT();
1976 return 0;
1977 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301978
Jeff Johnson295189b2012-06-20 16:38:30 -07001979 pConfig->persona = pHostapdAdapter->device_mode;
1980
1981 pSapEventCallback = hdd_hostapd_SAPEventCB;
1982 if(WLANSAP_StartBss(pVosContext, pSapEventCallback, pConfig,
1983 (v_PVOID_t)pHostapdAdapter->dev) != VOS_STATUS_SUCCESS)
1984 {
1985 hddLog(LOGE,FL("SAP Start Bss fail\n"));
1986 return -EINVAL;
1987 }
1988
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301989 hddLog(LOG1,
Jeff Johnson295189b2012-06-20 16:38:30 -07001990 FL("Waiting for Scan to complete(auto mode) and BSS to start"));
1991
1992 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301993
Jeff Johnson295189b2012-06-20 16:38:30 -07001994 if (!VOS_IS_STATUS_SUCCESS(status))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301995 {
1996 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07001997 ("ERROR: HDD vos wait for single_event failed!!\n"));
1998 VOS_ASSERT(0);
1999 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302000
Jeff Johnson295189b2012-06-20 16:38:30 -07002001 //Succesfully started Bss update the state bit.
2002 set_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags);
2003
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07002004#ifdef WLAN_FEATURE_P2P_DEBUG
2005 if (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO)
2006 {
2007 if(globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED)
2008 {
2009 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
2010 hddLog(LOGE,"[P2P State] From Go nego completed to "
Jeff Johnson1250df42012-12-10 14:31:52 -08002011 "Non-autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07002012 }
2013 else if(globalP2PConnectionStatus == P2P_NOT_ACTIVE)
2014 {
2015 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
2016 hddLog(LOGE,"[P2P State] From Inactive to "
Jeff Johnson1250df42012-12-10 14:31:52 -08002017 "Autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07002018 }
2019 }
2020#endif
2021
Jeff Johnson295189b2012-06-20 16:38:30 -07002022 pHostapdState->bCommit = TRUE;
2023 EXIT();
2024
2025 return 0;
2026}
2027
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002028#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302029static int wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy,
2030 struct net_device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -07002031 struct beacon_parameters *params)
2032{
2033 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302034 hdd_context_t *pHddCtx;
2035 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07002036
2037 ENTER();
2038
2039 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "device mode=%d\n",pAdapter->device_mode);
2040
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302041 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2042 status = wlan_hdd_validate_context(pHddCtx);
2043
2044 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002045 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302046 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2047 "%s: HDD context is not valid", __func__);
2048 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002049 }
2050
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302051 if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07002052 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07002053 )
2054 {
2055 beacon_data_t *old,*new;
2056
2057 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302058
Jeff Johnson295189b2012-06-20 16:38:30 -07002059 if (old)
2060 return -EALREADY;
2061
2062 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
2063
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302064 if(status != VOS_STATUS_SUCCESS)
Jeff Johnson295189b2012-06-20 16:38:30 -07002065 {
2066 hddLog(VOS_TRACE_LEVEL_FATAL,
2067 "%s:Error!!! Allocating the new beacon\n",__func__);
2068 return -EINVAL;
2069 }
2070
2071 pAdapter->sessionCtx.ap.beacon = new;
2072
2073 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
2074 }
2075
2076 EXIT();
2077 return status;
2078}
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302079
2080static int wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07002081 struct net_device *dev,
2082 struct beacon_parameters *params)
2083{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302084 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302085 hdd_context_t *pHddCtx;
2086 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07002087
2088 ENTER();
2089
2090 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",
2091 __func__,pAdapter->device_mode);
2092
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302093 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2094 status = wlan_hdd_validate_context(pHddCtx);
2095
2096 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002097 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302098 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2099 "%s: HDD context is not valid", __func__);
2100 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002101 }
2102
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302103 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07002104 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302105 )
Jeff Johnson295189b2012-06-20 16:38:30 -07002106 {
2107 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302108
Jeff Johnson295189b2012-06-20 16:38:30 -07002109 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302110
Jeff Johnson295189b2012-06-20 16:38:30 -07002111 if (!old)
2112 return -ENOENT;
2113
2114 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
2115
2116 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302117 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson295189b2012-06-20 16:38:30 -07002118 "%s: Error!!! Allocating the new beacon\n",__func__);
2119 return -EINVAL;
2120 }
2121
2122 pAdapter->sessionCtx.ap.beacon = new;
2123
2124 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
2125 }
2126
2127 EXIT();
2128 return status;
2129}
2130
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002131#endif //(LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
2132
2133#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07002134static int wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy,
2135 struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002136#else
2137static int wlan_hdd_cfg80211_stop_ap (struct wiphy *wiphy,
2138 struct net_device *dev)
2139#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07002140{
2141 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnsone7245742012-09-05 17:12:55 -07002142 hdd_context_t *pHddCtx = NULL;
2143 hdd_scaninfo_t *pScanInfo = NULL;
2144 hdd_adapter_t *staAdapter = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302145 VOS_STATUS status;
Jeff Johnson295189b2012-06-20 16:38:30 -07002146
2147 ENTER();
2148
2149 if (NULL == pAdapter)
2150 {
2151 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002152 "%s: HDD adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002153 return -ENODEV;
2154 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07002155
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302156 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2157 status = wlan_hdd_validate_context(pHddCtx);
2158
2159 if (0 != status)
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07002160 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302161 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2162 "%s: HDD context is not valid", __func__);
2163 return status;
Jeff Johnson4416a782013-03-25 14:17:50 -07002164 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07002165
2166 staAdapter = hdd_get_adapter(pAdapter->pHddCtx, WLAN_HDD_INFRA_STATION);
2167 if (NULL == staAdapter)
2168 {
2169 staAdapter = hdd_get_adapter(pAdapter->pHddCtx, WLAN_HDD_P2P_CLIENT);
2170 if (NULL == staAdapter)
2171 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302172 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002173 "%s: HDD adapter context is Null", __func__);
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07002174 return -ENODEV;
2175 }
2176 }
2177
2178 pScanInfo = &pHddCtx->scan_info;
2179
Jeff Johnson295189b2012-06-20 16:38:30 -07002180 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",
2181 __func__,pAdapter->device_mode);
2182
Jeff Johnsone7245742012-09-05 17:12:55 -07002183 if ((pScanInfo != NULL) && pScanInfo->mScanPending)
2184 {
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -08002185 INIT_COMPLETION(pScanInfo->abortscan_event_var);
Jeff Johnsone7245742012-09-05 17:12:55 -07002186 hdd_abort_mac_scan(staAdapter->pHddCtx);
2187 status = wait_for_completion_interruptible_timeout(
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -08002188 &pScanInfo->abortscan_event_var,
Jeff Johnsone7245742012-09-05 17:12:55 -07002189 msecs_to_jiffies(WLAN_WAIT_TIME_ABORTSCAN));
2190 if (!status)
2191 {
2192 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Jeff Johnson902c9832012-12-10 14:28:09 -08002193 "%s: Timeout occurred while waiting for abortscan" ,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002194 __func__);
Jeff Johnsone7245742012-09-05 17:12:55 -07002195 VOS_ASSERT(pScanInfo->mScanPending);
2196 return 0;
2197 }
2198 }
2199
Jeff Johnson295189b2012-06-20 16:38:30 -07002200 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07002201 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07002202 )
2203 {
2204 beacon_data_t *old;
2205
2206 old = pAdapter->sessionCtx.ap.beacon;
2207
2208 if (!old)
2209 return -ENOENT;
2210
Jeff Johnson295189b2012-06-20 16:38:30 -07002211 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07002212
2213 mutex_lock(&pHddCtx->sap_lock);
2214 if(test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
2215 {
Jeff Johnson4416a782013-03-25 14:17:50 -07002216 if ( VOS_STATUS_SUCCESS == (status = WLANSAP_StopBss(pHddCtx->pvosContext) ) )
Jeff Johnson295189b2012-06-20 16:38:30 -07002217 {
2218 hdd_hostapd_state_t *pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
2219
2220 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
2221
2222 if (!VOS_IS_STATUS_SUCCESS(status))
2223 {
2224 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2225 ("ERROR: HDD vos wait for single_event failed!!\n"));
2226 VOS_ASSERT(0);
2227 }
2228 }
2229 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
2230 }
2231 mutex_unlock(&pHddCtx->sap_lock);
2232
2233 if(status != VOS_STATUS_SUCCESS)
2234 {
2235 hddLog(VOS_TRACE_LEVEL_FATAL,
2236 "%s:Error!!! Stopping the BSS\n",__func__);
2237 return -EINVAL;
2238 }
2239
Jeff Johnson4416a782013-03-25 14:17:50 -07002240 if (ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -07002241 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 0,NULL, eANI_BOOLEAN_FALSE)
2242 ==eHAL_STATUS_FAILURE)
2243 {
2244 hddLog(LOGE,
2245 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM\n");
2246 }
2247
Jeff Johnson4416a782013-03-25 14:17:50 -07002248 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -07002249 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
2250 eANI_BOOLEAN_FALSE) )
2251 {
2252 hddLog(LOGE,
2253 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM\n");
2254 }
2255
2256 // Reset WNI_CFG_PROBE_RSP Flags
2257 wlan_hdd_reset_prob_rspies(pAdapter);
2258
2259 pAdapter->sessionCtx.ap.beacon = NULL;
2260 kfree(old);
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07002261#ifdef WLAN_FEATURE_P2P_DEBUG
2262 if((pAdapter->device_mode == WLAN_HDD_P2P_GO) &&
2263 (globalP2PConnectionStatus == P2P_GO_COMPLETED_STATE))
2264 {
2265 hddLog(LOGE,"[P2P State] From GO completed to Inactive state "
2266 "GO got removed");
2267 globalP2PConnectionStatus = P2P_NOT_ACTIVE;
2268 }
2269#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07002270 }
2271 EXIT();
2272 return status;
2273}
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002274
2275#if (LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
2276
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302277static int wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
2278 struct net_device *dev,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002279 struct cfg80211_ap_settings *params)
2280{
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302281 hdd_adapter_t *pAdapter;
2282 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302283 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002284
2285 ENTER();
2286
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302287 if (NULL == dev)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07002288 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302289 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302290 "%s: Device is Null", __func__);
2291 return -ENODEV;
2292 }
2293
2294 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2295 if (NULL == pAdapter)
2296 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302297 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302298 "%s: HDD adapter is Null", __func__);
2299 return -ENODEV;
2300 }
2301
2302 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
2303 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302304 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302305 "%s: HDD adapter magic is invalid", __func__);
2306 return -ENODEV;
2307 }
2308
2309 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302310 status = wlan_hdd_validate_context(pHddCtx);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302311
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302312 if (0 != status)
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302313 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302314 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2315 "%s: HDD context is not valid", __func__);
2316 return status;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302317 }
2318
2319 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device mode = %d",
2320 __func__, pAdapter->device_mode);
2321
2322 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002323 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002324 )
2325 {
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302326 beacon_data_t *old, *new;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002327
2328 old = pAdapter->sessionCtx.ap.beacon;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302329
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002330 if (old)
2331 return -EALREADY;
2332
2333 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter, &new, &params->beacon, params->dtim_period);
2334
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302335 if (status != 0)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002336 {
2337 hddLog(VOS_TRACE_LEVEL_FATAL,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302338 "%s:Error!!! Allocating the new beacon", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002339 return -EINVAL;
2340 }
2341 pAdapter->sessionCtx.ap.beacon = new;
Viral Modi3a32cc52013-02-08 11:14:52 -08002342#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
2343 wlan_hdd_cfg80211_set_channel(wiphy, dev, params->channel, params->channel_type);
2344#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002345 status = wlan_hdd_cfg80211_start_bss(pAdapter, &params->beacon, params->ssid,
2346 params->ssid_len, params->hidden_ssid);
2347 }
2348
2349 EXIT();
2350 return status;
2351}
2352
2353
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302354static int wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002355 struct net_device *dev,
2356 struct cfg80211_beacon_data *params)
2357{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302358 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302359 hdd_context_t *pHddCtx;
2360 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002361
2362 ENTER();
2363
2364 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",
2365 __func__, pAdapter->device_mode);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302366
2367 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2368 status = wlan_hdd_validate_context(pHddCtx);
2369
2370 if (0 != status)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07002371 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302372 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2373 "%s: HDD context is not valid", __func__);
2374 return status;
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07002375 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002376
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302377 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002378 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302379 )
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002380 {
2381 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302382
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002383 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302384
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002385 if (!old)
2386 return -ENOENT;
2387
2388 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter, &new, params, 0);
2389
2390 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302391 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002392 "%s: Error!!! Allocating the new beacon\n",__func__);
2393 return -EINVAL;
2394 }
2395
2396 pAdapter->sessionCtx.ap.beacon = new;
2397
2398 status = wlan_hdd_cfg80211_start_bss(pAdapter, params, NULL, 0, 0);
2399 }
2400
2401 EXIT();
2402 return status;
2403}
2404
2405#endif //(LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
2406
Jeff Johnson295189b2012-06-20 16:38:30 -07002407
2408static int wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
2409 struct net_device *dev,
2410 struct bss_parameters *params)
2411{
2412 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2413
2414 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302415
Jeff Johnson295189b2012-06-20 16:38:30 -07002416 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",
2417 __func__,pAdapter->device_mode);
2418
2419 if((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07002420 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302421 )
Jeff Johnson295189b2012-06-20 16:38:30 -07002422 {
2423 /* ap_isolate == -1 means that in change bss, upper layer doesn't
2424 * want to update this parameter */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302425 if (-1 != params->ap_isolate)
Jeff Johnson295189b2012-06-20 16:38:30 -07002426 {
2427 pAdapter->sessionCtx.ap.apDisableIntraBssFwd = !!params->ap_isolate;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302428 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002429 }
2430
2431 EXIT();
2432 return 0;
2433}
2434
2435/*
2436 * FUNCTION: wlan_hdd_cfg80211_change_iface
2437 * This function is used to set the interface type (INFRASTRUCTURE/ADHOC)
2438 */
2439int wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
2440 struct net_device *ndev,
2441 enum nl80211_iftype type,
2442 u32 *flags,
2443 struct vif_params *params
2444 )
2445{
2446 struct wireless_dev *wdev;
2447 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
2448 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
Mohit Khanna0f232092012-09-11 14:46:08 -07002449 hdd_adapter_t *pP2pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07002450 tCsrRoamProfile *pRoamProfile = NULL;
2451 eCsrRoamBssType LastBSSType;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302452 hdd_config_t *pConfig = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07002453 eMib_dot11DesiredBssType connectedBssType;
2454 VOS_STATUS status;
2455
2456 ENTER();
2457
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302458 status = wlan_hdd_validate_context(pHddCtx);
2459
2460 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -07002461 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302462 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2463 "%s: HDD context is not valid", __func__);
2464 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -07002465 }
2466
2467 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
2468 __func__, pAdapter->device_mode);
2469
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302470 pConfig = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -07002471 wdev = ndev->ieee80211_ptr;
2472
2473#ifdef WLAN_BTAMP_FEATURE
2474 if((NL80211_IFTYPE_P2P_CLIENT == type)||
2475 (NL80211_IFTYPE_ADHOC == type)||
2476 (NL80211_IFTYPE_AP == type)||
2477 (NL80211_IFTYPE_P2P_GO == type))
2478 {
2479 pHddCtx->isAmpAllowed = VOS_FALSE;
2480 // stop AMP traffic
2481 status = WLANBAP_StopAmp();
2482 if(VOS_STATUS_SUCCESS != status )
2483 {
2484 pHddCtx->isAmpAllowed = VOS_TRUE;
2485 hddLog(VOS_TRACE_LEVEL_FATAL,
2486 "%s: Failed to stop AMP", __func__);
2487 return -EINVAL;
2488 }
2489 }
2490#endif //WLAN_BTAMP_FEATURE
2491 /* Reset the current device mode bit mask*/
2492 wlan_hdd_clear_concurrency_mode(pHddCtx, pAdapter->device_mode);
2493
2494 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -07002495 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnsone7245742012-09-05 17:12:55 -07002496 || (pAdapter->device_mode == WLAN_HDD_P2P_DEVICE)
Jeff Johnson295189b2012-06-20 16:38:30 -07002497 )
2498 {
2499 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
2500 pRoamProfile = &pWextState->roamProfile;
2501 LastBSSType = pRoamProfile->BSSType;
2502
2503 switch (type)
2504 {
2505 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -07002506 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -07002507 hddLog(VOS_TRACE_LEVEL_INFO,
2508 "%s: setting interface Type to INFRASTRUCTURE", __func__);
2509 pRoamProfile->BSSType = eCSR_BSS_TYPE_INFRASTRUCTURE;
Jeff Johnsone7245742012-09-05 17:12:55 -07002510#ifdef WLAN_FEATURE_11AC
2511 if(pConfig->dot11Mode == eHDD_DOT11_MODE_AUTO)
2512 {
2513 pConfig->dot11Mode = eHDD_DOT11_MODE_11ac;
2514 }
2515#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302516 pRoamProfile->phyMode =
Jeff Johnsone7245742012-09-05 17:12:55 -07002517 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07002518 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08002519 //Check for sub-string p2p to confirm its a p2p interface
2520 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302521 {
Gopichand Nakkala864d3552012-12-31 16:08:51 -08002522 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
2523 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
2524 }
2525 else
2526 {
2527 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -07002528 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -08002529 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002530 break;
2531 case NL80211_IFTYPE_ADHOC:
2532 hddLog(VOS_TRACE_LEVEL_INFO,
2533 "%s: setting interface Type to ADHOC", __func__);
2534 pRoamProfile->BSSType = eCSR_BSS_TYPE_START_IBSS;
2535 pRoamProfile->phyMode =
2536 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Shailender Karmuchia734f332013-04-19 14:02:48 -07002537 pAdapter->device_mode = WLAN_HDD_IBSS;
Jeff Johnson295189b2012-06-20 16:38:30 -07002538 wdev->iftype = type;
2539 break;
2540
2541 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -07002542 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07002543 {
2544 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
2545 "%s: setting interface Type to %s", __func__,
2546 (type == NL80211_IFTYPE_AP) ? "SoftAP" : "P2pGo");
2547
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08002548 //Cancel any remain on channel for GO mode
2549 if (NL80211_IFTYPE_P2P_GO == type)
2550 {
2551 wlan_hdd_cancel_existing_remain_on_channel(pAdapter);
2552 }
Mohit Khanna0f232092012-09-11 14:46:08 -07002553 if (NL80211_IFTYPE_AP == type)
2554 {
2555 /* As Loading WLAN Driver one interface being created for p2p device
2556 * address. This will take one HW STA and the max number of clients
2557 * that can connect to softAP will be reduced by one. so while changing
2558 * the interface type to NL80211_IFTYPE_AP (SoftAP) remove p2p0
2559 * interface as it is not required in SoftAP mode.
2560 */
2561
2562 // Get P2P Adapter
2563 pP2pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_DEVICE);
2564
2565 if (pP2pAdapter)
2566 {
2567 hdd_stop_adapter(pHddCtx, pP2pAdapter);
2568 hdd_deinit_adapter(pHddCtx, pP2pAdapter);
2569 hdd_close_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
2570 }
2571 }
2572
Jeff Johnson295189b2012-06-20 16:38:30 -07002573 //De-init the adapter.
2574 hdd_stop_adapter( pHddCtx, pAdapter );
2575 hdd_deinit_adapter( pHddCtx, pAdapter );
2576 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
Jeff Johnson295189b2012-06-20 16:38:30 -07002577 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
2578 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Jeff Johnson32d95a32012-09-10 13:15:23 -07002579
2580 //Disable BMPS and IMPS if enabled
2581 //before starting Go
2582 if(WLAN_HDD_P2P_GO == pAdapter->device_mode)
2583 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302584 if(VOS_STATUS_E_FAILURE ==
Jeff Johnson32d95a32012-09-10 13:15:23 -07002585 hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_P2P_GO))
2586 {
2587 //Fail to Exit BMPS
2588 VOS_ASSERT(0);
2589 }
2590 }
2591
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -07002592 if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) &&
2593 (pConfig->apRandomBssidEnabled))
2594 {
2595 /* To meet Android requirements create a randomized
2596 MAC address of the form 02:1A:11:Fx:xx:xx */
2597 get_random_bytes(&ndev->dev_addr[3], 3);
2598 ndev->dev_addr[0] = 0x02;
2599 ndev->dev_addr[1] = 0x1A;
2600 ndev->dev_addr[2] = 0x11;
2601 ndev->dev_addr[3] |= 0xF0;
2602 memcpy(pAdapter->macAddressCurrent.bytes, ndev->dev_addr,
2603 VOS_MAC_ADDR_SIZE);
2604 pr_info("wlan: Generated HotSpot BSSID "
2605 "%02x:%02x:%02x:%02x:%02x:%02x\n",
2606 ndev->dev_addr[0],
2607 ndev->dev_addr[1],
2608 ndev->dev_addr[2],
2609 ndev->dev_addr[3],
2610 ndev->dev_addr[4],
2611 ndev->dev_addr[5]);
2612 }
2613
Jeff Johnson295189b2012-06-20 16:38:30 -07002614 hdd_set_ap_ops( pAdapter->dev );
2615
2616 status = hdd_init_ap_mode(pAdapter);
2617 if(status != VOS_STATUS_SUCCESS)
2618 {
2619 hddLog(VOS_TRACE_LEVEL_FATAL,
2620 "%s: Error initializing the ap mode", __func__);
2621 return -EINVAL;
2622 }
2623 hdd_set_conparam(1);
2624
Jeff Johnson295189b2012-06-20 16:38:30 -07002625 /*interface type changed update in wiphy structure*/
2626 if(wdev)
2627 {
2628 wdev->iftype = type;
2629 pHddCtx->change_iface = type;
2630 }
2631 else
2632 {
2633 hddLog(VOS_TRACE_LEVEL_ERROR,
2634 "%s: ERROR !!!! Wireless dev is NULL", __func__);
2635 return -EINVAL;
2636 }
2637 goto done;
2638 }
2639
2640 default:
2641 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
2642 __func__);
2643 return -EOPNOTSUPP;
2644 }
2645 }
2646 else if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07002647 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07002648 )
2649 {
2650 switch(type)
2651 {
2652 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -07002653 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -07002654 case NL80211_IFTYPE_ADHOC:
Jeff Johnson32d95a32012-09-10 13:15:23 -07002655 hdd_stop_adapter( pHddCtx, pAdapter );
2656 hdd_deinit_adapter( pHddCtx, pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07002657 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08002658 //Check for sub-string p2p to confirm its a p2p interface
2659 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala864d3552012-12-31 16:08:51 -08002660 {
2661 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
2662 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
2663 }
2664 else
2665 {
2666 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -07002667 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -08002668 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002669 hdd_set_conparam(0);
2670 pHddCtx->change_iface = type;
Jeff Johnson295189b2012-06-20 16:38:30 -07002671 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
2672 hdd_set_station_ops( pAdapter->dev );
2673 status = hdd_init_station_mode( pAdapter );
2674 if( VOS_STATUS_SUCCESS != status )
2675 return -EOPNOTSUPP;
Jeff Johnsone7245742012-09-05 17:12:55 -07002676 /* In case of JB, for P2P-GO, only change interface will be called,
2677 * This is the right place to enable back bmps_imps()
2678 */
2679 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07002680 goto done;
2681 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -07002682 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07002683 wdev->iftype = type;
Jeff Johnson295189b2012-06-20 16:38:30 -07002684 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
2685 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Jeff Johnson295189b2012-06-20 16:38:30 -07002686 goto done;
2687 default:
2688 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
2689 __func__);
2690 return -EOPNOTSUPP;
2691
2692 }
2693
2694 }
2695 else
2696 {
2697 return -EOPNOTSUPP;
2698 }
2699
2700
2701 if(pRoamProfile)
2702 {
2703 if ( LastBSSType != pRoamProfile->BSSType )
2704 {
2705 /*interface type changed update in wiphy structure*/
2706 wdev->iftype = type;
2707
2708 /*the BSS mode changed, We need to issue disconnect
2709 if connected or in IBSS disconnect state*/
2710 if ( hdd_connGetConnectedBssType(
2711 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), &connectedBssType ) ||
2712 ( eCSR_BSS_TYPE_START_IBSS == LastBSSType ) )
2713 {
2714 /*need to issue a disconnect to CSR.*/
2715 INIT_COMPLETION(pAdapter->disconnect_comp_var);
2716 if( eHAL_STATUS_SUCCESS ==
2717 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
2718 pAdapter->sessionId,
2719 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
2720 {
2721 wait_for_completion_interruptible_timeout(
2722 &pAdapter->disconnect_comp_var,
2723 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
2724 }
2725 }
2726 }
2727 }
2728
2729done:
2730 /*set bitmask based on updated value*/
2731 wlan_hdd_set_concurrency_mode(pHddCtx, pAdapter->device_mode);
2732#ifdef WLAN_BTAMP_FEATURE
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302733 if((NL80211_IFTYPE_STATION == type) && (pHddCtx->concurrency_mode <= 1) &&
Jeff Johnson295189b2012-06-20 16:38:30 -07002734 (pHddCtx->no_of_sessions[WLAN_HDD_INFRA_STATION] <=1))
2735 {
2736 //we are ok to do AMP
2737 pHddCtx->isAmpAllowed = VOS_TRUE;
2738 }
2739#endif //WLAN_BTAMP_FEATURE
2740 EXIT();
2741 return 0;
2742}
2743
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002744#ifdef FEATURE_WLAN_TDLS
2745static int wlan_hdd_tdls_add_station(struct wiphy *wiphy,
2746 struct net_device *dev, u8 *mac, bool update, tCsrStaParams *StaParams)
2747{
2748 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2749 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
2750 VOS_STATUS status;
Hoonki Lee5305c3a2013-04-29 23:28:59 -07002751 hddTdlsPeer_t *pTdlsPeer;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002752
2753 ENTER();
2754
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05302755 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002756 {
2757 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2758 "Invalid arguments");
2759 return -EINVAL;
2760 }
Hoonki Lee27511902013-03-14 18:19:06 -07002761
2762 if ((eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode) ||
2763 (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode))
2764 {
2765 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2766 "%s: TDLS mode is disabled OR not enabled in FW."
2767 MAC_ADDRESS_STR " Request declined.",
2768 __func__, MAC_ADDR_ARRAY(mac));
2769 return -ENOTSUPP;
2770 }
2771
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002772 if (pHddCtx->isLogpInProgress)
2773 {
2774 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2775 "%s:LOGP in Progress. Ignore!!!", __func__);
Gopichand Nakkala05922802013-03-14 12:23:19 -07002776 wlan_hdd_tdls_set_link_status(pAdapter, mac, eTDLS_LINK_IDLE);
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002777 return -EBUSY;
2778 }
2779
Hoonki Lee5305c3a2013-04-29 23:28:59 -07002780 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, mac);
2781
2782 if ( NULL == pTdlsPeer ) {
2783 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2784 "%s: " MAC_ADDRESS_STR " (update %d) not exist. return invalid",
2785 __func__, MAC_ADDR_ARRAY(mac), update);
2786 return -EINVAL;
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07002787 }
Hoonki Lee5305c3a2013-04-29 23:28:59 -07002788
2789 /* in add station, we accept existing valid staId if there is */
2790 if ((0 == update) &&
2791 ((pTdlsPeer->link_status >= eTDLS_LINK_CONNECTING) ||
2792 (TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07002793 {
Hoonki Lee5305c3a2013-04-29 23:28:59 -07002794 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07002795 "%s: " MAC_ADDRESS_STR
Hoonki Lee5305c3a2013-04-29 23:28:59 -07002796 " link_status %d. staId %d. add station ignored.",
2797 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, pTdlsPeer->staId);
2798 return 0;
2799 }
2800 /* in change station, we accept only when staId is valid */
2801 if ((1 == update) &&
2802 ((pTdlsPeer->link_status > eTDLS_LINK_CONNECTING) ||
2803 (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
2804 {
2805 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2806 "%s: " MAC_ADDRESS_STR
2807 " link status %d. staId %d. change station %s.",
2808 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, pTdlsPeer->staId,
2809 (TDLS_STA_INDEX_VALID(pTdlsPeer->staId)) ? "ignored" : "declined");
2810 return (TDLS_STA_INDEX_VALID(pTdlsPeer->staId)) ? 0 : -EPERM;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07002811 }
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07002812
2813 /* when others are on-going, we want to change link_status to idle */
Hoonki Leefb8df672013-04-10 18:20:34 -07002814 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, mac, TRUE, TRUE))
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002815 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07002816 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2817 "%s: " MAC_ADDRESS_STR
2818 " TDLS setup is ongoing. Request declined.",
2819 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala05922802013-03-14 12:23:19 -07002820 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002821 }
2822
2823 /* first to check if we reached to maximum supported TDLS peer.
2824 TODO: for now, return -EPERM looks working fine,
2825 but need to check if any other errno fit into this category.*/
2826 if (HDD_MAX_NUM_TDLS_STA <= wlan_hdd_tdlsConnectedPeers(pAdapter))
2827 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07002828 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2829 "%s: " MAC_ADDRESS_STR
2830 " TDLS Max peer already connected. Request declined.",
2831 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala05922802013-03-14 12:23:19 -07002832 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002833 }
2834 else
2835 {
2836 hddTdlsPeer_t *pTdlsPeer;
2837 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, mac);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07002838 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002839 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07002840 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2841 "%s: " MAC_ADDRESS_STR " already connected. Request declined.",
2842 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002843 return -EPERM;
2844 }
2845 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07002846 if (0 == update)
2847 wlan_hdd_tdls_set_link_status(pAdapter, mac, eTDLS_LINK_CONNECTING);
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002848
Jeff Johnsond75fe012013-04-06 10:53:06 -07002849 /* debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05302850 if (NULL != StaParams)
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07002851 {
2852 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2853 "%s: TDLS Peer Parameters.", __func__);
Hoonki Lee66b75f32013-04-16 18:30:07 -07002854 if(StaParams->htcap_present)
2855 {
2856 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2857 "ht_capa->cap_info: %0x", StaParams->HTCap.capInfo);
2858 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2859 "ht_capa->extended_capabilities: %0x",
2860 StaParams->HTCap.extendedHtCapInfo);
2861 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07002862 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2863 "params->capability: %0x",StaParams->capability);
2864 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2865 "params->ext_capab_len: %0x",StaParams->extn_capability);
Hoonki Lee66b75f32013-04-16 18:30:07 -07002866 if(StaParams->vhtcap_present)
2867 {
2868 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2869 "rxMcsMap %x rxHighest %x txMcsMap %x txHighest %x",
2870 StaParams->VHTCap.suppMcs.rxMcsMap, StaParams->VHTCap.suppMcs.rxHighest,
2871 StaParams->VHTCap.suppMcs.txMcsMap, StaParams->VHTCap.suppMcs.txHighest);
2872 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07002873 {
2874 int i = 0;
Hoonki Lee5305c3a2013-04-29 23:28:59 -07002875 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "Supported rates:");
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07002876 for (i = 0; i < sizeof(StaParams->supported_rates); i++)
2877 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2878 "[%d]: %x ", i, StaParams->supported_rates[i]);
2879 }
Jeff Johnsond75fe012013-04-06 10:53:06 -07002880 } /* end debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05302881 else if ((1 == update) && (NULL == StaParams))
2882 {
2883 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2884 "%s : update is true, but staParams is NULL. Error!", __func__);
2885 return -EPERM;
2886 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002887
2888 INIT_COMPLETION(pAdapter->tdls_add_station_comp);
2889
2890 if (!update)
2891 {
2892 status = sme_AddTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
2893 pAdapter->sessionId, mac);
2894 }
2895 else
2896 {
2897 status = sme_ChangeTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
2898 pAdapter->sessionId, mac, StaParams);
2899 }
2900
2901 status = wait_for_completion_interruptible_timeout(&pAdapter->tdls_add_station_comp,
2902 msecs_to_jiffies(WAIT_TIME_TDLS_ADD_STA));
2903
2904 if (!status)
2905 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07002906 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002907 "%s: timeout waiting for tdls add station indication",
2908 __func__);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07002909 return -EPERM;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002910 }
2911 if ( eHAL_STATUS_SUCCESS != pAdapter->tdlsAddStaStatus)
2912 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07002913 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002914 "%s: Add Station is unsucessful", __func__);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07002915 return -EPERM;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002916 }
2917
2918 return 0;
Gopichand Nakkala05922802013-03-14 12:23:19 -07002919
2920error:
2921 wlan_hdd_tdls_set_link_status(pAdapter, mac, eTDLS_LINK_IDLE);
2922 return -EPERM;
2923
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002924}
2925#endif
2926
Jeff Johnson295189b2012-06-20 16:38:30 -07002927static int wlan_hdd_change_station(struct wiphy *wiphy,
2928 struct net_device *dev,
2929 u8 *mac,
2930 struct station_parameters *params)
2931{
2932 VOS_STATUS status = VOS_STATUS_SUCCESS;
2933 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Gopichand Nakkala29149562013-05-10 21:43:41 +05302934 hdd_context_t *pHddCtx;
2935 hdd_station_ctx_t *pHddStaCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07002936 v_MACADDR_t STAMacAddress;
Gopichand Nakkalab0856222013-03-12 22:39:05 -07002937#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002938 tCsrStaParams StaParams = {0};
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002939 tANI_U8 isBufSta = 0;
Gopichand Nakkalab0856222013-03-12 22:39:05 -07002940#endif
Jeff Johnsone7245742012-09-05 17:12:55 -07002941 ENTER();
2942
Gopichand Nakkala29149562013-05-10 21:43:41 +05302943 if ((NULL == pAdapter))
2944 {
2945 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
2946 "invalid adapter ");
2947 return -EINVAL;
2948 }
2949
2950 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2951 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
2952
2953 if ((NULL == pHddCtx) || (NULL == pHddStaCtx))
2954 {
2955 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
2956 "invalid HDD state or HDD station context");
2957 return -EINVAL;
2958 }
2959
2960 if (pHddCtx->isLogpInProgress)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002961 {
2962 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2963 "%s:LOGP in Progress. Ignore!!!", __func__);
2964 return -EAGAIN;
2965 }
2966
Jeff Johnson295189b2012-06-20 16:38:30 -07002967 vos_mem_copy(STAMacAddress.bytes, mac, sizeof(v_MACADDR_t));
2968
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002969 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
2970 || (pAdapter->device_mode == WLAN_HDD_P2P_GO))
Jeff Johnson295189b2012-06-20 16:38:30 -07002971 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002972 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED))
Jeff Johnson295189b2012-06-20 16:38:30 -07002973 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302974 status = hdd_softap_change_STA_state( pAdapter, &STAMacAddress,
Jeff Johnson295189b2012-06-20 16:38:30 -07002975 WLANTL_STA_AUTHENTICATED);
2976
Gopichand Nakkala29149562013-05-10 21:43:41 +05302977 if (status != VOS_STATUS_SUCCESS)
2978 {
2979 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2980 "%s: Not able to change TL state to AUTHENTICATED", __func__);
2981 return -EINVAL;
2982 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002983 }
2984 }
Hoonki Leea6d49be2013-04-05 09:43:25 -07002985 else if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
2986 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)) {
Gopichand Nakkala29149562013-05-10 21:43:41 +05302987#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07002988 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
2989 StaParams.capability = params->capability;
2990 StaParams.uapsd_queues = params->uapsd_queues;
2991 StaParams.max_sp = params->max_sp;
2992
2993 if (0 != params->ext_capab_len)
2994 vos_mem_copy(StaParams.extn_capability, params->ext_capab,
2995 sizeof(StaParams.extn_capability));
2996
2997 if (NULL != params->ht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -07002998 {
2999 StaParams.htcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003000 vos_mem_copy(&StaParams.HTCap, params->ht_capa, sizeof(tSirHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -07003001 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003002
3003 StaParams.supported_rates_len = params->supported_rates_len;
3004
3005 /* Note : The Maximum sizeof supported_rates sent by the Supplicant is 32.
3006 * The supported_rates array , for all the structures propogating till Add Sta
3007 * to the firmware has to be modified , if the supplicant (ieee80211) is
3008 * modified to send more rates.
3009 */
3010
3011 /* To avoid Data Currption , set to max length to SIR_MAC_MAX_SUPP_RATES
3012 */
3013 if (StaParams.supported_rates_len > SIR_MAC_MAX_SUPP_RATES)
3014 StaParams.supported_rates_len = SIR_MAC_MAX_SUPP_RATES;
3015
3016 if (0 != StaParams.supported_rates_len) {
3017 int i = 0;
3018 vos_mem_copy(StaParams.supported_rates, params->supported_rates,
3019 StaParams.supported_rates_len);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07003020 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003021 "Supported Rates with Length %d", StaParams.supported_rates_len);
3022 for (i=0; i < StaParams.supported_rates_len; i++)
Hoonki Lee5305c3a2013-04-29 23:28:59 -07003023 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003024 "[%d]: %0x", i, StaParams.supported_rates[i]);
3025 }
3026
3027 if (NULL != params->vht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -07003028 {
3029 StaParams.vhtcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003030 vos_mem_copy(&StaParams.VHTCap, params->vht_capa, sizeof(tSirVHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -07003031 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003032
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003033 if (0 != params->ext_capab_len ) {
3034 /*Define A Macro : TODO Sunil*/
3035 if ((1<<4) & StaParams.extn_capability[3]) {
3036 isBufSta = 1;
3037 }
3038 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003039 //status = wlan_hdd_tdls_set_peer_caps( mac, params->uapsd_queues,
3040 // params->max_sp, isBufSta);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003041 //if (VOS_STATUS_SUCCESS != status) {
3042 // VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3043 // "%s: wlan_hdd_tdls_set_peer_caps failed!", __func__);
3044 // return -EINVAL;
3045 //}
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003046 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 1, &StaParams);
3047
3048 if (VOS_STATUS_SUCCESS != status) {
3049 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3050 "%s: sme_ChangeTdlsPeerSta failed!", __func__);
3051 return -EINVAL;
3052 }
3053 }
Gopichand Nakkalab0856222013-03-12 22:39:05 -07003054#endif
Gopichand Nakkala29149562013-05-10 21:43:41 +05303055 if(params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED))
3056 {
3057 status = WLANTL_ChangeSTAState(pHddCtx->pvosContext, pHddStaCtx->conn_info.staId[ 0 ],
3058 WLANTL_STA_AUTHENTICATED);
3059 if (status != VOS_STATUS_SUCCESS)
3060 {
3061 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
3062 "%s: Not able to change TL state to AUTHENTICATED", __func__);
3063 return -EINVAL;
3064 }
3065 pHddStaCtx->conn_info.uIsAuthenticated = VOS_TRUE;
3066 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3067 "%s: TL Moving to Authenticated state", __func__);
3068 }
3069 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303070
Jeff Johnsone7245742012-09-05 17:12:55 -07003071 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07003072 return status;
3073}
3074
3075/*
Jeff Johnson295189b2012-06-20 16:38:30 -07003076 * FUNCTION: wlan_hdd_cfg80211_add_key
3077 * This function is used to initialize the key information
3078 */
3079#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003080static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07003081 struct net_device *ndev,
3082 u8 key_index, bool pairwise,
3083 const u8 *mac_addr,
3084 struct key_params *params
3085 )
3086#else
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003087static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07003088 struct net_device *ndev,
3089 u8 key_index, const u8 *mac_addr,
3090 struct key_params *params
3091 )
3092#endif
3093{
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003094 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -07003095 tCsrRoamSetKey setKey;
3096 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05303097 int status;
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003098 v_U32_t roamId= 0xFF;
3099 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07003100 hdd_hostapd_state_t *pHostapdState;
3101 VOS_STATUS vos_status;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07003102 eHalStatus halStatus;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05303103 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07003104
3105 ENTER();
3106
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05303107 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
3108 status = wlan_hdd_validate_context(pHddCtx);
3109
3110 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07003111 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05303112 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3113 "%s: HDD context is not valid", __func__);
3114 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07003115 }
3116
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003117 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
3118 __func__, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07003119
3120 if (CSR_MAX_NUM_KEY <= key_index)
3121 {
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003122 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07003123 key_index);
3124
3125 return -EINVAL;
3126 }
3127
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003128 if (CSR_MAX_KEY_LEN < params->key_len)
3129 {
3130 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key length %d", __func__,
3131 params->key_len);
3132
3133 return -EINVAL;
3134 }
3135
3136 hddLog(VOS_TRACE_LEVEL_INFO,
3137 "%s: called with key index = %d & key length %d",
3138 __func__, key_index, params->key_len);
Jeff Johnson295189b2012-06-20 16:38:30 -07003139
3140 /*extract key idx, key len and key*/
3141 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
3142 setKey.keyId = key_index;
3143 setKey.keyLength = params->key_len;
3144 vos_mem_copy(&setKey.Key[0],params->key, params->key_len);
3145
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003146 switch (params->cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -07003147 {
3148 case WLAN_CIPHER_SUITE_WEP40:
3149 setKey.encType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
3150 break;
3151
3152 case WLAN_CIPHER_SUITE_WEP104:
3153 setKey.encType = eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
3154 break;
3155
3156 case WLAN_CIPHER_SUITE_TKIP:
3157 {
3158 u8 *pKey = &setKey.Key[0];
3159 setKey.encType = eCSR_ENCRYPT_TYPE_TKIP;
3160
3161 vos_mem_zero(pKey, CSR_MAX_KEY_LEN);
3162
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003163 /*Supplicant sends the 32bytes key in this order
Jeff Johnson295189b2012-06-20 16:38:30 -07003164
3165 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003166 | Tk1 |TX-MIC | RX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -07003167 |--------------|----------|----------|
3168 <---16bytes---><--8bytes--><--8bytes-->
3169
3170 */
3171 /*Sme expects the 32 bytes key to be in the below order
3172
3173 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003174 | Tk1 |RX-MIC | TX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -07003175 |--------------|----------|----------|
3176 <---16bytes---><--8bytes--><--8bytes-->
3177 */
3178 /* Copy the Temporal Key 1 (TK1) */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003179 vos_mem_copy(pKey, params->key, 16);
Jeff Johnson295189b2012-06-20 16:38:30 -07003180
3181 /*Copy the rx mic first*/
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003182 vos_mem_copy(&pKey[16], &params->key[24], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -07003183
3184 /*Copy the tx mic */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003185 vos_mem_copy(&pKey[24], &params->key[16], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -07003186
3187
3188 break;
3189 }
3190
3191 case WLAN_CIPHER_SUITE_CCMP:
3192 setKey.encType = eCSR_ENCRYPT_TYPE_AES;
3193 break;
3194
3195#ifdef FEATURE_WLAN_WAPI
3196 case WLAN_CIPHER_SUITE_SMS4:
3197 {
3198 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
3199 wlan_hdd_cfg80211_set_key_wapi(pAdapter, key_index, mac_addr,
3200 params->key, params->key_len);
3201 return 0;
3202 }
3203#endif
Chet Lanctot186b5732013-03-18 10:26:30 -07003204
Jeff Johnson295189b2012-06-20 16:38:30 -07003205#ifdef FEATURE_WLAN_CCX
3206 case WLAN_CIPHER_SUITE_KRK:
3207 setKey.encType = eCSR_ENCRYPT_TYPE_KRK;
3208 break;
3209#endif
Chet Lanctot186b5732013-03-18 10:26:30 -07003210
3211#ifdef WLAN_FEATURE_11W
3212 case WLAN_CIPHER_SUITE_AES_CMAC:
3213 setKey.encType = eCSR_ENCRYPT_TYPE_AES_CMAC;
Chet Lanctot3b5158a2013-03-31 16:45:21 -07003214 break;
Chet Lanctot186b5732013-03-18 10:26:30 -07003215#endif
3216
Jeff Johnson295189b2012-06-20 16:38:30 -07003217 default:
3218 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unsupported cipher type %lu",
3219 __func__, params->cipher);
3220 return -EOPNOTSUPP;
3221 }
3222
3223 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: encryption type %d",
3224 __func__, setKey.encType);
3225
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003226 if (
Jeff Johnson295189b2012-06-20 16:38:30 -07003227#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
3228 (!pairwise)
3229#else
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003230 (!mac_addr || is_broadcast_ether_addr(mac_addr))
Jeff Johnson295189b2012-06-20 16:38:30 -07003231#endif
3232 )
3233 {
3234 /* set group key*/
3235 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnson1250df42012-12-10 14:31:52 -08003236 "%s- %d: setting Broadcast key",
Jeff Johnson295189b2012-06-20 16:38:30 -07003237 __func__, __LINE__);
3238 setKey.keyDirection = eSIR_RX_ONLY;
3239 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
3240 }
3241 else
3242 {
3243 /* set pairwise key*/
3244 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3245 "%s- %d: setting pairwise key",
3246 __func__, __LINE__);
3247 setKey.keyDirection = eSIR_TX_RX;
3248 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
3249 }
3250
Gopichand Nakkala29149562013-05-10 21:43:41 +05303251 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP) ||
3252 (pAdapter->device_mode == WLAN_HDD_P2P_GO))
3253 {
Jeff Johnson295189b2012-06-20 16:38:30 -07003254 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003255 if( pHostapdState->bssState == BSS_START )
3256 {
Jeff Johnson295189b2012-06-20 16:38:30 -07003257 status = WLANSAP_SetKeySta( pVosContext, &setKey);
3258
3259 if ( status != eHAL_STATUS_SUCCESS )
3260 {
3261 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3262 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
3263 __LINE__, status );
3264 }
3265 }
3266
3267 /* Saving WEP keys */
3268 else if( eCSR_ENCRYPT_TYPE_WEP40_STATICKEY == setKey.encType ||
3269 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY == setKey.encType )
3270 {
3271 //Save the wep key in ap context. Issue setkey after the BSS is started.
3272 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
3273 vos_mem_copy(&pAPCtx->wepKey[key_index], &setKey, sizeof(tCsrRoamSetKey));
3274 }
3275 else
3276 {
3277 //Save the key in ap context. Issue setkey after the BSS is started.
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003278 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07003279 vos_mem_copy(&pAPCtx->groupKey, &setKey, sizeof(tCsrRoamSetKey));
3280 }
3281 }
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003282 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION) ||
3283 (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT) )
Jeff Johnson295189b2012-06-20 16:38:30 -07003284 {
3285 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
3286 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3287
Gopichand Nakkala3d295922013-05-07 16:19:14 +05303288#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
3289 if (!pairwise)
3290#else
3291 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
3292#endif
3293 {
3294 /* set group key*/
3295 if (pHddStaCtx->roam_info.deferKeyComplete)
3296 {
3297 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3298 "%s- %d: Perform Set key Complete",
3299 __func__, __LINE__);
3300 hdd_PerformRoamSetKeyComplete(pAdapter);
3301 }
3302 }
3303
Jeff Johnson295189b2012-06-20 16:38:30 -07003304 pWextState->roamProfile.Keys.KeyLength[key_index] = (u8)params->key_len;
3305
Venkata Prathyusha Kuntupalliee2ce712013-01-17 14:09:24 -08003306 pWextState->roamProfile.Keys.defaultIndex = key_index;
3307
3308
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003309 vos_mem_copy(&pWextState->roamProfile.Keys.KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -07003310 params->key, params->key_len);
3311
Gopichand Nakkala3d295922013-05-07 16:19:14 +05303312
Jeff Johnson295189b2012-06-20 16:38:30 -07003313 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
3314
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303315 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -07003316 "%s: set key for peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303317 __func__, setKey.peerMac[0], setKey.peerMac[1],
3318 setKey.peerMac[2], setKey.peerMac[3],
3319 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -07003320 setKey.keyDirection);
3321
3322 vos_status = wlan_hdd_check_ula_done(pAdapter);
3323
3324 if ( vos_status != VOS_STATUS_SUCCESS )
3325 {
3326 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3327 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
3328 __LINE__, vos_status );
3329
3330 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
3331
3332 return -EINVAL;
3333
3334 }
3335
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07003336#ifdef WLAN_FEATURE_VOWIFI_11R
Gopichand Nakkala3d295922013-05-07 16:19:14 +05303337 /* The supplicant may attempt to set the PTK once pre-authentication
3338 is done. Save the key in the UMAC and include it in the ADD BSS
3339 request */
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07003340 halStatus = sme_FTUpdateKey( WLAN_HDD_GET_HAL_CTX(pAdapter), &setKey);
Gopichand Nakkala3d295922013-05-07 16:19:14 +05303341 if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_SUCCESS )
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07003342 {
Gopichand Nakkala3d295922013-05-07 16:19:14 +05303343 hddLog(VOS_TRACE_LEVEL_INFO_MED,
3344 "%s: Update PreAuth Key success", __func__);
3345 return 0;
3346 }
3347 else if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_FAILED )
3348 {
3349 hddLog(VOS_TRACE_LEVEL_ERROR,
3350 "%s: Update PreAuth Key failed", __func__);
Gopichand Nakkalad7d13652013-02-15 01:48:00 +05303351 return -EINVAL;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07003352 }
3353#endif /* WLAN_FEATURE_VOWIFI_11R */
Jeff Johnson295189b2012-06-20 16:38:30 -07003354
3355 /* issue set key request to SME*/
3356 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
3357 pAdapter->sessionId, &setKey, &roamId );
3358
3359 if ( 0 != status )
3360 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303361 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07003362 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
3363 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
3364 return -EINVAL;
3365 }
3366
3367
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303368 /* in case of IBSS as there was no information available about WEP keys during
3369 * IBSS join, group key intialized with NULL key, so re-initialize group key
Jeff Johnson295189b2012-06-20 16:38:30 -07003370 * with correct value*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303371 if ( (eCSR_BSS_TYPE_START_IBSS == pWextState->roamProfile.BSSType) &&
3372 !( ( IW_AUTH_KEY_MGMT_802_1X
3373 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X))
Jeff Johnson295189b2012-06-20 16:38:30 -07003374 && (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType)
3375 )
3376 &&
3377 ( (WLAN_CIPHER_SUITE_WEP40 == params->cipher)
3378 || (WLAN_CIPHER_SUITE_WEP104 == params->cipher)
3379 )
3380 )
3381 {
3382 setKey.keyDirection = eSIR_RX_ONLY;
3383 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
3384
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303385 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -07003386 "%s: set key peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303387 __func__, setKey.peerMac[0], setKey.peerMac[1],
3388 setKey.peerMac[2], setKey.peerMac[3],
3389 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -07003390 setKey.keyDirection);
3391
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303392 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07003393 pAdapter->sessionId, &setKey, &roamId );
3394
3395 if ( 0 != status )
3396 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303397 hddLog(VOS_TRACE_LEVEL_ERROR,
3398 "%s: sme_RoamSetKey failed for group key (IBSS), returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07003399 __func__, status);
3400 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
3401 return -EINVAL;
3402 }
3403 }
3404 }
3405
3406 return 0;
3407}
3408
3409/*
3410 * FUNCTION: wlan_hdd_cfg80211_get_key
3411 * This function is used to get the key information
3412 */
3413#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303414static int wlan_hdd_cfg80211_get_key(
3415 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07003416 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303417 u8 key_index, bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -07003418 const u8 *mac_addr, void *cookie,
3419 void (*callback)(void *cookie, struct key_params*)
3420 )
3421#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303422static int wlan_hdd_cfg80211_get_key(
3423 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07003424 struct net_device *ndev,
3425 u8 key_index, const u8 *mac_addr, void *cookie,
3426 void (*callback)(void *cookie, struct key_params*)
3427 )
3428#endif
3429{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303430 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -07003431 hdd_wext_state_t *pWextState= WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
3432 tCsrRoamProfile *pRoamProfile = &(pWextState->roamProfile);
3433 struct key_params params;
3434
3435 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303436
Jeff Johnson295189b2012-06-20 16:38:30 -07003437 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",
3438 __func__,pAdapter->device_mode);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303439
Jeff Johnson295189b2012-06-20 16:38:30 -07003440 memset(&params, 0, sizeof(params));
3441
3442 if (CSR_MAX_NUM_KEY <= key_index)
3443 {
3444 return -EINVAL;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303445 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003446
3447 switch(pRoamProfile->EncryptionType.encryptionType[0])
3448 {
3449 case eCSR_ENCRYPT_TYPE_NONE:
3450 params.cipher = IW_AUTH_CIPHER_NONE;
3451 break;
3452
3453 case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY:
3454 case eCSR_ENCRYPT_TYPE_WEP40:
3455 params.cipher = WLAN_CIPHER_SUITE_WEP40;
3456 break;
3457
3458 case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY:
3459 case eCSR_ENCRYPT_TYPE_WEP104:
3460 params.cipher = WLAN_CIPHER_SUITE_WEP104;
3461 break;
3462
3463 case eCSR_ENCRYPT_TYPE_TKIP:
3464 params.cipher = WLAN_CIPHER_SUITE_TKIP;
3465 break;
3466
3467 case eCSR_ENCRYPT_TYPE_AES:
3468 params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
3469 break;
3470
3471 default:
3472 params.cipher = IW_AUTH_CIPHER_NONE;
3473 break;
3474 }
3475
3476 params.key_len = pRoamProfile->Keys.KeyLength[key_index];
3477 params.seq_len = 0;
3478 params.seq = NULL;
3479 params.key = &pRoamProfile->Keys.KeyMaterial[key_index][0];
3480 callback(cookie, &params);
3481 return 0;
3482}
3483
3484/*
3485 * FUNCTION: wlan_hdd_cfg80211_del_key
3486 * This function is used to delete the key information
3487 */
3488#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303489static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07003490 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303491 u8 key_index,
3492 bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -07003493 const u8 *mac_addr
3494 )
3495#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303496static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07003497 struct net_device *ndev,
3498 u8 key_index,
3499 const u8 *mac_addr
3500 )
3501#endif
3502{
3503 int status = 0;
3504
3505 //This code needs to be revisited. There is sme_removeKey API, we should
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303506 //plan to use that. After the change to use correct index in setkey,
Jeff Johnson295189b2012-06-20 16:38:30 -07003507 //it is observed that this is invalidating peer
3508 //key index whenever re-key is done. This is affecting data link.
3509 //It should be ok to ignore del_key.
3510#if 0
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303511 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
3512 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07003513 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
3514 tCsrRoamSetKey setKey;
3515 v_U32_t roamId= 0xFF;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303516
Jeff Johnson295189b2012-06-20 16:38:30 -07003517 ENTER();
3518
3519 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device_mode = %d\n",
3520 __func__,pAdapter->device_mode);
3521
3522 if (CSR_MAX_NUM_KEY <= key_index)
3523 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303524 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07003525 key_index);
3526
3527 return -EINVAL;
3528 }
3529
3530 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
3531 setKey.keyId = key_index;
3532
3533 if (mac_addr)
3534 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
3535 else
3536 vos_mem_copy(setKey.peerMac, groupmacaddr, WNI_CFG_BSSID_LEN);
3537
3538 setKey.encType = eCSR_ENCRYPT_TYPE_NONE;
3539
3540 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07003541 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303542 )
3543 {
3544
3545 hdd_hostapd_state_t *pHostapdState =
Jeff Johnson295189b2012-06-20 16:38:30 -07003546 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
3547 if( pHostapdState->bssState == BSS_START)
3548 {
3549 status = WLANSAP_SetKeySta( pVosContext, &setKey);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303550
Jeff Johnson295189b2012-06-20 16:38:30 -07003551 if ( status != eHAL_STATUS_SUCCESS )
3552 {
3553 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3554 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
3555 __LINE__, status );
3556 }
3557 }
3558 }
3559 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303560 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnson295189b2012-06-20 16:38:30 -07003561 )
3562 {
3563 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3564
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303565 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
3566
3567 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -07003568 "%s: delete key for peerMac %2x:%2x:%2x:%2x:%2x:%2x",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303569 __func__, setKey.peerMac[0], setKey.peerMac[1],
3570 setKey.peerMac[2], setKey.peerMac[3],
Jeff Johnson295189b2012-06-20 16:38:30 -07003571 setKey.peerMac[4], setKey.peerMac[5]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303572 if(pAdapter->sessionCtx.station.conn_info.connState ==
3573 eConnectionState_Associated)
Jeff Johnson295189b2012-06-20 16:38:30 -07003574 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303575 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07003576 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303577
Jeff Johnson295189b2012-06-20 16:38:30 -07003578 if ( 0 != status )
3579 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303580 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07003581 "%s: sme_RoamSetKey failure, returned %d",
3582 __func__, status);
3583 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
3584 return -EINVAL;
3585 }
3586 }
3587 }
3588#endif
Jeff Johnsone7245742012-09-05 17:12:55 -07003589 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07003590 return status;
3591}
3592
3593/*
3594 * FUNCTION: wlan_hdd_cfg80211_set_default_key
3595 * This function is used to set the default tx key index
3596 */
3597#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
3598static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
3599 struct net_device *ndev,
3600 u8 key_index,
3601 bool unicast, bool multicast)
3602#else
3603static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
3604 struct net_device *ndev,
3605 u8 key_index)
3606#endif
3607{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303608 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05303609 int status;
Gopichand Nakkala29149562013-05-10 21:43:41 +05303610 hdd_wext_state_t *pWextState;
3611 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05303612 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07003613
3614 ENTER();
3615
Gopichand Nakkala29149562013-05-10 21:43:41 +05303616 if ((NULL == pAdapter))
3617 {
3618 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
3619 "invalid adapter");
3620 return -EINVAL;
3621 }
3622
3623 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
3624 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3625
3626 if ((NULL == pWextState) || (NULL == pHddStaCtx))
3627 {
3628 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
3629 "invalid Wext state or HDD context");
3630 return -EINVAL;
3631 }
3632
Jeff Johnson295189b2012-06-20 16:38:30 -07003633 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d key_index = %d \n",
3634 __func__,pAdapter->device_mode, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303635
Jeff Johnson295189b2012-06-20 16:38:30 -07003636 if (CSR_MAX_NUM_KEY <= key_index)
3637 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303638 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07003639 key_index);
3640
3641 return -EINVAL;
3642 }
3643
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05303644 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
3645 status = wlan_hdd_validate_context(pHddCtx);
3646
3647 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07003648 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05303649 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3650 "%s: HDD context is not valid", __func__);
3651 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07003652 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303653
Jeff Johnson295189b2012-06-20 16:38:30 -07003654 if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -07003655 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303656 )
Jeff Johnson295189b2012-06-20 16:38:30 -07003657 {
Gopichand Nakkala29149562013-05-10 21:43:41 +05303658 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
Jeff Johnson295189b2012-06-20 16:38:30 -07003659 pWextState->roamProfile.EncryptionType.encryptionType[0]) &&
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303660 (eCSR_ENCRYPT_TYPE_AES !=
Jeff Johnson295189b2012-06-20 16:38:30 -07003661 pWextState->roamProfile.EncryptionType.encryptionType[0])
3662 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303663 {
3664 /* if default key index is not same as previous one,
Jeff Johnson295189b2012-06-20 16:38:30 -07003665 * then update the default key index */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303666
Jeff Johnson295189b2012-06-20 16:38:30 -07003667 tCsrRoamSetKey setKey;
3668 v_U32_t roamId= 0xFF;
3669 tCsrKeys *Keys = &pWextState->roamProfile.Keys;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303670
3671 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: default tx key index %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07003672 __func__, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303673
Jeff Johnson295189b2012-06-20 16:38:30 -07003674 Keys->defaultIndex = (u8)key_index;
3675 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
3676 setKey.keyId = key_index;
3677 setKey.keyLength = Keys->KeyLength[key_index];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303678
3679 vos_mem_copy(&setKey.Key[0],
3680 &Keys->KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -07003681 Keys->KeyLength[key_index]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303682
Gopichand Nakkala29149562013-05-10 21:43:41 +05303683 setKey.keyDirection = eSIR_TX_RX;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303684
3685 vos_mem_copy(setKey.peerMac,
Jeff Johnson295189b2012-06-20 16:38:30 -07003686 &pHddStaCtx->conn_info.bssId[0],
3687 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303688
Gopichand Nakkala29149562013-05-10 21:43:41 +05303689 if (Keys->KeyLength[key_index] == CSR_WEP40_KEY_LEN &&
3690 pWextState->roamProfile.EncryptionType.encryptionType[0] ==
3691 eCSR_ENCRYPT_TYPE_WEP104)
3692 {
3693 /*In the case of dynamic wep supplicant hardcodes DWEP type to eCSR_ENCRYPT_TYPE_WEP104
3694 even though ap is configured for WEP-40 encryption. In this canse the key length
3695 is 5 but the encryption type is 104 hence checking the key langht(5) and encryption
3696 type(104) and switching encryption type to 40*/
3697 pWextState->roamProfile.EncryptionType.encryptionType[0] =
3698 eCSR_ENCRYPT_TYPE_WEP40;
3699 pWextState->roamProfile.mcEncryptionType.encryptionType[0] =
3700 eCSR_ENCRYPT_TYPE_WEP40;
3701 }
3702
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303703 setKey.encType =
Jeff Johnson295189b2012-06-20 16:38:30 -07003704 pWextState->roamProfile.EncryptionType.encryptionType[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303705
Jeff Johnson295189b2012-06-20 16:38:30 -07003706 /* issue set key request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303707 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07003708 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303709
Jeff Johnson295189b2012-06-20 16:38:30 -07003710 if ( 0 != status )
3711 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303712 hddLog(VOS_TRACE_LEVEL_ERROR,
3713 "%s: sme_RoamSetKey failed, returned %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07003714 status);
3715 return -EINVAL;
3716 }
3717 }
3718 }
3719
3720 /* In SoftAp mode setting key direction for default mode */
3721 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
3722 {
3723 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
3724 pWextState->roamProfile.EncryptionType.encryptionType[0]) &&
3725 (eCSR_ENCRYPT_TYPE_AES !=
3726 pWextState->roamProfile.EncryptionType.encryptionType[0])
3727 )
3728 {
3729 /* Saving key direction for default key index to TX default */
3730 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
3731 pAPCtx->wepKey[key_index].keyDirection = eSIR_TX_DEFAULT;
3732 }
3733 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303734
Jeff Johnson295189b2012-06-20 16:38:30 -07003735 return status;
3736}
3737
Jeff Johnson295189b2012-06-20 16:38:30 -07003738/*
3739 * FUNCTION: wlan_hdd_cfg80211_inform_bss
3740 * This function is used to inform the BSS details to nl80211 interface.
3741 */
3742static struct cfg80211_bss* wlan_hdd_cfg80211_inform_bss(
3743 hdd_adapter_t *pAdapter, tCsrRoamConnectedProfile *roamProfile)
3744{
3745 struct net_device *dev = pAdapter->dev;
3746 struct wireless_dev *wdev = dev->ieee80211_ptr;
3747 struct wiphy *wiphy = wdev->wiphy;
3748 tSirBssDescription *pBssDesc = roamProfile->pBssDesc;
3749 int chan_no;
3750 int ie_length;
3751 const char *ie;
3752 unsigned int freq;
3753 struct ieee80211_channel *chan;
3754 int rssi = 0;
3755 struct cfg80211_bss *bss = NULL;
3756
3757 ENTER();
3758
3759 if( NULL == pBssDesc )
3760 {
3761 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pBssDesc is NULL\n", __func__);
3762 return bss;
3763 }
3764
3765 chan_no = pBssDesc->channelId;
3766 ie_length = GET_IE_LEN_IN_BSS_DESC( pBssDesc->length );
3767 ie = ((ie_length != 0) ? (const char *)&pBssDesc->ieFields: NULL);
3768
3769 if( NULL == ie )
3770 {
3771 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: IE of BSS descriptor is NULL\n", __func__);
3772 return bss;
3773 }
3774
3775#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
3776 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
3777 {
3778 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
3779 }
3780 else
3781 {
3782 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
3783 }
3784#else
3785 freq = ieee80211_channel_to_frequency(chan_no);
3786#endif
3787
3788 chan = __ieee80211_get_channel(wiphy, freq);
3789
3790 bss = cfg80211_get_bss(wiphy, chan, pBssDesc->bssId,
3791 &roamProfile->SSID.ssId[0], roamProfile->SSID.length,
3792 WLAN_CAPABILITY_ESS, WLAN_CAPABILITY_ESS);
3793 if (bss == NULL)
3794 {
3795 rssi = (VOS_MIN ((pBssDesc->rssi + pBssDesc->sinr), 0))*100;
3796
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303797 return (cfg80211_inform_bss(wiphy, chan, pBssDesc->bssId,
3798 le64_to_cpu(*(__le64 *)pBssDesc->timeStamp),
Jeff Johnson295189b2012-06-20 16:38:30 -07003799 pBssDesc->capabilityInfo,
3800 pBssDesc->beaconInterval, ie, ie_length,
3801 rssi, GFP_KERNEL ));
3802}
3803 else
3804 {
3805 return bss;
3806 }
3807}
3808
3809
3810
3811/*
3812 * FUNCTION: wlan_hdd_cfg80211_inform_bss_frame
3813 * This function is used to inform the BSS details to nl80211 interface.
3814 */
3815struct cfg80211_bss*
3816wlan_hdd_cfg80211_inform_bss_frame( hdd_adapter_t *pAdapter,
3817 tSirBssDescription *bss_desc
3818 )
3819{
3820 /*
3821 cfg80211_inform_bss() is not updating ie field of bss entry, if entry
3822 already exists in bss data base of cfg80211 for that particular BSS ID.
3823 Using cfg80211_inform_bss_frame to update the bss entry instead of
3824 cfg80211_inform_bss, But this call expects mgmt packet as input. As of
3825 now there is no possibility to get the mgmt(probe response) frame from PE,
3826 converting bss_desc to ieee80211_mgmt(probe response) and passing to
3827 cfg80211_inform_bss_frame.
3828 */
3829 struct net_device *dev = pAdapter->dev;
3830 struct wireless_dev *wdev = dev->ieee80211_ptr;
3831 struct wiphy *wiphy = wdev->wiphy;
3832 int chan_no = bss_desc->channelId;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08003833#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
3834 qcom_ie_age *qie_age = NULL;
3835 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length ) + sizeof(qcom_ie_age);
3836#else
Jeff Johnson295189b2012-06-20 16:38:30 -07003837 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length );
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08003838#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07003839 const char *ie =
3840 ((ie_length != 0) ? (const char *)&bss_desc->ieFields: NULL);
3841 unsigned int freq;
3842 struct ieee80211_channel *chan;
3843 struct ieee80211_mgmt *mgmt =
3844 kzalloc((sizeof (struct ieee80211_mgmt) + ie_length), GFP_KERNEL);
3845 struct cfg80211_bss *bss_status = NULL;
3846 size_t frame_len = sizeof (struct ieee80211_mgmt) + ie_length;
3847 int rssi = 0;
Jeff Johnsone7245742012-09-05 17:12:55 -07003848#ifdef WLAN_OPEN_SOURCE
3849 struct timespec ts;
3850#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07003851
3852 ENTER();
3853
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -07003854 if (!mgmt)
3855 return NULL;
3856
Jeff Johnson295189b2012-06-20 16:38:30 -07003857 memcpy(mgmt->bssid, bss_desc->bssId, ETH_ALEN);
Jeff Johnsone7245742012-09-05 17:12:55 -07003858
3859#ifdef WLAN_OPEN_SOURCE
3860 /* Android does not want the timestamp from the frame.
3861 Instead it wants a monotonic increasing value */
3862 get_monotonic_boottime(&ts);
3863 mgmt->u.probe_resp.timestamp =
3864 ((u64)ts.tv_sec * 1000000) + (ts.tv_nsec / 1000);
3865#else
3866 /* keep old behavior for non-open source (for now) */
Jeff Johnson295189b2012-06-20 16:38:30 -07003867 memcpy(&mgmt->u.probe_resp.timestamp, bss_desc->timeStamp,
3868 sizeof (bss_desc->timeStamp));
Jeff Johnsone7245742012-09-05 17:12:55 -07003869
3870#endif
3871
Jeff Johnson295189b2012-06-20 16:38:30 -07003872 mgmt->u.probe_resp.beacon_int = bss_desc->beaconInterval;
3873 mgmt->u.probe_resp.capab_info = bss_desc->capabilityInfo;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08003874
3875#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
3876 /* GPS Requirement: need age ie per entry. Using vendor specific. */
3877 /* Assuming this is the last IE, copy at the end */
3878 ie_length -=sizeof(qcom_ie_age);
3879 qie_age = (qcom_ie_age *)(mgmt->u.probe_resp.variable + ie_length);
3880 qie_age->element_id = QCOM_VENDOR_IE_ID;
3881 qie_age->len = QCOM_VENDOR_IE_AGE_LEN;
3882 qie_age->oui_1 = QCOM_OUI1;
3883 qie_age->oui_2 = QCOM_OUI2;
3884 qie_age->oui_3 = QCOM_OUI3;
3885 qie_age->type = QCOM_VENDOR_IE_AGE_TYPE;
3886 qie_age->age = vos_timer_get_system_ticks() - bss_desc->nReceivedTime;
3887#endif
3888
Jeff Johnson295189b2012-06-20 16:38:30 -07003889 memcpy(mgmt->u.probe_resp.variable, ie, ie_length);
Gopichand Nakkalad908ec82013-05-16 19:32:19 +05303890 if (bss_desc->fProbeRsp)
3891 {
3892 mgmt->frame_control |=
3893 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_RESP);
3894 }
3895 else
3896 {
3897 mgmt->frame_control |=
3898 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_BEACON);
3899 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003900
3901#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303902 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ) &&
Jeff Johnson295189b2012-06-20 16:38:30 -07003903 (wiphy->bands[IEEE80211_BAND_2GHZ] != NULL))
3904 {
3905 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
3906 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303907 else if ((chan_no > ARRAY_SIZE(hdd_channels_2_4_GHZ)) &&
Jeff Johnson295189b2012-06-20 16:38:30 -07003908 (wiphy->bands[IEEE80211_BAND_5GHZ] != NULL))
3909
3910 {
3911 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
3912 }
3913 else
3914 {
3915 kfree(mgmt);
3916 return NULL;
3917 }
3918#else
3919 freq = ieee80211_channel_to_frequency(chan_no);
3920#endif
3921 chan = __ieee80211_get_channel(wiphy, freq);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -08003922 /*when the band is changed on the fly using the GUI, three things are done
3923 * 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)
3924 * as part of the scan abort, message willbe queued to PE and we proceed with flushing and changinh the band.
3925 * pe will stop the scanning further and report back the results what ever it had till now by calling the call back function.
3926 * if the time between update band and scandone call back is sufficent enough the band change reflects in SME, SME validates the channels
3927 * and discards the channels correponding to previous band and calls back with zero bss results.
3928 * 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
3929 * all the channels correponding to previous band.this is due to race condition.but those channels are invalid to the new band and so
3930 * this function __ieee80211_get_channel will return NULL.Each time we report scan result with this pointer null warning kernel trace is printed.
3931 * if the scan results contain large number of APs continuosly kernel warning trace is printed and it will lead to apps watch dog bark.
3932 * So drop the bss and continue to next bss.
3933 */
3934 if(chan == NULL)
3935 {
3936 hddLog(VOS_TRACE_LEVEL_INFO, "%s chan pointer is NULL", __func__);
Chilam Ngc4244af2013-04-01 15:37:32 -07003937 kfree(mgmt);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -08003938 return NULL;
3939 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003940 /*To keep the rssi icon of the connected AP in the scan window
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303941 *and the rssi icon of the wireless networks in sync
Jeff Johnson295189b2012-06-20 16:38:30 -07003942 * */
3943 if (( eConnectionState_Associated ==
3944 pAdapter->sessionCtx.station.conn_info.connState ) &&
3945 ( VOS_TRUE == vos_mem_compare(bss_desc->bssId,
3946 pAdapter->sessionCtx.station.conn_info.bssId,
3947 WNI_CFG_BSSID_LEN)))
3948 {
3949 /* supplicant takes the signal strength in terms of mBm(100*dBm) */
3950 rssi = (pAdapter->rssi * 100);
3951 }
3952 else
3953 {
3954 rssi = (VOS_MIN ((bss_desc->rssi + bss_desc->sinr), 0))*100;
3955 }
3956
3957 bss_status = cfg80211_inform_bss_frame(wiphy, chan, mgmt,
3958 frame_len, rssi, GFP_KERNEL);
3959 kfree(mgmt);
3960 return bss_status;
3961}
3962
3963/*
3964 * FUNCTION: wlan_hdd_cfg80211_update_bss_db
3965 * This function is used to update the BSS data base of CFG8011
3966 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303967struct cfg80211_bss* wlan_hdd_cfg80211_update_bss_db( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07003968 tCsrRoamInfo *pRoamInfo
3969 )
3970{
3971 tCsrRoamConnectedProfile roamProfile;
3972 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
3973 struct cfg80211_bss *bss = NULL;
3974
3975 ENTER();
3976
3977 memset(&roamProfile, 0, sizeof(tCsrRoamConnectedProfile));
3978 sme_RoamGetConnectProfile(hHal, pAdapter->sessionId, &roamProfile);
3979
3980 if (NULL != roamProfile.pBssDesc)
3981 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303982 bss = wlan_hdd_cfg80211_inform_bss(pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07003983 &roamProfile);
3984
3985 if (NULL == bss)
3986 {
3987 hddLog(VOS_TRACE_LEVEL_INFO, "%s: cfg80211_inform_bss return NULL",
3988 __func__);
3989 }
3990
3991 sme_RoamFreeConnectProfile(hHal, &roamProfile);
3992 }
3993 else
3994 {
3995 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: roamProfile.pBssDesc is NULL",
3996 __func__);
3997 }
3998 return bss;
3999}
4000
4001/*
4002 * FUNCTION: wlan_hdd_cfg80211_update_bss
4003 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304004static int wlan_hdd_cfg80211_update_bss( struct wiphy *wiphy,
4005 hdd_adapter_t *pAdapter
Jeff Johnson295189b2012-06-20 16:38:30 -07004006 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304007{
Jeff Johnson295189b2012-06-20 16:38:30 -07004008 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
4009 tCsrScanResultInfo *pScanResult;
4010 eHalStatus status = 0;
4011 tScanResultHandle pResult;
4012 struct cfg80211_bss *bss_status = NULL;
4013
4014 ENTER();
4015
4016 if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress)
4017 {
4018 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:LOGP in Progress. Ignore!!!",__func__);
4019 return -EAGAIN;
4020 }
4021
4022 /*
4023 * start getting scan results and populate cgf80211 BSS database
4024 */
4025 status = sme_ScanGetResult(hHal, pAdapter->sessionId, NULL, &pResult);
4026
4027 /* no scan results */
4028 if (NULL == pResult)
4029 {
4030 hddLog(VOS_TRACE_LEVEL_INFO, "%s: No scan result\n", __func__);
4031 return status;
4032 }
4033
4034 pScanResult = sme_ScanResultGetFirst(hHal, pResult);
4035
4036 while (pScanResult)
4037 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304038 /*
4039 * cfg80211_inform_bss() is not updating ie field of bss entry, if
4040 * entry already exists in bss data base of cfg80211 for that
4041 * particular BSS ID. Using cfg80211_inform_bss_frame to update the
4042 * bss entry instead of cfg80211_inform_bss, But this call expects
4043 * mgmt packet as input. As of now there is no possibility to get
4044 * the mgmt(probe response) frame from PE, converting bss_desc to
Jeff Johnson295189b2012-06-20 16:38:30 -07004045 * ieee80211_mgmt(probe response) and passing to c
4046 * fg80211_inform_bss_frame.
4047 * */
4048
4049 bss_status = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
4050 &pScanResult->BssDescriptor);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304051
Jeff Johnson295189b2012-06-20 16:38:30 -07004052
4053 if (NULL == bss_status)
4054 {
4055 hddLog(VOS_TRACE_LEVEL_INFO,
4056 "%s: NULL returned by cfg80211_inform_bss\n", __func__);
4057 }
4058 else
4059 {
4060 cfg80211_put_bss(bss_status);
4061 }
4062
4063 pScanResult = sme_ScanResultGetNext(hHal, pResult);
4064 }
4065
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304066 sme_ScanResultPurge(hHal, pResult);
Jeff Johnson295189b2012-06-20 16:38:30 -07004067
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304068 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07004069}
4070
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004071void
4072hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel)
4073{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304074 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07004075 "%02X:%02X:%02X:%02X:%02X:%02X\n",
4076 macAddr[0], macAddr[1], macAddr[2], macAddr[3], macAddr[4],
4077 macAddr[5]);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004078} /****** end hddPrintMacAddr() ******/
4079
4080void
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07004081hddPrintPmkId(tANI_U8 *pmkId, tANI_U8 logLevel)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004082{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304083 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07004084 "%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X\n",
4085 pmkId[0], pmkId[1], pmkId[2], pmkId[3], pmkId[4],
4086 pmkId[5], pmkId[6], pmkId[7], pmkId[8], pmkId[9], pmkId[10],
4087 pmkId[11], pmkId[12], pmkId[13], pmkId[14], pmkId[15]);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004088} /****** end hddPrintPmkId() ******/
4089
4090//hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel);
4091//hddPrintMacAddr(macAddr, VOS_TRACE_LEVEL_FATAL);
4092
4093//void sirDumpBuf(tpAniSirGlobal pMac, tANI_U8 modId, tANI_U32 level, tANI_U8 *buf, tANI_U32 size);
4094//sirDumpBuf(pMac, VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, pmkid, 16);
4095
4096#define dump_bssid(bssid) \
4097 { \
Jeff Johnsone7245742012-09-05 17:12:55 -07004098 hddLog(VOS_TRACE_LEVEL_INFO, "BSSID (MAC) address:\t"); \
4099 hddPrintMacAddr(bssid, VOS_TRACE_LEVEL_INFO);\
4100 hddLog(VOS_TRACE_LEVEL_INFO, "\n"); \
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004101 }
4102
4103#define dump_pmkid(pMac, pmkid) \
4104 { \
Jeff Johnsone7245742012-09-05 17:12:55 -07004105 hddLog(VOS_TRACE_LEVEL_INFO, "PMKSA-ID:\t"); \
4106 hddPrintPmkId(pmkid, VOS_TRACE_LEVEL_INFO);\
4107 hddLog(VOS_TRACE_LEVEL_INFO, "\n"); \
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004108 }
4109
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -07004110#if defined(FEATURE_WLAN_LFR) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004111/*
4112 * FUNCTION: wlan_hdd_cfg80211_pmksa_candidate_notify
4113 * This function is used to notify the supplicant of a new PMKSA candidate.
4114 */
4115int wlan_hdd_cfg80211_pmksa_candidate_notify(
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304116 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004117 int index, bool preauth )
4118{
Jeff Johnsone7245742012-09-05 17:12:55 -07004119#ifdef FEATURE_WLAN_OKC
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004120 struct net_device *dev = pAdapter->dev;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004121 hdd_context_t *pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004122
4123 ENTER();
Jeff Johnsone7245742012-09-05 17:12:55 -07004124 hddLog(VOS_TRACE_LEVEL_INFO, "%s is going to notify supplicant of:", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004125
4126 if( NULL == pRoamInfo )
4127 {
4128 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pRoamInfo is NULL\n", __func__);
4129 return -EINVAL;
4130 }
4131
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004132 if (eANI_BOOLEAN_TRUE == hdd_is_okc_mode_enabled(pHddCtx))
4133 {
4134 dump_bssid(pRoamInfo->bssid);
4135 cfg80211_pmksa_candidate_notify(dev, index,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004136 pRoamInfo->bssid, preauth, GFP_KERNEL);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004137 }
Jeff Johnsone7245742012-09-05 17:12:55 -07004138#endif /* FEATURE_WLAN_OKC */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304139 return 0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004140}
4141#endif //FEATURE_WLAN_LFR
4142
Jeff Johnson295189b2012-06-20 16:38:30 -07004143/*
4144 * FUNCTION: hdd_cfg80211_scan_done_callback
4145 * scanning callback function, called after finishing scan
4146 *
4147 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304148static eHalStatus hdd_cfg80211_scan_done_callback(tHalHandle halHandle,
Jeff Johnson295189b2012-06-20 16:38:30 -07004149 void *pContext, tANI_U32 scanId, eCsrScanStatus status)
4150{
4151 struct net_device *dev = (struct net_device *) pContext;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304152 //struct wireless_dev *wdev = dev->ieee80211_ptr;
Jeff Johnson295189b2012-06-20 16:38:30 -07004153 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07004154 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
4155 hdd_scaninfo_t *pScanInfo = &pHddCtx->scan_info;
Jeff Johnson295189b2012-06-20 16:38:30 -07004156 struct cfg80211_scan_request *req = NULL;
4157 int ret = 0;
4158
4159 ENTER();
4160
4161 hddLog(VOS_TRACE_LEVEL_INFO,
4162 "%s called with halHandle = %p, pContext = %p,"
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304163 "scanID = %d, returned status = %d\n",
Jeff Johnson295189b2012-06-20 16:38:30 -07004164 __func__, halHandle, pContext, (int) scanId, (int) status);
4165
4166 //Block on scan req completion variable. Can't wait forever though.
4167 ret = wait_for_completion_interruptible_timeout(
4168 &pScanInfo->scan_req_completion_event,
4169 msecs_to_jiffies(WLAN_WAIT_TIME_SCAN_REQ));
4170 if (!ret)
4171 {
4172 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -07004173 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -07004174 }
4175
4176 if(pScanInfo->mScanPending != VOS_TRUE)
4177 {
4178 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -07004179 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -07004180 }
4181
4182 /* Check the scanId */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304183 if (pScanInfo->scanId != scanId)
Jeff Johnson295189b2012-06-20 16:38:30 -07004184 {
4185 hddLog(VOS_TRACE_LEVEL_INFO,
4186 "%s called with mismatched scanId pScanInfo->scanId = %d "
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304187 "scanId = %d \n", __func__, (int) pScanInfo->scanId,
Jeff Johnson295189b2012-06-20 16:38:30 -07004188 (int) scanId);
4189 }
4190
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304191 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07004192 pAdapter);
4193
4194 if (0 > ret)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304195 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004196
4197
4198 /* If any client wait scan result through WEXT
4199 * send scan done event to client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07004200 if (pHddCtx->scan_info.waitScanResult)
Jeff Johnson295189b2012-06-20 16:38:30 -07004201 {
4202 /* The other scan request waiting for current scan finish
4203 * Send event to notify current scan finished */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07004204 if(WEXT_SCAN_PENDING_DELAY == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -07004205 {
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07004206 vos_event_set(&pHddCtx->scan_info.scan_finished_event);
Jeff Johnson295189b2012-06-20 16:38:30 -07004207 }
4208 /* Send notify to WEXT client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07004209 else if(WEXT_SCAN_PENDING_PIGGYBACK == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -07004210 {
4211 struct net_device *dev = pAdapter->dev;
4212 union iwreq_data wrqu;
4213 int we_event;
4214 char *msg;
4215
4216 memset(&wrqu, '\0', sizeof(wrqu));
4217 we_event = SIOCGIWSCAN;
4218 msg = NULL;
4219 wireless_send_event(dev, we_event, &wrqu, msg);
4220 }
4221 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07004222 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07004223
4224 /* Get the Scan Req */
4225 req = pAdapter->request;
4226
4227 if (!req)
4228 {
4229 hddLog(VOS_TRACE_LEVEL_ERROR, "request is became NULL\n");
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07004230 pScanInfo->mScanPending = VOS_FALSE;
Jeff Johnsone7245742012-09-05 17:12:55 -07004231 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -07004232 }
4233
4234 /*
4235 * setting up 0, just in case.
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304236 */
Jeff Johnson295189b2012-06-20 16:38:30 -07004237 req->n_ssids = 0;
4238 req->n_channels = 0;
4239 req->ie = 0;
4240
Jeff Johnson295189b2012-06-20 16:38:30 -07004241 pAdapter->request = NULL;
Jeff Johnsone7245742012-09-05 17:12:55 -07004242 /* Scan is no longer pending */
4243 pScanInfo->mScanPending = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07004244
Madan Mohan Koyyalamudib764bf82012-10-11 16:38:51 -07004245 /*
4246 * cfg80211_scan_done informing NL80211 about completion
4247 * of scanning
4248 */
4249 cfg80211_scan_done(req, false);
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -08004250 complete(&pScanInfo->abortscan_event_var);
Jeff Johnson295189b2012-06-20 16:38:30 -07004251
Jeff Johnsone7245742012-09-05 17:12:55 -07004252allow_suspend:
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07004253 /* release the wake lock at the end of the scan*/
4254 hdd_allow_suspend();
Jeff Johnsone7245742012-09-05 17:12:55 -07004255
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -07004256 /* Acquire wakelock to handle the case where APP's tries to suspend
4257 * immediatly after the driver gets connect request(i.e after scan)
4258 * from supplicant, this result in app's is suspending and not able
4259 * to process the connect request to AP */
Amar Singhal6144c002013-05-03 16:11:42 -07004260 hdd_allow_suspend_timeout(1000);
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -07004261
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07004262#ifdef FEATURE_WLAN_TDLS
4263 wlan_hdd_tdls_scan_done_callback(pAdapter);
4264#endif
4265
Jeff Johnson295189b2012-06-20 16:38:30 -07004266 EXIT();
4267 return 0;
4268}
4269
4270/*
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08004271 * FUNCTION: hdd_isScanAllowed
4272 * Go through each adapter and check if scan allowed
4273 *
4274 */
4275v_BOOL_t hdd_isScanAllowed( hdd_context_t *pHddCtx )
4276{
4277 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
4278 hdd_station_ctx_t *pHddStaCtx = NULL;
4279 hdd_adapter_t *pAdapter = NULL;
4280 VOS_STATUS status = 0;
4281 v_U8_t staId = 0;
4282 v_U8_t *staMac = NULL;
4283
4284 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
4285
4286 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
4287 {
4288 pAdapter = pAdapterNode->pAdapter;
4289
4290 if( pAdapter )
4291 {
4292 hddLog(VOS_TRACE_LEVEL_INFO,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304293 "%s: Adapter with device mode %d exists",
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08004294 __func__, pAdapter->device_mode);
4295 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
4296 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
4297 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
4298 {
4299 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4300 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
4301 (VOS_FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
4302 {
4303 staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]);
4304 hddLog(VOS_TRACE_LEVEL_ERROR,
4305 "%s: client %02x:%02x:%02x:%02x:%02x:%02x is in the "
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304306 "middle of WPS/EAPOL exchange.", __func__,
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08004307 staMac[0], staMac[1], staMac[2],
4308 staMac[3], staMac[4], staMac[5]);
4309 return VOS_FALSE;
4310 }
4311 }
4312 else if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) ||
4313 (WLAN_HDD_P2P_GO == pAdapter->device_mode))
4314 {
4315 for (staId = 0; staId < WLAN_MAX_STA_COUNT; staId++)
4316 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304317 if ((pAdapter->aStaInfo[staId].isUsed) &&
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08004318 (WLANTL_STA_CONNECTED == pAdapter->aStaInfo[staId].tlSTAState))
4319 {
4320 staMac = (v_U8_t *) &(pAdapter->aStaInfo[staId].macAddrSTA.bytes[0]);
4321
4322 hddLog(VOS_TRACE_LEVEL_ERROR,
4323 "%s: client %02x:%02x:%02x:%02x:%02x:%02x of SoftAP/P2P-GO is in the "
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304324 "middle of WPS/EAPOL exchange.", __func__,
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08004325 staMac[0], staMac[1], staMac[2],
4326 staMac[3], staMac[4], staMac[5]);
4327 return VOS_FALSE;
4328 }
4329 }
4330 }
4331 }
4332 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
4333 pAdapterNode = pNext;
4334 }
4335 hddLog(VOS_TRACE_LEVEL_INFO,
4336 "%s: Scan allowed", __func__);
4337 return VOS_TRUE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304338}
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08004339
4340/*
Jeff Johnson295189b2012-06-20 16:38:30 -07004341 * FUNCTION: wlan_hdd_cfg80211_scan
4342 * this scan respond to scan trigger and update cfg80211 scan database
4343 * later, scan dump command can be used to recieve scan results
4344 */
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -08004345int wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
4346#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
4347 struct net_device *dev,
4348#endif
4349 struct cfg80211_scan_request *request)
4350{
4351#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
4352 struct net_device *dev = request->wdev->netdev;
4353#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304354 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Jeff Johnson295189b2012-06-20 16:38:30 -07004355 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
4356 hdd_wext_state_t *pwextBuf = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05304357 hdd_config_t *cfg_param = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07004358 tCsrScanRequest scanRequest;
4359 tANI_U8 *channelList = NULL, i;
4360 v_U32_t scanId = 0;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05304361 int status;
4362 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07004363 v_U8_t* pP2pIe = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07004364
4365 ENTER();
4366
4367 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",
4368 __func__,pAdapter->device_mode);
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08004369
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05304370 status = wlan_hdd_validate_context(pHddCtx);
4371
4372 if (0 != status)
4373 {
4374 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4375 "%s: HDD context is not valid", __func__);
4376 return status;
4377 }
4378
4379 cfg_param = pHddCtx->cfg_ini;
4380 pScanInfo = &pHddCtx->scan_info;
4381
Gopichand Nakkala681989c2013-03-06 22:27:48 -08004382 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08004383 (eConnectionState_Connecting ==
Gopichand Nakkala681989c2013-03-06 22:27:48 -08004384 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08004385 {
4386 hddLog(VOS_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08004387 "%s: %p(%d) Connection in progress: Scan request denied (EBUSY)", __func__, \
4388 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08004389 return -EBUSY;
4390 }
4391
Jeff Johnson295189b2012-06-20 16:38:30 -07004392#ifdef WLAN_BTAMP_FEATURE
4393 //Scan not supported when AMP traffic is on.
Gopichand Nakkala681989c2013-03-06 22:27:48 -08004394 if (VOS_TRUE == WLANBAP_AmpSessionOn())
Jeff Johnson295189b2012-06-20 16:38:30 -07004395 {
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08004396 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07004397 "%s: No scanning when AMP is on", __func__);
4398 return -EOPNOTSUPP;
4399 }
4400#endif
4401 //Scan on any other interface is not supported.
Gopichand Nakkala681989c2013-03-06 22:27:48 -08004402 if (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07004403 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -08004404 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07004405 "%s: Not scanning on device_mode = %d",
4406 __func__, pAdapter->device_mode);
4407 return -EOPNOTSUPP;
4408 }
4409
4410 if (TRUE == pScanInfo->mScanPending)
4411 {
4412 hddLog(VOS_TRACE_LEVEL_INFO, "%s: mScanPending is TRUE", __func__);
Gopichand Nakkala681989c2013-03-06 22:27:48 -08004413 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -07004414 }
4415
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304416 //Don't Allow Scan and return busy if Remain On
Jeff Johnson32d95a32012-09-10 13:15:23 -07004417 //Channel and action frame is pending
4418 //Otherwise Cancel Remain On Channel and allow Scan
4419 //If no action frame pending
Gopichand Nakkala681989c2013-03-06 22:27:48 -08004420 if (0 != wlan_hdd_check_remain_on_channel(pAdapter))
Jeff Johnson32d95a32012-09-10 13:15:23 -07004421 {
4422 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Remain On Channel Pending", __func__);
4423 return -EBUSY;
4424 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08004425#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07004426 /* if tdls disagree scan right now, return immediately.
4427 tdls will schedule the scan when scan is allowed. (return SUCCESS)
4428 or will reject the scan if any TDLS is in progress. (return -EBUSY)
4429 */
4430 status = wlan_hdd_tdls_scan_callback (pAdapter,
4431 wiphy,
4432#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
4433 dev,
Gopichand Nakkalac3c42b92013-03-20 19:42:34 -07004434#endif
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07004435 request);
4436 if(status <= 0)
4437 {
4438 hddLog(VOS_TRACE_LEVEL_INFO, "%s: TDLS Pending %d", __func__, status);
4439 return status;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08004440 }
4441#endif
Jeff Johnson32d95a32012-09-10 13:15:23 -07004442
Jeff Johnson295189b2012-06-20 16:38:30 -07004443 if (mutex_lock_interruptible(&pHddCtx->tmInfo.tmOperationLock))
4444 {
4445 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_ERROR,
Jeff Johnson1250df42012-12-10 14:31:52 -08004446 "%s: Acquire lock fail", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004447 return -EAGAIN;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304448 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004449 if (TRUE == pHddCtx->tmInfo.tmAction.enterImps)
4450 {
4451 hddLog(VOS_TRACE_LEVEL_WARN,
4452 "%s: MAX TM Level Scan not allowed", __func__);
4453 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304454 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -07004455 }
4456 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
4457
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08004458 /* Check if scan is allowed at this point of time.
4459 */
4460 if (!hdd_isScanAllowed(pHddCtx))
4461 {
4462 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Scan not allowed", __func__);
4463 return -EBUSY;
4464 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304465
Jeff Johnson295189b2012-06-20 16:38:30 -07004466 vos_mem_zero( &scanRequest, sizeof(scanRequest));
4467
4468 if (NULL != request)
4469 {
4470 hddLog(VOS_TRACE_LEVEL_INFO, "scan request for ssid = %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304471 (int)request->n_ssids);
Jeff Johnson295189b2012-06-20 16:38:30 -07004472
4473 /* Even though supplicant doesn't provide any SSIDs, n_ssids is set to 1.
4474 * Becasue of this, driver is assuming that this is not wildcard scan and so
4475 * is not aging out the scan results.
4476 */
Jeff Johnson32d95a32012-09-10 13:15:23 -07004477 if (request->ssids && '\0' == request->ssids->ssid[0])
Jeff Johnson295189b2012-06-20 16:38:30 -07004478 {
4479 request->n_ssids = 0;
4480 }
4481
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07004482 if ((request->ssids) && (0 < request->n_ssids))
Jeff Johnson295189b2012-06-20 16:38:30 -07004483 {
4484 tCsrSSIDInfo *SsidInfo;
4485 int j;
4486 scanRequest.SSIDs.numOfSSIDs = request->n_ssids;
4487 /* Allocate num_ssid tCsrSSIDInfo structure */
4488 SsidInfo = scanRequest.SSIDs.SSIDList =
4489 ( tCsrSSIDInfo *)vos_mem_malloc(
4490 request->n_ssids*sizeof(tCsrSSIDInfo));
4491
4492 if(NULL == scanRequest.SSIDs.SSIDList)
4493 {
4494 hddLog(VOS_TRACE_LEVEL_ERROR,
4495 "memory alloc failed SSIDInfo buffer");
4496 return -ENOMEM;
4497 }
4498
4499 /* copy all the ssid's and their length */
4500 for(j = 0; j < request->n_ssids; j++, SsidInfo++)
4501 {
4502 /* get the ssid length */
4503 SsidInfo->SSID.length = request->ssids[j].ssid_len;
4504 vos_mem_copy(SsidInfo->SSID.ssId, &request->ssids[j].ssid[0],
4505 SsidInfo->SSID.length);
4506 SsidInfo->SSID.ssId[SsidInfo->SSID.length] = '\0';
4507 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "SSID number %d: %s",
4508 j, SsidInfo->SSID.ssId);
4509 }
4510 /* set the scan type to active */
4511 scanRequest.scanType = eSIR_ACTIVE_SCAN;
4512 }
4513 else if(WLAN_HDD_P2P_GO == pAdapter->device_mode)
4514 {
4515 /* set the scan type to active */
4516 scanRequest.scanType = eSIR_ACTIVE_SCAN;
4517 }
4518 else
4519 {
4520 /*Set the scan type to default type, in this case it is ACTIVE*/
4521 scanRequest.scanType = pScanInfo->scan_mode;
4522 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304523 scanRequest.minChnTime = cfg_param->nActiveMinChnTime;
Jeff Johnson295189b2012-06-20 16:38:30 -07004524 scanRequest.maxChnTime = cfg_param->nActiveMaxChnTime;
4525 }
4526 else
4527 {
4528 /* set the scan type to active */
4529 scanRequest.scanType = eSIR_ACTIVE_SCAN;
4530 vos_mem_set( scanRequest.bssid, sizeof( tCsrBssid ), 0xff );
4531
4532 /* set min and max channel time to zero */
4533 scanRequest.minChnTime = 0;
4534 scanRequest.maxChnTime = 0;
4535 }
4536
4537 /* set BSSType to default type */
4538 scanRequest.BSSType = eCSR_BSS_TYPE_ANY;
4539
4540 /*TODO: scan the requested channels only*/
4541
4542 /*Right now scanning all the channels */
4543 if( request )
4544 {
4545 if( request->n_channels )
4546 {
4547 channelList = vos_mem_malloc( request->n_channels );
4548 if( NULL == channelList )
4549 {
4550 status = -ENOMEM;
4551 goto free_mem;
4552 }
4553
4554 for( i = 0 ; i < request->n_channels ; i++ )
4555 channelList[i] = request->channels[i]->hw_value;
4556 }
4557
4558 scanRequest.ChannelInfo.numOfChannels = request->n_channels;
4559 scanRequest.ChannelInfo.ChannelList = channelList;
4560
4561 /* set requestType to full scan */
4562 scanRequest.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304563
4564 /* Flush the scan results(only p2p beacons) for STA scan and P2P
Madan Mohan Koyyalamudi8d50f312012-11-27 15:48:57 -08004565 * search (Flush on both full scan and social scan but not on single
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304566 * channel scan).P2P search happens on 3 social channels (1, 6, 11)
Madan Mohan Koyyalamudi8d50f312012-11-27 15:48:57 -08004567 */
4568
4569 /* Supplicant does single channel scan after 8-way handshake
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304570 * and in that case driver shoudnt flush scan results. If
4571 * driver flushes the scan results here and unfortunately if
4572 * the AP doesnt respond to our probe req then association
Madan Mohan Koyyalamudi8d50f312012-11-27 15:48:57 -08004573 * fails which is not desired
4574 */
4575
4576 if( request->n_channels != WLAN_HDD_P2P_SINGLE_CHANNEL_SCAN )
4577 {
4578 sme_ScanFlushP2PResult( WLAN_HDD_GET_HAL_CTX(pAdapter),
4579 pAdapter->sessionId );
4580 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004581
4582 if( request->ie_len )
4583 {
4584 /* save this for future association (join requires this) */
4585 memset( &pScanInfo->scanAddIE, 0, sizeof(pScanInfo->scanAddIE) );
4586 memcpy( pScanInfo->scanAddIE.addIEdata, request->ie, request->ie_len);
4587 pScanInfo->scanAddIE.length = request->ie_len;
4588
4589 if((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Jeff Johnsone7245742012-09-05 17:12:55 -07004590 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
4591 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -07004592 )
4593 {
4594 pwextBuf->roamProfile.pAddIEScan = pScanInfo->scanAddIE.addIEdata;
4595 pwextBuf->roamProfile.nAddIEScanLength = pScanInfo->scanAddIE.length;
4596 }
4597
4598 scanRequest.uIEFieldLen = pScanInfo->scanAddIE.length;
4599 scanRequest.pIEField = pScanInfo->scanAddIE.addIEdata;
4600
Jeff Johnson295189b2012-06-20 16:38:30 -07004601 pP2pIe = wlan_hdd_get_p2p_ie_ptr((v_U8_t*)request->ie,
4602 request->ie_len);
4603 if (pP2pIe != NULL)
4604 {
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07004605#ifdef WLAN_FEATURE_P2P_DEBUG
4606 if (((globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED) ||
4607 (globalP2PConnectionStatus == P2P_GO_NEG_PROCESS)) &&
4608 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
4609 {
4610 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_1;
4611 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
4612 "Go nego completed to Connection is started");
4613 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
4614 "for 8way Handshake");
4615 }
4616 else if((globalP2PConnectionStatus == P2P_CLIENT_DISCONNECTED_STATE) &&
4617 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
4618 {
4619 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_2;
4620 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
4621 "Disconnected state to Connection is started");
4622 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
4623 "for 4way Handshake");
4624 }
4625#endif
4626
Jeff Johnsone7245742012-09-05 17:12:55 -07004627 /* no_cck will be set during p2p find to disable 11b rates */
4628 if(TRUE == request->no_cck)
Jeff Johnson295189b2012-06-20 16:38:30 -07004629 {
Jeff Johnson295189b2012-06-20 16:38:30 -07004630 hddLog(VOS_TRACE_LEVEL_INFO,
4631 "%s: This is a P2P Search", __func__);
4632 scanRequest.p2pSearch = 1;
Jeff Johnsone7245742012-09-05 17:12:55 -07004633
Jeff Johnsone7245742012-09-05 17:12:55 -07004634 if( request->n_channels == WLAN_HDD_P2P_SOCIAL_CHANNELS )
4635 {
Madan Mohan Koyyalamudi1b1d9e82012-10-21 11:38:33 -07004636 /* set requestType to P2P Discovery */
4637 scanRequest.requestType = eCSR_SCAN_P2P_DISCOVERY;
Jeff Johnsone7245742012-09-05 17:12:55 -07004638 }
4639
4640 /*
4641 Skip Dfs Channel in case of P2P Search
4642 if it is set in ini file
4643 */
4644 if(cfg_param->skipDfsChnlInP2pSearch)
4645 {
4646 scanRequest.skipDfsChnlInP2pSearch = 1;
4647 }
4648 else
4649 {
4650 scanRequest.skipDfsChnlInP2pSearch = 0;
4651 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004652
Jeff Johnson295189b2012-06-20 16:38:30 -07004653 }
4654 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004655 }
4656 }
4657
4658 INIT_COMPLETION(pScanInfo->scan_req_completion_event);
4659
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07004660 /* acquire the wakelock to avoid the apps suspend during the scan. To
4661 * address the following issues.
4662 * 1) Disconnected scenario: we are not allowing the suspend as WLAN is not in
4663 * BMPS/IMPS this result in android trying to suspend aggressively and backing off
4664 * for long time, this result in apps running at full power for long time.
4665 * 2) Connected scenario: If we allow the suspend during the scan, RIVA will
4666 * be stuck in full power because of resume BMPS
4667 */
4668 hdd_prevent_suspend();
Jeff Johnsone7245742012-09-05 17:12:55 -07004669
4670 status = sme_ScanRequest( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07004671 pAdapter->sessionId, &scanRequest, &scanId,
4672 &hdd_cfg80211_scan_done_callback, dev );
Jeff Johnsone7245742012-09-05 17:12:55 -07004673
Jeff Johnson295189b2012-06-20 16:38:30 -07004674 if (eHAL_STATUS_SUCCESS != status)
4675 {
4676 hddLog(VOS_TRACE_LEVEL_ERROR,
4677 "%s: sme_ScanRequest returned error %d", __func__, status);
4678 complete(&pScanInfo->scan_req_completion_event);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -07004679 if(eHAL_STATUS_RESOURCES == status)
4680 {
Madan Mohan Koyyalamudia3fcf142012-10-18 15:01:20 -07004681 hddLog(VOS_TRACE_LEVEL_INFO, "%s: HO is in progress.So defer the scan by informing busy",__func__);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -07004682 status = -EBUSY;
4683 } else {
4684 status = -EIO;
4685 }
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07004686 hdd_allow_suspend();
Jeff Johnson295189b2012-06-20 16:38:30 -07004687 goto free_mem;
4688 }
4689
4690 pScanInfo->mScanPending = TRUE;
4691 pAdapter->request = request;
4692 pScanInfo->scanId = scanId;
4693
4694 complete(&pScanInfo->scan_req_completion_event);
4695
4696free_mem:
4697 if( scanRequest.SSIDs.SSIDList )
4698 {
4699 vos_mem_free(scanRequest.SSIDs.SSIDList);
4700 }
4701
4702 if( channelList )
4703 vos_mem_free( channelList );
4704
4705 EXIT();
4706
4707 return status;
4708}
4709
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07004710
4711void hdd_select_cbmode( hdd_adapter_t *pAdapter,v_U8_t operationChannel)
4712{
4713 v_U8_t iniDot11Mode =
4714 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->dot11Mode;
4715 eHddDot11Mode hddDot11Mode = iniDot11Mode;
4716
4717 switch ( iniDot11Mode )
4718 {
4719 case eHDD_DOT11_MODE_AUTO:
4720 case eHDD_DOT11_MODE_11ac:
4721 case eHDD_DOT11_MODE_11ac_ONLY:
4722#ifdef WLAN_FEATURE_11AC
4723 hddDot11Mode = eHDD_DOT11_MODE_11ac;
4724#else
4725 hddDot11Mode = eHDD_DOT11_MODE_11n;
4726#endif
4727 break;
4728 case eHDD_DOT11_MODE_11n:
4729 case eHDD_DOT11_MODE_11n_ONLY:
4730 hddDot11Mode = eHDD_DOT11_MODE_11n;
4731 break;
4732 default:
4733 hddDot11Mode = iniDot11Mode;
4734 break;
4735 }
4736 /* This call decides required channel bonding mode */
4737 sme_SelectCBMode((WLAN_HDD_GET_CTX(pAdapter)->hHal),
4738 hdd_cfg_xlate_to_csr_phy_mode(hddDot11Mode),
4739 operationChannel);
4740}
4741
Jeff Johnson295189b2012-06-20 16:38:30 -07004742/*
4743 * FUNCTION: wlan_hdd_cfg80211_connect_start
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304744 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -07004745 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304746int wlan_hdd_cfg80211_connect_start( hdd_adapter_t *pAdapter,
Jeff Johnson32d95a32012-09-10 13:15:23 -07004747 const u8 *ssid, size_t ssid_len, const u8 *bssid, u8 operatingChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -07004748{
4749 int status = 0;
4750 hdd_wext_state_t *pWextState;
4751 v_U32_t roamId;
4752 tCsrRoamProfile *pRoamProfile;
4753 eMib_dot11DesiredBssType connectedBssType;
4754 eCsrAuthType RSNAuthType;
4755
4756 ENTER();
4757
4758 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304759
Jeff Johnson295189b2012-06-20 16:38:30 -07004760 if (SIR_MAC_MAX_SSID_LENGTH < ssid_len)
4761 {
4762 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wrong SSID len", __func__);
4763 return -EINVAL;
4764 }
4765
4766 pRoamProfile = &pWextState->roamProfile;
4767
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304768 if (pRoamProfile)
Jeff Johnson295189b2012-06-20 16:38:30 -07004769 {
Jeff Johnsone7245742012-09-05 17:12:55 -07004770 int ret = 0;
4771 hdd_station_ctx_t *pHddStaCtx;
4772 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4773 hdd_connGetConnectedBssType(pHddStaCtx,&connectedBssType );
4774
4775 if((eMib_dot11DesiredBssType_independent == connectedBssType) ||
4776 (eConnectionState_Associated == pHddStaCtx->conn_info.connState) ||
4777 (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState))
Jeff Johnson295189b2012-06-20 16:38:30 -07004778 {
4779 /* Issue disconnect to CSR */
4780 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304781 if( eHAL_STATUS_SUCCESS ==
Jeff Johnson295189b2012-06-20 16:38:30 -07004782 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
4783 pAdapter->sessionId,
4784 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
4785 {
Jeff Johnsone7245742012-09-05 17:12:55 -07004786 ret = wait_for_completion_interruptible_timeout(
4787 &pAdapter->disconnect_comp_var,
4788 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
4789 if (0 == ret)
4790 {
4791 VOS_ASSERT(0);
4792 }
4793 }
4794 }
4795 else if(eConnectionState_Disconnecting == pHddStaCtx->conn_info.connState)
4796 {
4797 ret = wait_for_completion_interruptible_timeout(
4798 &pAdapter->disconnect_comp_var,
4799 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
4800 if (0 == ret)
4801 {
4802 VOS_ASSERT(0);
Jeff Johnson295189b2012-06-20 16:38:30 -07004803 }
4804 }
4805
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304806 if (HDD_WMM_USER_MODE_NO_QOS ==
Jeff Johnson295189b2012-06-20 16:38:30 -07004807 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->WmmMode)
4808 {
4809 /*QoS not enabled in cfg file*/
4810 pRoamProfile->uapsd_mask = 0;
4811 }
4812 else
4813 {
4814 /*QoS enabled, update uapsd mask from cfg file*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304815 pRoamProfile->uapsd_mask =
Jeff Johnson295189b2012-06-20 16:38:30 -07004816 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask;
4817 }
4818
4819 pRoamProfile->SSIDs.numOfSSIDs = 1;
4820 pRoamProfile->SSIDs.SSIDList->SSID.length = ssid_len;
4821 vos_mem_zero(pRoamProfile->SSIDs.SSIDList->SSID.ssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304822 sizeof(pRoamProfile->SSIDs.SSIDList->SSID.ssId));
Jeff Johnson295189b2012-06-20 16:38:30 -07004823 vos_mem_copy((void *)(pRoamProfile->SSIDs.SSIDList->SSID.ssId),
4824 ssid, ssid_len);
4825
4826 if (bssid)
4827 {
4828 pRoamProfile->BSSIDs.numOfBSSIDs = 1;
4829 vos_mem_copy((void *)(pRoamProfile->BSSIDs.bssid), bssid,
4830 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304831 /* Save BSSID in seperate variable as well, as RoamProfile
4832 BSSID is getting zeroed out in the association process. And in
Jeff Johnson295189b2012-06-20 16:38:30 -07004833 case of join failure we should send valid BSSID to supplicant
4834 */
4835 vos_mem_copy((void *)(pWextState->req_bssId), bssid,
4836 WNI_CFG_BSSID_LEN);
4837 }
4838
4839 if ((IW_AUTH_WPA_VERSION_WPA == pWextState->wpaVersion) ||
4840 (IW_AUTH_WPA_VERSION_WPA2 == pWextState->wpaVersion))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304841 {
Jeff Johnson295189b2012-06-20 16:38:30 -07004842 /*set gen ie*/
4843 hdd_SetGENIEToCsr(pAdapter, &RSNAuthType);
4844 /*set auth*/
4845 hdd_set_csr_auth_type(pAdapter, RSNAuthType);
4846 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004847#ifdef FEATURE_WLAN_WAPI
4848 if (pAdapter->wapi_info.nWapiMode)
4849 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004850 hddLog(LOG1, "%s: Setting WAPI AUTH Type and Encryption Mode values", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004851 switch (pAdapter->wapi_info.wapiAuthMode)
4852 {
4853 case WAPI_AUTH_MODE_PSK:
4854 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004855 hddLog(LOG1, "%s: WAPI AUTH TYPE: PSK: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07004856 pAdapter->wapi_info.wapiAuthMode);
4857 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_PSK;
4858 break;
4859 }
4860 case WAPI_AUTH_MODE_CERT:
4861 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004862 hddLog(LOG1, "%s: WAPI AUTH TYPE: CERT: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07004863 pAdapter->wapi_info.wapiAuthMode);
4864 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE;
4865 break;
4866 }
4867 } // End of switch
4868 if ( pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_PSK ||
4869 pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_CERT)
4870 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004871 hddLog(LOG1, "%s: WAPI PAIRWISE/GROUP ENCRYPTION: WPI", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004872 pRoamProfile->AuthType.numEntries = 1;
4873 pRoamProfile->EncryptionType.numEntries = 1;
4874 pRoamProfile->EncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
4875 pRoamProfile->mcEncryptionType.numEntries = 1;
4876 pRoamProfile->mcEncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
4877 }
4878 }
4879#endif /* FEATURE_WLAN_WAPI */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05304880#ifdef WLAN_FEATURE_GTK_OFFLOAD
4881 /* Initializing gtkOffloadRequestParams */
4882 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
4883 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
4884 {
4885 pHddStaCtx->gtkOffloadRequestParams.requested = FALSE;
4886 memset(&pHddStaCtx->gtkOffloadRequestParams.gtkOffloadReqParams,
4887 0, sizeof (tSirGtkOffloadParams));
4888 }
4889#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07004890 pRoamProfile->csrPersona = pAdapter->device_mode;
4891
Jeff Johnson32d95a32012-09-10 13:15:23 -07004892 if( operatingChannel )
4893 {
4894 pRoamProfile->ChannelInfo.ChannelList = &operatingChannel;
4895 pRoamProfile->ChannelInfo.numOfChannels = 1;
4896 }
Chet Lanctot186b5732013-03-18 10:26:30 -07004897 else
4898 {
4899 pRoamProfile->ChannelInfo.ChannelList = NULL;
4900 pRoamProfile->ChannelInfo.numOfChannels = 0;
4901 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07004902 if ( (WLAN_HDD_IBSS == pAdapter->device_mode) && operatingChannel)
4903 {
4904 hdd_select_cbmode(pAdapter,operatingChannel);
4905 }
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08004906 /* change conn_state to connecting before sme_RoamConnect(), because sme_RoamConnect()
4907 * has a direct path to call hdd_smeRoamCallback(), which will change the conn_state
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304908 * If direct path, conn_state will be accordingly changed to NotConnected or Associated
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08004909 * by either hdd_AssociationCompletionHandler() or hdd_DisConnectHandler() in sme_RoamCallback()
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -08004910 * if sme_RomConnect is to be queued, Connecting state will remain until it is completed.
4911 */
4912 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode)
4913 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
4914 eConnectionState_Connecting);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304915
4916 status = sme_RoamConnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07004917 pAdapter->sessionId, pRoamProfile, &roamId);
4918
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08004919 if( (eHAL_STATUS_SUCCESS != status) &&
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +05304920 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) )
4921
4922 {
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08004923 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: sme_RoamConnect (session %d) failed with "
4924 "status %d. -> NotConnected", __func__, pAdapter->sessionId, status);
4925 /* change back to NotAssociated */
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +05304926 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08004927 eConnectionState_NotConnected);
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +05304928 }
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -08004929
4930 pRoamProfile->ChannelInfo.ChannelList = NULL;
4931 pRoamProfile->ChannelInfo.numOfChannels = 0;
4932
Jeff Johnson295189b2012-06-20 16:38:30 -07004933 }
4934 else
4935 {
4936 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid Roam profile", __func__);
4937 return -EINVAL;
4938 }
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08004939 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07004940 return status;
4941}
4942
4943/*
4944 * FUNCTION: wlan_hdd_set_cfg80211_auth_type
4945 * This function is used to set the authentication type (OPEN/SHARED).
4946 *
4947 */
4948static int wlan_hdd_cfg80211_set_auth_type(hdd_adapter_t *pAdapter,
4949 enum nl80211_auth_type auth_type)
4950{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304951 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07004952 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4953
4954 ENTER();
4955
4956 /*set authentication type*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304957 switch (auth_type)
Jeff Johnson295189b2012-06-20 16:38:30 -07004958 {
Jeff Johnson295189b2012-06-20 16:38:30 -07004959 case NL80211_AUTHTYPE_AUTOMATIC:
Gopichand Nakkala29149562013-05-10 21:43:41 +05304960 hddLog(VOS_TRACE_LEVEL_INFO,
4961 "%s: set authentication type to AUTOSWITCH", __func__);
4962 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_AUTOSWITCH;
4963 break;
4964
4965 case NL80211_AUTHTYPE_OPEN_SYSTEM:
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07004966#ifdef WLAN_FEATURE_VOWIFI_11R
4967 case NL80211_AUTHTYPE_FT:
4968#endif /* WLAN_FEATURE_VOWIFI_11R */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304969 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -07004970 "%s: set authentication type to OPEN", __func__);
4971 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
4972 break;
4973
4974 case NL80211_AUTHTYPE_SHARED_KEY:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304975 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -07004976 "%s: set authentication type to SHARED", __func__);
4977 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_SHARED_KEY;
4978 break;
4979#ifdef FEATURE_WLAN_CCX
4980 case NL80211_AUTHTYPE_NETWORK_EAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304981 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -07004982 "%s: set authentication type to CCKM WPA", __func__);
4983 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_CCKM_WPA;//eCSR_AUTH_TYPE_CCKM_RSN needs to be handled as well if required.
4984 break;
4985#endif
4986
4987
4988 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304989 hddLog(VOS_TRACE_LEVEL_ERROR,
4990 "%s: Unsupported authentication type %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07004991 auth_type);
4992 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_UNKNOWN;
4993 return -EINVAL;
4994 }
4995
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304996 pWextState->roamProfile.AuthType.authType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -07004997 pHddStaCtx->conn_info.authType;
4998 return 0;
4999}
5000
5001/*
5002 * FUNCTION: wlan_hdd_set_akm_suite
5003 * This function is used to set the key mgmt type(PSK/8021x).
5004 *
5005 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305006static int wlan_hdd_set_akm_suite( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07005007 u32 key_mgmt
5008 )
5009{
5010 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
5011 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305012
Jeff Johnson295189b2012-06-20 16:38:30 -07005013 /*set key mgmt type*/
5014 switch(key_mgmt)
5015 {
5016 case WLAN_AKM_SUITE_PSK:
Gopichand Nakkala356fb102013-03-06 12:34:04 +05305017#ifdef WLAN_FEATURE_VOWIFI_11R
5018 case WLAN_AKM_SUITE_FT_PSK:
5019#endif
5020 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to PSK",
Jeff Johnson295189b2012-06-20 16:38:30 -07005021 __func__);
5022 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_PSK;
5023 break;
5024
5025 case WLAN_AKM_SUITE_8021X:
Gopichand Nakkala356fb102013-03-06 12:34:04 +05305026#ifdef WLAN_FEATURE_VOWIFI_11R
5027 case WLAN_AKM_SUITE_FT_8021X:
5028#endif
5029 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to 8021x",
Jeff Johnson295189b2012-06-20 16:38:30 -07005030 __func__);
5031 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
5032 break;
5033#ifdef FEATURE_WLAN_CCX
5034#define WLAN_AKM_SUITE_CCKM 0x00409600 /* Should be in ieee802_11_defs.h */
5035#define IW_AUTH_KEY_MGMT_CCKM 8 /* Should be in linux/wireless.h */
5036 case WLAN_AKM_SUITE_CCKM:
5037 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to CCKM",
5038 __func__);
5039 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_CCKM;
5040 break;
5041#endif
5042
5043 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305044 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported key mgmt type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07005045 __func__, key_mgmt);
5046 return -EINVAL;
5047
5048 }
5049 return 0;
5050}
5051
5052/*
5053 * FUNCTION: wlan_hdd_cfg80211_set_cipher
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305054 * This function is used to set the encryption type
Jeff Johnson295189b2012-06-20 16:38:30 -07005055 * (NONE/WEP40/WEP104/TKIP/CCMP).
5056 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305057static int wlan_hdd_cfg80211_set_cipher( hdd_adapter_t *pAdapter,
5058 u32 cipher,
Jeff Johnson295189b2012-06-20 16:38:30 -07005059 bool ucast
5060 )
5061{
5062 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305063 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07005064 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
5065
5066 ENTER();
5067
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305068 if (!cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -07005069 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305070 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: received cipher %d - considering none",
Jeff Johnson295189b2012-06-20 16:38:30 -07005071 __func__, cipher);
5072 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
5073 }
5074 else
5075 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305076
Jeff Johnson295189b2012-06-20 16:38:30 -07005077 /*set encryption method*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305078 switch (cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -07005079 {
5080 case IW_AUTH_CIPHER_NONE:
5081 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
5082 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305083
Jeff Johnson295189b2012-06-20 16:38:30 -07005084 case WLAN_CIPHER_SUITE_WEP40:
Gopichand Nakkala29149562013-05-10 21:43:41 +05305085 encryptionType = eCSR_ENCRYPT_TYPE_WEP40;
Jeff Johnson295189b2012-06-20 16:38:30 -07005086 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305087
Jeff Johnson295189b2012-06-20 16:38:30 -07005088 case WLAN_CIPHER_SUITE_WEP104:
Gopichand Nakkala29149562013-05-10 21:43:41 +05305089 encryptionType = eCSR_ENCRYPT_TYPE_WEP104;
Jeff Johnson295189b2012-06-20 16:38:30 -07005090 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305091
Jeff Johnson295189b2012-06-20 16:38:30 -07005092 case WLAN_CIPHER_SUITE_TKIP:
5093 encryptionType = eCSR_ENCRYPT_TYPE_TKIP;
5094 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305095
Jeff Johnson295189b2012-06-20 16:38:30 -07005096 case WLAN_CIPHER_SUITE_CCMP:
5097 encryptionType = eCSR_ENCRYPT_TYPE_AES;
5098 break;
5099#ifdef FEATURE_WLAN_WAPI
5100 case WLAN_CIPHER_SUITE_SMS4:
5101 encryptionType = eCSR_ENCRYPT_TYPE_WPI;
5102 break;
5103#endif
5104
5105#ifdef FEATURE_WLAN_CCX
5106 case WLAN_CIPHER_SUITE_KRK:
5107 encryptionType = eCSR_ENCRYPT_TYPE_KRK;
5108 break;
5109#endif
5110 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305111 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported cipher type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07005112 __func__, cipher);
5113 return -EOPNOTSUPP;
5114 }
5115 }
5116
5117 if (ucast)
5118 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305119 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting unicast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07005120 __func__, encryptionType);
5121 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
5122 pWextState->roamProfile.EncryptionType.numEntries = 1;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305123 pWextState->roamProfile.EncryptionType.encryptionType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -07005124 encryptionType;
5125 }
5126 else
5127 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305128 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting mcast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07005129 __func__, encryptionType);
5130 pHddStaCtx->conn_info.mcEncryptionType = encryptionType;
5131 pWextState->roamProfile.mcEncryptionType.numEntries = 1;
5132 pWextState->roamProfile.mcEncryptionType.encryptionType[0] = encryptionType;
5133 }
5134
5135 return 0;
5136}
5137
5138
5139/*
5140 * FUNCTION: wlan_hdd_cfg80211_set_ie
5141 * This function is used to parse WPA/RSN IE's.
5142 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305143int wlan_hdd_cfg80211_set_ie( hdd_adapter_t *pAdapter,
5144 u8 *ie,
Jeff Johnson295189b2012-06-20 16:38:30 -07005145 size_t ie_len
5146 )
5147{
5148 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
5149 u8 *genie = ie;
5150 v_U16_t remLen = ie_len;
5151#ifdef FEATURE_WLAN_WAPI
5152 v_U32_t akmsuite[MAX_NUM_AKM_SUITES];
5153 u16 *tmp;
5154 v_U16_t akmsuiteCount;
5155 int *akmlist;
5156#endif
5157 ENTER();
5158
5159 /* clear previous assocAddIE */
5160 pWextState->assocAddIE.length = 0;
5161 pWextState->roamProfile.bWPSAssociation = VOS_FALSE;
5162
5163 while (remLen >= 2)
5164 {
5165 v_U16_t eLen = 0;
5166 v_U8_t elementId;
5167 elementId = *genie++;
5168 eLen = *genie++;
5169 remLen -= 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305170
5171 hddLog(VOS_TRACE_LEVEL_INFO, "%s: IE[0x%X], LEN[%d]\n",
Jeff Johnson295189b2012-06-20 16:38:30 -07005172 __func__, elementId, eLen);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305173
5174 switch ( elementId )
Jeff Johnson295189b2012-06-20 16:38:30 -07005175 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305176 case DOT11F_EID_WPA:
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005177 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 -07005178 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305179 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07005180 "%s: Invalid WPA IE", __func__);
5181 return -EINVAL;
5182 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305183 else if (0 == memcmp(&genie[0], "\x00\x50\xf2\x04", 4))
Jeff Johnson295189b2012-06-20 16:38:30 -07005184 {
5185 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305186 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPS IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -07005187 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305188
Jeff Johnson295189b2012-06-20 16:38:30 -07005189 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
5190 {
Jeff Johnson902c9832012-12-10 14:28:09 -08005191 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE. "
5192 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -07005193 VOS_ASSERT(0);
5194 return -ENOMEM;
5195 }
5196 // WSC IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
5197 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
5198 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305199
Jeff Johnson295189b2012-06-20 16:38:30 -07005200 pWextState->roamProfile.bWPSAssociation = VOS_TRUE;
5201 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
5202 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
5203 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305204 else if (0 == memcmp(&genie[0], "\x00\x50\xf2", 3))
5205 {
Jeff Johnson295189b2012-06-20 16:38:30 -07005206 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPA IE (len %d)",__func__, eLen + 2);
5207 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
5208 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2) /*ie_len*/);
5209 pWextState->roamProfile.pWPAReqIE = pWextState->WPARSNIE;
5210 pWextState->roamProfile.nWPAReqIELength = eLen + 2;//ie_len;
5211 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305212 else if ( (0 == memcmp(&genie[0], P2P_OUI_TYPE,
5213 P2P_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07005214 /*Consider P2P IE, only for P2P Client */
5215 && (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
5216 {
5217 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305218 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set P2P IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -07005219 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305220
Jeff Johnson295189b2012-06-20 16:38:30 -07005221 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
5222 {
Jeff Johnson902c9832012-12-10 14:28:09 -08005223 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
5224 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -07005225 VOS_ASSERT(0);
5226 return -ENOMEM;
5227 }
5228 // P2P IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
5229 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
5230 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305231
Jeff Johnson295189b2012-06-20 16:38:30 -07005232 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
5233 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
5234 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005235#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305236 else if ( (0 == memcmp(&genie[0], WFD_OUI_TYPE,
5237 WFD_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07005238 /*Consider WFD IE, only for P2P Client */
5239 && (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
5240 {
5241 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305242 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WFD IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -07005243 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305244
Jeff Johnson295189b2012-06-20 16:38:30 -07005245 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
5246 {
Jeff Johnson902c9832012-12-10 14:28:09 -08005247 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
5248 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -07005249 VOS_ASSERT(0);
5250 return -ENOMEM;
5251 }
5252 // WFD IE is saved to Additional IE ; it should be accumulated to handle
5253 // WPS IE + P2P IE + WFD IE
5254 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
5255 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305256
Jeff Johnson295189b2012-06-20 16:38:30 -07005257 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
5258 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
5259 }
5260#endif
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005261 /* Appending HS 2.0 Indication Element in Assiciation Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305262 else if ( (0 == memcmp(&genie[0], HS20_OUI_TYPE,
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07005263 HS20_OUI_TYPE_SIZE)) )
5264 {
5265 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305266 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set HS20 IE(len %d)",
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07005267 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005268
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07005269 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
5270 {
Jeff Johnson902c9832012-12-10 14:28:09 -08005271 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
5272 "Need bigger buffer space");
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07005273 VOS_ASSERT(0);
5274 return -ENOMEM;
5275 }
5276 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
5277 pWextState->assocAddIE.length += eLen + 2;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005278
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07005279 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
5280 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
5281 }
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005282
Jeff Johnson295189b2012-06-20 16:38:30 -07005283 break;
5284 case DOT11F_EID_RSN:
5285 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set RSN IE(len %d)",__func__, eLen + 2);
5286 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
5287 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2)/*ie_len*/);
5288 pWextState->roamProfile.pRSNReqIE = pWextState->WPARSNIE;
5289 pWextState->roamProfile.nRSNReqIELength = eLen + 2; //ie_len;
5290 break;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005291 /* Appending Extended Capabilities with Interworking bit set in Assoc Req */
5292 case DOT11F_EID_EXTCAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305293 {
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005294 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305295 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set Extended CAPS IE(len %d)",
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005296 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305297
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005298 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
5299 {
Jeff Johnson902c9832012-12-10 14:28:09 -08005300 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
5301 "Need bigger buffer space");
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005302 VOS_ASSERT(0);
5303 return -ENOMEM;
5304 }
5305 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
5306 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305307
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005308 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
5309 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
5310 break;
5311 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005312#ifdef FEATURE_WLAN_WAPI
5313 case WLAN_EID_WAPI:
5314 pAdapter->wapi_info.nWapiMode = 1; //Setting WAPI Mode to ON=1
5315 hddLog(VOS_TRACE_LEVEL_INFO,"WAPI MODE IS %lu \n",
5316 pAdapter->wapi_info.nWapiMode);
5317 tmp = (u16 *)ie;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305318 tmp = tmp + 2; // Skip element Id and Len, Version
Jeff Johnson295189b2012-06-20 16:38:30 -07005319 akmsuiteCount = WPA_GET_LE16(tmp);
5320 tmp = tmp + 1;
5321 akmlist = (int *)(tmp);
5322 if(akmsuiteCount <= MAX_NUM_AKM_SUITES)
5323 {
5324 memcpy(akmsuite, akmlist, (4*akmsuiteCount));
5325 }
5326 else
5327 {
5328 hddLog(VOS_TRACE_LEVEL_FATAL, "Invalid akmSuite count\n");
5329 VOS_ASSERT(0);
5330 return -EINVAL;
5331 }
5332
5333 if (WAPI_PSK_AKM_SUITE == akmsuite[0])
5334 {
5335 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO PSK",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005336 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005337 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_PSK;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305338 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005339 if (WAPI_CERT_AKM_SUITE == akmsuite[0])
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305340 {
Jeff Johnson295189b2012-06-20 16:38:30 -07005341 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO CERTIFICATE",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005342 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005343 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_CERT;
5344 }
5345 break;
5346#endif
5347 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305348 hddLog (VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07005349 "%s Set UNKNOWN IE %X", __func__, elementId);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005350 /* when Unknown IE is received we should break and continue
5351 * to the next IE in the buffer instead we were returning
5352 * so changing this to break */
5353 break;
Jeff Johnson295189b2012-06-20 16:38:30 -07005354 }
5355 genie += eLen;
5356 remLen -= eLen;
5357 }
5358 EXIT();
5359 return 0;
5360}
5361
5362/*
Gopichand Nakkala18f0c262013-05-07 23:25:08 +05305363 * FUNCTION: hdd_isWPAIEPresent
5364 * Parse the received IE to find the WPA IE
5365 *
5366 */
5367static bool hdd_isWPAIEPresent(u8 *ie, u8 ie_len)
5368{
5369 v_U8_t eLen = 0;
5370 v_U16_t remLen = ie_len;
5371 v_U8_t elementId = 0;
5372
5373 while (remLen >= 2)
5374 {
5375 elementId = *ie++;
5376 eLen = *ie++;
5377 remLen -= 2;
5378 if (eLen > remLen)
5379 {
5380 hddLog(VOS_TRACE_LEVEL_ERROR,
5381 "%s: IE length is wrong %d", __func__, eLen);
5382 return FALSE;
5383 }
5384 if ((elementId == DOT11F_EID_WPA) && (remLen > 5))
5385 {
5386 /* OUI - 0x00 0X50 0XF2
5387 WPA Information Element - 0x01
5388 WPA version - 0x01*/
5389 if (0 == memcmp(&ie[0], "\x00\x50\xf2\x01\x01", 5))
5390 return TRUE;
5391 }
5392 ie += eLen;
5393 remLen -= eLen;
5394 }
5395 return FALSE;
5396}
5397
5398/*
Jeff Johnson295189b2012-06-20 16:38:30 -07005399 * FUNCTION: wlan_hdd_cfg80211_set_privacy
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305400 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -07005401 * parameters during connect operation.
5402 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305403int wlan_hdd_cfg80211_set_privacy( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07005404 struct cfg80211_connect_params *req
5405 )
5406{
5407 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305408 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07005409 ENTER();
5410
5411 /*set wpa version*/
5412 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
5413
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305414 if (req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -07005415 {
5416 if ( (NL80211_WPA_VERSION_1 == req->crypto.wpa_versions)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305417 && ( (req->ie_len)
Gopichand Nakkala18f0c262013-05-07 23:25:08 +05305418 && (hdd_isWPAIEPresent(req->ie, req->ie_len) ) ) )
Jeff Johnson295189b2012-06-20 16:38:30 -07005419 // Make sure that it is including a WPA IE.
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305420 /* Currently NL is putting WPA version 1 even for open,
Jeff Johnson295189b2012-06-20 16:38:30 -07005421 * since p2p ie is also put in same buffer.
5422 * */
5423 {
5424 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
5425 }
5426 else if (NL80211_WPA_VERSION_2 == req->crypto.wpa_versions)
5427 {
5428 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
5429 }
5430 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305431
5432 hddLog(VOS_TRACE_LEVEL_INFO, "%s: set wpa version to %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07005433 pWextState->wpaVersion);
5434
5435 /*set authentication type*/
5436 status = wlan_hdd_cfg80211_set_auth_type(pAdapter, req->auth_type);
5437
5438 if (0 > status)
5439 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305440 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07005441 "%s: failed to set authentication type ", __func__);
5442 return status;
5443 }
5444
5445 /*set key mgmt type*/
5446 if (req->crypto.n_akm_suites)
5447 {
5448 status = wlan_hdd_set_akm_suite(pAdapter, req->crypto.akm_suites[0]);
5449 if (0 > status)
5450 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305451 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set akm suite",
Jeff Johnson295189b2012-06-20 16:38:30 -07005452 __func__);
5453 return status;
5454 }
5455 }
5456
5457 /*set pairwise cipher type*/
5458 if (req->crypto.n_ciphers_pairwise)
5459 {
5460 status = wlan_hdd_cfg80211_set_cipher(pAdapter,
5461 req->crypto.ciphers_pairwise[0], true);
5462 if (0 > status)
5463 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305464 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07005465 "%s: failed to set unicast cipher type", __func__);
5466 return status;
5467 }
5468 }
5469 else
5470 {
5471 /*Reset previous cipher suite to none*/
5472 status = wlan_hdd_cfg80211_set_cipher(pAdapter, 0, true);
5473 if (0 > status)
5474 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305475 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07005476 "%s: failed to set unicast cipher type", __func__);
5477 return status;
5478 }
5479 }
5480
5481 /*set group cipher type*/
5482 status = wlan_hdd_cfg80211_set_cipher(pAdapter, req->crypto.cipher_group,
5483 false);
5484
5485 if (0 > status)
5486 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305487 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set mcast cipher type",
Jeff Johnson295189b2012-06-20 16:38:30 -07005488 __func__);
5489 return status;
5490 }
5491
Chet Lanctot186b5732013-03-18 10:26:30 -07005492#ifdef WLAN_FEATURE_11W
5493 pWextState->roamProfile.MFPEnabled = (req->mfp == NL80211_MFP_REQUIRED);
5494#endif
5495
Jeff Johnson295189b2012-06-20 16:38:30 -07005496 /*parse WPA/RSN IE, and set the correspoing fileds in Roam profile*/
5497 if (req->ie_len)
5498 {
5499 status = wlan_hdd_cfg80211_set_ie(pAdapter, req->ie, req->ie_len);
5500 if ( 0 > status)
5501 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305502 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse the WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -07005503 __func__);
5504 return status;
5505 }
5506 }
5507
5508 /*incase of WEP set default key information*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305509 if (req->key && req->key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -07005510 {
5511 if ( (WLAN_CIPHER_SUITE_WEP40 == req->crypto.ciphers_pairwise[0])
5512 || (WLAN_CIPHER_SUITE_WEP104 == req->crypto.ciphers_pairwise[0])
5513 )
5514 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305515 if ( IW_AUTH_KEY_MGMT_802_1X
Jeff Johnson295189b2012-06-20 16:38:30 -07005516 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X ))
5517 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305518 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Dynamic WEP not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -07005519 __func__);
5520 return -EOPNOTSUPP;
5521 }
5522 else
5523 {
5524 u8 key_len = req->key_len;
5525 u8 key_idx = req->key_idx;
5526
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305527 if ((eCSR_SECURITY_WEP_KEYSIZE_MAX_BYTES >= key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -07005528 && (CSR_MAX_NUM_KEY > key_idx)
5529 )
5530 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305531 hddLog(VOS_TRACE_LEVEL_INFO,
5532 "%s: setting default wep key, key_idx = %hu key_len %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07005533 __func__, key_idx, key_len);
5534 vos_mem_copy(
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305535 &pWextState->roamProfile.Keys.KeyMaterial[key_idx][0],
Jeff Johnson295189b2012-06-20 16:38:30 -07005536 req->key, key_len);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305537 pWextState->roamProfile.Keys.KeyLength[key_idx] =
Jeff Johnson295189b2012-06-20 16:38:30 -07005538 (u8)key_len;
5539 pWextState->roamProfile.Keys.defaultIndex = (u8)key_idx;
5540 }
5541 }
5542 }
5543 }
5544
5545 return status;
5546}
5547
5548/*
5549 * FUNCTION: wlan_hdd_cfg80211_set_privacy
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305550 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -07005551 * parameters during connect operation.
5552 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305553static int wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07005554 struct net_device *ndev,
5555 struct cfg80211_connect_params *req
5556 )
5557{
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305558 int status;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305559 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -07005560 VOS_STATUS exitbmpsStatus = VOS_STATUS_E_INVAL;
5561 hdd_context_t *pHddCtx = NULL;
5562
5563 ENTER();
5564
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305565 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -07005566 "%s: device_mode = %d\n",__func__,pAdapter->device_mode);
5567
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305568 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
5569 status = wlan_hdd_validate_context(pHddCtx);
5570
5571 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -07005572 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305573 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5574 "%s: HDD context is not valid", __func__);
5575 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -07005576 }
5577
5578#ifdef WLAN_BTAMP_FEATURE
5579 //Infra connect not supported when AMP traffic is on.
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305580 if( VOS_TRUE == WLANBAP_AmpSessionOn() )
Jeff Johnson295189b2012-06-20 16:38:30 -07005581 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305582 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07005583 "%s: No connection when AMP is on", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08005584 return -ECONNREFUSED;
Jeff Johnson295189b2012-06-20 16:38:30 -07005585 }
5586#endif
5587 /*initialise security parameters*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305588 status = wlan_hdd_cfg80211_set_privacy(pAdapter, req);
Jeff Johnson295189b2012-06-20 16:38:30 -07005589
5590 if ( 0 > status)
5591 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305592 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security params",
Jeff Johnson295189b2012-06-20 16:38:30 -07005593 __func__);
5594 return status;
5595 }
5596
5597 //If Device Mode is Station Concurrent Sessions Exit BMps
Jeff Johnsona8a1a482012-12-12 16:49:33 -08005598 //P2P Mode will be taken care in Open/close adapter
Jeff Johnson295189b2012-06-20 16:38:30 -07005599 if((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
5600 (vos_concurrent_sessions_running()))
5601 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305602 exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
Jeff Johnson295189b2012-06-20 16:38:30 -07005603 }
5604
Mohit Khanna765234a2012-09-11 15:08:35 -07005605 if ( req->channel )
5606 {
5607 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
5608 req->ssid_len, req->bssid,
5609 req->channel->hw_value);
5610 }
5611 else
5612 {
5613 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305614 req->ssid_len, req->bssid, 0);
Mohit Khanna765234a2012-09-11 15:08:35 -07005615 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005616
5617 if (0 > status)
5618 {
5619 //ReEnable BMPS if disabled
5620 if((VOS_STATUS_SUCCESS == exitbmpsStatus) &&
5621 (NULL != pHddCtx))
5622 {
5623 //ReEnable Bmps and Imps back
5624 hdd_enable_bmps_imps(pHddCtx);
5625 }
5626
5627 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: connect failed", __func__);
5628 return status;
5629 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305630 pHddCtx->isAmpAllowed = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07005631 EXIT();
5632 return status;
5633}
5634
5635
5636/*
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05305637 * FUNCTION: wlan_hdd_disconnect
5638 * This function is used to issue a disconnect request to SME
5639 */
5640int wlan_hdd_disconnect( hdd_adapter_t *pAdapter, u16 reason )
5641{
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305642 int status;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05305643 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305644 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
5645
5646 status = wlan_hdd_validate_context(pHddCtx);
5647
5648 if (0 != status)
5649 {
5650 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5651 "%s: HDD context is not valid", __func__);
5652 return status;
5653 }
5654
5655 pHddCtx->isAmpAllowed = VOS_TRUE;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05305656 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05305657 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305658
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05305659 /*issue disconnect*/
5660 status = sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
5661 pAdapter->sessionId, reason);
5662
5663 if ( 0 != status )
5664 {
5665 hddLog(VOS_TRACE_LEVEL_ERROR,
5666 "%s csrRoamDisconnect failure, returned %d \n",
5667 __func__, (int)status );
5668 return -EINVAL;
5669 }
5670 wait_for_completion_interruptible_timeout(
5671 &pAdapter->disconnect_comp_var,
5672 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
5673 /*stop tx queues*/
5674 netif_tx_disable(pAdapter->dev);
5675 netif_carrier_off(pAdapter->dev);
5676 return status;
5677}
5678
5679
5680/*
Jeff Johnson295189b2012-06-20 16:38:30 -07005681 * FUNCTION: wlan_hdd_cfg80211_disconnect
5682 * This function is used to issue a disconnect request to SME
5683 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305684static int wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07005685 struct net_device *dev,
5686 u16 reason
5687 )
5688{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305689 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
5690 tCsrRoamProfile *pRoamProfile =
Jeff Johnson295189b2012-06-20 16:38:30 -07005691 &(WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter))->roamProfile;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305692 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07005693 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkala4327a152013-03-04 23:22:42 -08005694 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaaa353782013-05-17 20:36:22 +05305695#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08005696 tANI_U8 staIdx;
5697#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305698
Jeff Johnson295189b2012-06-20 16:38:30 -07005699 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305700
5701 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",
Jeff Johnson295189b2012-06-20 16:38:30 -07005702 __func__,pAdapter->device_mode);
5703
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305704 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Disconnect called with reason code %d",
5705 __func__, reason);
Jeff Johnson295189b2012-06-20 16:38:30 -07005706
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305707 status = wlan_hdd_validate_context(pHddCtx);
5708
5709 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -07005710 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305711 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5712 "%s: HDD context is not valid", __func__);
5713 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -07005714 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305715
Jeff Johnson295189b2012-06-20 16:38:30 -07005716 if (NULL != pRoamProfile)
5717 {
5718 /*issue disconnect request to SME, if station is in connected state*/
5719 if (pHddStaCtx->conn_info.connState == eConnectionState_Associated)
5720 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305721 eCsrRoamDisconnectReason reasonCode =
Jeff Johnson295189b2012-06-20 16:38:30 -07005722 eCSR_DISCONNECT_REASON_UNSPECIFIED;
Gopichand Nakkalaaa353782013-05-17 20:36:22 +05305723 hdd_scaninfo_t *pScanInfo;
Jeff Johnson295189b2012-06-20 16:38:30 -07005724 switch(reason)
5725 {
5726 case WLAN_REASON_MIC_FAILURE:
5727 reasonCode = eCSR_DISCONNECT_REASON_MIC_ERROR;
5728 break;
5729
5730 case WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY:
5731 case WLAN_REASON_DISASSOC_AP_BUSY:
5732 case WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA:
5733 reasonCode = eCSR_DISCONNECT_REASON_DISASSOC;
5734 break;
5735
5736 case WLAN_REASON_PREV_AUTH_NOT_VALID:
5737 case WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA:
5738 reasonCode = eCSR_DISCONNECT_REASON_DEAUTH;
5739 break;
5740
5741 case WLAN_REASON_DEAUTH_LEAVING:
5742 default:
5743 reasonCode = eCSR_DISCONNECT_REASON_UNSPECIFIED;
5744 break;
5745 }
Gopichand Nakkalaaa353782013-05-17 20:36:22 +05305746 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
5747 pScanInfo = &pHddCtx->scan_info;
5748 if (pScanInfo->mScanPending)
5749 {
5750 hddLog(VOS_TRACE_LEVEL_INFO, "Disconnect is in progress, "
5751 "Aborting Scan");
5752 hdd_abort_mac_scan(pHddCtx);
5753 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005754
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08005755#ifdef FEATURE_WLAN_TDLS
5756 /* First clean up the tdls peers if any */
Gopichand Nakkala4327a152013-03-04 23:22:42 -08005757 for (staIdx = 0 ; staIdx < HDD_MAX_NUM_TDLS_STA; staIdx++)
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08005758 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -08005759 if ((pHddCtx->tdlsConnInfo[staIdx].sessionId == pAdapter->sessionId) &&
5760 (pHddCtx->tdlsConnInfo[staIdx].staId))
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08005761 {
Hoonki Lee11f7dda2013-02-14 16:55:44 -08005762 uint8 *mac;
Gopichand Nakkala4327a152013-03-04 23:22:42 -08005763 mac = pHddCtx->tdlsConnInfo[staIdx].peerMac.bytes;
Hoonki Lee11f7dda2013-02-14 16:55:44 -08005764 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07005765 "%s: call sme_DeleteTdlsPeerSta staId %d sessionId %d " MAC_ADDRESS_STR,
Gopichand Nakkala4327a152013-03-04 23:22:42 -08005766 __func__, pHddCtx->tdlsConnInfo[staIdx].staId, pAdapter->sessionId,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07005767 MAC_ADDR_ARRAY(mac));
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08005768 sme_DeleteTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala4327a152013-03-04 23:22:42 -08005769 pAdapter->sessionId,
5770 mac);
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08005771 }
5772 }
5773#endif
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05305774 status = wlan_hdd_disconnect(pAdapter, reasonCode);
5775 if ( 0 != status )
Jeff Johnson295189b2012-06-20 16:38:30 -07005776 {
5777 hddLog(VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05305778 "%s wlan_hdd_disconnect failure, returned %d \n",
Jeff Johnson295189b2012-06-20 16:38:30 -07005779 __func__, (int)status );
5780 return -EINVAL;
5781 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005782 }
5783 }
5784 else
5785 {
5786 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid roam profile", __func__);
5787 }
5788
5789 return status;
5790}
5791
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05305792
Jeff Johnson295189b2012-06-20 16:38:30 -07005793/*
5794 * FUNCTION: wlan_hdd_cfg80211_set_privacy_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305795 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -07005796 * settings in IBSS mode.
5797 */
5798static int wlan_hdd_cfg80211_set_privacy_ibss(
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305799 hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07005800 struct cfg80211_ibss_params *params
5801 )
5802{
5803 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305804 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07005805 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
5806 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305807
Jeff Johnson295189b2012-06-20 16:38:30 -07005808 ENTER();
5809
5810 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
5811
5812 if (params->ie_len && ( NULL != params->ie) )
5813 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305814 if (WLAN_EID_RSN == params->ie[0])
Jeff Johnson295189b2012-06-20 16:38:30 -07005815 {
5816 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
5817 encryptionType = eCSR_ENCRYPT_TYPE_AES;
5818 }
5819 else
5820 {
5821 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
5822 encryptionType = eCSR_ENCRYPT_TYPE_TKIP;
5823 }
5824 status = wlan_hdd_cfg80211_set_ie(pAdapter, params->ie, params->ie_len);
5825
5826 if (0 > status)
5827 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305828 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -07005829 __func__);
5830 return status;
5831 }
5832 }
5833
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305834 pWextState->roamProfile.AuthType.authType[0] =
5835 pHddStaCtx->conn_info.authType =
Jeff Johnson295189b2012-06-20 16:38:30 -07005836 eCSR_AUTH_TYPE_OPEN_SYSTEM;
5837
5838 if (params->privacy)
5839 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305840 /* Security enabled IBSS, At this time there is no information available
5841 * about the security paramters, so initialise the encryption type to
Jeff Johnson295189b2012-06-20 16:38:30 -07005842 * eCSR_ENCRYPT_TYPE_WEP40_STATICKEY.
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305843 * The correct security parameters will be updated later in
Jeff Johnson295189b2012-06-20 16:38:30 -07005844 * wlan_hdd_cfg80211_add_key */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305845 /* Hal expects encryption type to be set inorder
Jeff Johnson295189b2012-06-20 16:38:30 -07005846 *enable privacy bit in beacons */
5847
5848 encryptionType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
5849 }
5850
5851 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
5852 pWextState->roamProfile.EncryptionType.numEntries = 1;
5853 pWextState->roamProfile.EncryptionType.encryptionType[0] = encryptionType;
5854
5855 return status;
5856}
5857
5858/*
5859 * FUNCTION: wlan_hdd_cfg80211_join_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305860 * This function is used to create/join an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -07005861 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305862static int wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07005863 struct net_device *dev,
5864 struct cfg80211_ibss_params *params
5865 )
5866{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305867 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Jeff Johnson295189b2012-06-20 16:38:30 -07005868 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
5869 tCsrRoamProfile *pRoamProfile;
5870 int status;
5871 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305872 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07005873
5874 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305875
5876 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -07005877 "%s: device_mode = %d\n",__func__,pAdapter->device_mode);
5878
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305879 status = wlan_hdd_validate_context(pHddCtx);
5880
5881 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -07005882 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305883 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5884 "%s: HDD context is not valid", __func__);
5885 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -07005886 }
5887
5888 if (NULL == pWextState)
5889 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305890 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption\n",
Jeff Johnson295189b2012-06-20 16:38:30 -07005891 __func__);
5892 return -EIO;
5893 }
5894
5895 pRoamProfile = &pWextState->roamProfile;
5896
5897 if ( eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType )
5898 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305899 hddLog (VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07005900 "%s Interface type is not set to IBSS \n", __func__);
5901 return -EINVAL;
5902 }
5903
5904 /* Set Channel */
5905 if (NULL != params->channel)
5906 {
5907 u8 channelNum;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07005908 v_U32_t numChans = WNI_CFG_VALID_CHANNEL_LIST_LEN;
5909 v_U8_t validChan[WNI_CFG_VALID_CHANNEL_LIST_LEN];
5910 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
5911 int indx;
Jeff Johnson295189b2012-06-20 16:38:30 -07005912
5913 /* Get channel number */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305914 channelNum =
Jeff Johnson295189b2012-06-20 16:38:30 -07005915 ieee80211_frequency_to_channel(params->channel->center_freq);
5916
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07005917
5918 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
5919 validChan, &numChans))
Jeff Johnson295189b2012-06-20 16:38:30 -07005920 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07005921 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid channel list",
5922 __func__);
5923 return -EOPNOTSUPP;
Jeff Johnson295189b2012-06-20 16:38:30 -07005924 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07005925
5926 for (indx = 0; indx < numChans; indx++)
Jeff Johnson295189b2012-06-20 16:38:30 -07005927 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07005928 if (channelNum == validChan[indx])
5929 {
5930 break;
5931 }
5932 }
5933 if (indx >= numChans)
5934 {
5935 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Not valid Channel %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07005936 __func__, channelNum);
5937 return -EINVAL;
5938 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07005939 /* Set the Operational Channel */
5940 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: set channel %d", __func__,
5941 channelNum);
5942 pRoamProfile->ChannelInfo.numOfChannels = 1;
5943 pHddStaCtx->conn_info.operationChannel = channelNum;
5944 pRoamProfile->ChannelInfo.ChannelList =
5945 &pHddStaCtx->conn_info.operationChannel;
Jeff Johnson295189b2012-06-20 16:38:30 -07005946 }
5947
5948 /* Initialize security parameters */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305949 status = wlan_hdd_cfg80211_set_privacy_ibss(pAdapter, params);
Jeff Johnson295189b2012-06-20 16:38:30 -07005950 if (status < 0)
5951 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305952 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security parameters",
Jeff Johnson295189b2012-06-20 16:38:30 -07005953 __func__);
5954 return status;
5955 }
5956
5957 /* Issue connect start */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305958 status = wlan_hdd_cfg80211_connect_start(pAdapter, params->ssid,
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07005959 params->ssid_len, params->bssid,
5960 pHddStaCtx->conn_info.operationChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -07005961
5962 if (0 > status)
5963 {
5964 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: connect failed", __func__);
5965 return status;
5966 }
5967
5968 return 0;
5969}
5970
5971/*
5972 * FUNCTION: wlan_hdd_cfg80211_leave_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305973 * This function is used to leave an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -07005974 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305975static int wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07005976 struct net_device *dev
5977 )
5978{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305979 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Jeff Johnson295189b2012-06-20 16:38:30 -07005980 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
5981 tCsrRoamProfile *pRoamProfile;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305982 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
5983 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07005984
5985 ENTER();
5986
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305987 status = wlan_hdd_validate_context(pHddCtx);
5988
5989 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005990 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05305991 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5992 "%s: HDD context is not valid", __func__);
5993 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005994 }
5995
Jeff Johnson295189b2012-06-20 16:38:30 -07005996 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",__func__,pAdapter->device_mode);
5997 if (NULL == pWextState)
5998 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305999 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption\n",
Jeff Johnson295189b2012-06-20 16:38:30 -07006000 __func__);
6001 return -EIO;
6002 }
6003
6004 pRoamProfile = &pWextState->roamProfile;
6005
6006 /* Issue disconnect only if interface type is set to IBSS */
6007 if (eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType)
6008 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306009 hddLog (VOS_TRACE_LEVEL_ERROR, "%s: BSS Type is not set to IBSS",
Jeff Johnson295189b2012-06-20 16:38:30 -07006010 __func__);
6011 return -EINVAL;
6012 }
6013
6014 /* Issue Disconnect request */
6015 INIT_COMPLETION(pAdapter->disconnect_comp_var);
6016 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
6017 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
6018
6019 return 0;
6020}
6021
6022/*
6023 * FUNCTION: wlan_hdd_cfg80211_set_wiphy_params
6024 * This function is used to set the phy parameters
6025 * (RTS Threshold/FRAG Threshold/Retry Count etc ...)
6026 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306027static int wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07006028 u32 changed)
6029{
6030 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
6031 tHalHandle hHal = pHddCtx->hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306032 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07006033
6034 ENTER();
6035
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306036 status = wlan_hdd_validate_context(pHddCtx);
6037
6038 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006039 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306040 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6041 "%s: HDD context is not valid", __func__);
6042 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006043 }
6044
Jeff Johnson295189b2012-06-20 16:38:30 -07006045 if (changed & WIPHY_PARAM_RTS_THRESHOLD)
6046 {
6047 u16 rts_threshold = (wiphy->rts_threshold == -1) ?
6048 WNI_CFG_RTS_THRESHOLD_STAMAX :
6049 wiphy->rts_threshold;
6050
6051 if ((WNI_CFG_RTS_THRESHOLD_STAMIN > rts_threshold) ||
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306052 (WNI_CFG_RTS_THRESHOLD_STAMAX < rts_threshold))
Jeff Johnson295189b2012-06-20 16:38:30 -07006053 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306054 hddLog(VOS_TRACE_LEVEL_ERROR,
6055 "%s: Invalid RTS Threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07006056 __func__, rts_threshold);
6057 return -EINVAL;
6058 }
6059
6060 if (0 != ccmCfgSetInt(hHal, WNI_CFG_RTS_THRESHOLD,
6061 rts_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306062 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -07006063 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306064 hddLog(VOS_TRACE_LEVEL_ERROR,
6065 "%s: ccmCfgSetInt failed for rts_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07006066 __func__, rts_threshold);
6067 return -EIO;
6068 }
6069
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306070 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set rts threshold %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07006071 rts_threshold);
6072 }
6073
6074 if (changed & WIPHY_PARAM_FRAG_THRESHOLD)
6075 {
6076 u16 frag_threshold = (wiphy->frag_threshold == -1) ?
6077 WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX :
6078 wiphy->frag_threshold;
6079
6080 if ((WNI_CFG_FRAGMENTATION_THRESHOLD_STAMIN > frag_threshold)||
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306081 (WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX < frag_threshold) )
Jeff Johnson295189b2012-06-20 16:38:30 -07006082 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306083 hddLog(VOS_TRACE_LEVEL_ERROR,
6084 "%s: Invalid frag_threshold value %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07006085 frag_threshold);
6086 return -EINVAL;
6087 }
6088
6089 if (0 != ccmCfgSetInt(hHal, WNI_CFG_FRAGMENTATION_THRESHOLD,
6090 frag_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306091 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -07006092 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306093 hddLog(VOS_TRACE_LEVEL_ERROR,
6094 "%s: ccmCfgSetInt failed for frag_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07006095 __func__, frag_threshold);
6096 return -EIO;
6097 }
6098
6099 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set frag threshold %hu", __func__,
6100 frag_threshold);
6101 }
6102
6103 if ((changed & WIPHY_PARAM_RETRY_SHORT)
6104 || (changed & WIPHY_PARAM_RETRY_LONG))
6105 {
6106 u8 retry_value = (changed & WIPHY_PARAM_RETRY_SHORT) ?
6107 wiphy->retry_short :
6108 wiphy->retry_long;
6109
6110 if ((WNI_CFG_LONG_RETRY_LIMIT_STAMIN > retry_value) ||
6111 (WNI_CFG_LONG_RETRY_LIMIT_STAMAX < retry_value))
6112 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306113 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07006114 __func__, retry_value);
6115 return -EINVAL;
6116 }
6117
6118 if (changed & WIPHY_PARAM_RETRY_SHORT)
6119 {
6120 if (0 != ccmCfgSetInt(hHal, WNI_CFG_LONG_RETRY_LIMIT,
6121 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306122 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -07006123 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306124 hddLog(VOS_TRACE_LEVEL_ERROR,
6125 "%s: ccmCfgSetInt failed for long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07006126 __func__, retry_value);
6127 return -EIO;
6128 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306129 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07006130 __func__, retry_value);
6131 }
6132 else if (changed & WIPHY_PARAM_RETRY_SHORT)
6133 {
6134 if (0 != ccmCfgSetInt(hHal, WNI_CFG_SHORT_RETRY_LIMIT,
6135 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306136 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -07006137 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306138 hddLog(VOS_TRACE_LEVEL_ERROR,
6139 "%s: ccmCfgSetInt failed for short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07006140 __func__, retry_value);
6141 return -EIO;
6142 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306143 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07006144 __func__, retry_value);
6145 }
6146 }
6147
6148 return 0;
6149}
6150
6151/*
6152 * FUNCTION: wlan_hdd_cfg80211_set_txpower
6153 * This function is used to set the txpower
6154 */
6155static int wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
6156#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306157 enum tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -07006158#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306159 enum nl80211_tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -07006160#endif
6161 int dbm)
6162{
6163 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306164 tHalHandle hHal = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07006165 tSirMacAddr bssid = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
6166 tSirMacAddr selfMac = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306167 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07006168
6169 ENTER();
6170
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306171 status = wlan_hdd_validate_context(pHddCtx);
6172
6173 if (0 != status)
6174 {
6175 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6176 "%s: HDD context is not valid", __func__);
6177 return status;
6178 }
6179
6180 hHal = pHddCtx->hHal;
6181
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306182 if (0 != ccmCfgSetInt(hHal, WNI_CFG_CURRENT_TX_POWER_LEVEL,
6183 dbm, ccmCfgSetCallback,
6184 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -07006185 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306186 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07006187 "%s: ccmCfgSetInt failed for tx power %hu", __func__, dbm);
6188 return -EIO;
6189 }
6190
6191 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set tx power level %d dbm", __func__,
6192 dbm);
6193
6194 switch(type)
6195 {
6196 case NL80211_TX_POWER_AUTOMATIC: /*automatically determine transmit power*/
6197 /* Fall through */
6198 case NL80211_TX_POWER_LIMITED: /*limit TX power by the mBm parameter*/
6199 if( sme_SetMaxTxPower(hHal, bssid, selfMac, dbm) != eHAL_STATUS_SUCCESS )
6200 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306201 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Setting maximum tx power failed",
6202 __func__);
6203 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -07006204 }
6205 break;
6206 case NL80211_TX_POWER_FIXED: /*fix TX power to the mBm parameter*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306207 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: NL80211_TX_POWER_FIXED not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -07006208 __func__);
6209 return -EOPNOTSUPP;
6210 break;
6211 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306212 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid power setting type %d",
6213 __func__, type);
Jeff Johnson295189b2012-06-20 16:38:30 -07006214 return -EIO;
6215 }
6216
6217 return 0;
6218}
6219
6220/*
6221 * FUNCTION: wlan_hdd_cfg80211_get_txpower
6222 * This function is used to read the txpower
6223 */
6224static int wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy, int *dbm)
6225{
6226
6227 hdd_adapter_t *pAdapter;
6228 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306229 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07006230
Jeff Johnsone7245742012-09-05 17:12:55 -07006231 ENTER();
6232
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306233 status = wlan_hdd_validate_context(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07006234
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306235 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006236 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306237 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6238 "%s: HDD context is not valid", __func__);
6239 *dbm = 0;
6240 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006241 }
6242
Jeff Johnson295189b2012-06-20 16:38:30 -07006243 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
6244 if (NULL == pAdapter)
6245 {
6246 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Not in station context " ,__func__);
6247 return -ENOENT;
6248 }
6249
6250 wlan_hdd_get_classAstats(pAdapter);
6251 *dbm = pAdapter->hdd_stats.ClassA_stat.max_pwr;
6252
Jeff Johnsone7245742012-09-05 17:12:55 -07006253 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07006254 return 0;
6255}
6256
6257static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
6258 u8* mac, struct station_info *sinfo)
6259{
6260 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
6261 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6262 int ssidlen = pHddStaCtx->conn_info.SSID.SSID.length;
6263 tANI_U8 rate_flags;
6264
6265 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
6266 hdd_config_t *pCfg = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -07006267
6268 tANI_U8 OperationalRates[CSR_DOT11_SUPPORTED_RATES_MAX];
6269 tANI_U32 ORLeng = CSR_DOT11_SUPPORTED_RATES_MAX;
6270 tANI_U8 ExtendedRates[CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX];
6271 tANI_U32 ERLeng = CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX;
6272 tANI_U8 MCSRates[SIZE_OF_BASIC_MCS_SET];
6273 tANI_U32 MCSLeng = SIZE_OF_BASIC_MCS_SET;
6274 tANI_U16 maxRate = 0;
6275 tANI_U16 myRate;
6276 tANI_U16 currentRate = 0;
6277 tANI_U8 maxSpeedMCS = 0;
6278 tANI_U8 maxMCSIdx = 0;
6279 tANI_U8 rateFlag = 1;
6280 tANI_U8 i, j, rssidx;
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07006281 tANI_U16 temp;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306282 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07006283
Leo Chang6f8870f2013-03-26 18:11:36 -07006284#ifdef WLAN_FEATURE_11AC
6285 tANI_U32 vht_mcs_map;
6286 eDataRate11ACMaxMcs vhtMaxMcs;
6287#endif /* WLAN_FEATURE_11AC */
6288
Jeff Johnsone7245742012-09-05 17:12:55 -07006289 ENTER();
6290
Jeff Johnson295189b2012-06-20 16:38:30 -07006291 if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) ||
6292 (0 == ssidlen))
6293 {
6294 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Not associated or"
6295 " Invalid ssidlen, %d", __func__, ssidlen);
6296 /*To keep GUI happy*/
6297 return 0;
6298 }
6299
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306300 status = wlan_hdd_validate_context(pHddCtx);
6301
6302 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006303 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306304 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6305 "%s: HDD context is not valid", __func__);
6306 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006307 }
6308
Jeff Johnson295189b2012-06-20 16:38:30 -07006309 wlan_hdd_get_rssi(pAdapter, &sinfo->signal);
6310 sinfo->filled |= STATION_INFO_SIGNAL;
6311
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -07006312 wlan_hdd_get_station_stats(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07006313 rate_flags = pAdapter->hdd_stats.ClassA_stat.tx_rate_flags;
6314
6315 //convert to the UI units of 100kbps
6316 myRate = pAdapter->hdd_stats.ClassA_stat.tx_rate * 5;
6317
6318#ifdef LINKSPEED_DEBUG_ENABLED
Leo Chang6f8870f2013-03-26 18:11:36 -07006319 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 -07006320 sinfo->signal,
6321 pCfg->reportMaxLinkSpeed,
6322 myRate,
6323 (int) pCfg->linkSpeedRssiHigh,
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07006324 (int) pCfg->linkSpeedRssiMid,
6325 (int) pCfg->linkSpeedRssiLow,
Leo Chang6f8870f2013-03-26 18:11:36 -07006326 (int) rate_flags,
6327 (int) pAdapter->hdd_stats.ClassA_stat.mcs_index);
Jeff Johnson295189b2012-06-20 16:38:30 -07006328#endif //LINKSPEED_DEBUG_ENABLED
6329
6330 if (eHDD_LINK_SPEED_REPORT_ACTUAL != pCfg->reportMaxLinkSpeed)
6331 {
6332 // we do not want to necessarily report the current speed
6333 if (eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed)
6334 {
6335 // report the max possible speed
6336 rssidx = 0;
6337 }
6338 else if (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed)
6339 {
6340 // report the max possible speed with RSSI scaling
6341 if (sinfo->signal >= pCfg->linkSpeedRssiHigh)
6342 {
6343 // report the max possible speed
6344 rssidx = 0;
6345 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07006346 else if (sinfo->signal >= pCfg->linkSpeedRssiMid)
Jeff Johnson295189b2012-06-20 16:38:30 -07006347 {
6348 // report middle speed
6349 rssidx = 1;
6350 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07006351 else if (sinfo->signal >= pCfg->linkSpeedRssiLow)
6352 {
6353 // report middle speed
6354 rssidx = 2;
6355 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006356 else
6357 {
6358 // report actual speed
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07006359 rssidx = 3;
Jeff Johnson295189b2012-06-20 16:38:30 -07006360 }
6361 }
6362 else
6363 {
6364 // unknown, treat as eHDD_LINK_SPEED_REPORT_MAX
6365 hddLog(VOS_TRACE_LEVEL_ERROR,
6366 "%s: Invalid value for reportMaxLinkSpeed: %u",
6367 __func__, pCfg->reportMaxLinkSpeed);
6368 rssidx = 0;
6369 }
6370
6371 maxRate = 0;
6372
6373 /* Get Basic Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +05306374 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_OPERATIONAL_RATE_SET,
6375 OperationalRates, &ORLeng))
6376 {
6377 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
6378 /*To keep GUI happy*/
6379 return 0;
6380 }
6381
Jeff Johnson295189b2012-06-20 16:38:30 -07006382 for (i = 0; i < ORLeng; i++)
6383 {
Jeff Johnsone7245742012-09-05 17:12:55 -07006384 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -07006385 {
6386 /* Validate Rate Set */
6387 if (supported_data_rate[j].beacon_rate_index == (OperationalRates[i] & 0x7F))
6388 {
6389 currentRate = supported_data_rate[j].supported_rate[rssidx];
6390 break;
6391 }
6392 }
6393 /* Update MAX rate */
6394 maxRate = (currentRate > maxRate)?currentRate:maxRate;
6395 }
6396
6397 /* Get Extended Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +05306398 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET,
6399 ExtendedRates, &ERLeng))
6400 {
6401 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
6402 /*To keep GUI happy*/
6403 return 0;
6404 }
6405
Jeff Johnson295189b2012-06-20 16:38:30 -07006406 for (i = 0; i < ERLeng; i++)
6407 {
Jeff Johnsone7245742012-09-05 17:12:55 -07006408 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -07006409 {
6410 if (supported_data_rate[j].beacon_rate_index == (ExtendedRates[i] & 0x7F))
6411 {
6412 currentRate = supported_data_rate[j].supported_rate[rssidx];
6413 break;
6414 }
6415 }
6416 /* Update MAX rate */
6417 maxRate = (currentRate > maxRate)?currentRate:maxRate;
6418 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006419 /* Get MCS Rate Set -- but only if we are connected at MCS
6420 rates or if we are always reporting max speed or if we have
6421 good rssi */
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07006422 if ((0 == rssidx) && !(rate_flags & eHAL_TX_RATE_LEGACY))
Jeff Johnson295189b2012-06-20 16:38:30 -07006423 {
Gopichand Nakkala05ab1322013-02-15 11:28:38 +05306424 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_CURRENT_MCS_SET,
6425 MCSRates, &MCSLeng))
6426 {
6427 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
6428 /*To keep GUI happy*/
6429 return 0;
6430 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006431 rateFlag = 0;
Leo Chang6f8870f2013-03-26 18:11:36 -07006432#ifdef WLAN_FEATURE_11AC
6433 /* VHT80 rate has seperate rate table */
Gopichand Nakkala4c705372013-04-24 13:20:33 +05306434 if (rate_flags & (eHAL_TX_RATE_VHT20|eHAL_TX_RATE_VHT40|eHAL_TX_RATE_VHT80))
Jeff Johnson295189b2012-06-20 16:38:30 -07006435 {
Leo Chang6f8870f2013-03-26 18:11:36 -07006436 ccmCfgGetInt(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_VHT_TX_MCS_MAP, &vht_mcs_map);
Gopichand Nakkala4c705372013-04-24 13:20:33 +05306437 vhtMaxMcs = (eDataRate11ACMaxMcs)(vht_mcs_map & DATA_RATE_11AC_MCS_MASK );
Leo Chang6f8870f2013-03-26 18:11:36 -07006438 if (rate_flags & eHAL_TX_RATE_SGI)
Jeff Johnson295189b2012-06-20 16:38:30 -07006439 {
Leo Chang6f8870f2013-03-26 18:11:36 -07006440 rateFlag |= 1;
Jeff Johnson295189b2012-06-20 16:38:30 -07006441 }
Leo Chang6f8870f2013-03-26 18:11:36 -07006442 if (DATA_RATE_11AC_MAX_MCS_7 == vhtMaxMcs)
Jeff Johnson295189b2012-06-20 16:38:30 -07006443 {
Leo Chang6f8870f2013-03-26 18:11:36 -07006444 maxMCSIdx = 7;
6445 }
6446 else if (DATA_RATE_11AC_MAX_MCS_8 == vhtMaxMcs)
6447 {
6448 maxMCSIdx = 8;
6449 }
6450 else if (DATA_RATE_11AC_MAX_MCS_9 == vhtMaxMcs)
6451 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +05306452 //VHT20 is supporting 0~8
6453 if (rate_flags & eHAL_TX_RATE_VHT20)
6454 maxMCSIdx = 8;
6455 else
6456 maxMCSIdx = 9;
Leo Chang6f8870f2013-03-26 18:11:36 -07006457 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +05306458
6459 if (rate_flags & eHAL_TX_RATE_VHT80)
6460 {
6461 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT80_rate[rateFlag];
6462 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT80_rate[rateFlag];
6463 }
6464 else if (rate_flags & eHAL_TX_RATE_VHT40)
6465 {
6466 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT40_rate[rateFlag];
6467 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT40_rate[rateFlag];
6468 }
6469 else if (rate_flags & eHAL_TX_RATE_VHT20)
6470 {
6471 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT20_rate[rateFlag];
6472 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT20_rate[rateFlag];
6473 }
6474
Leo Chang6f8870f2013-03-26 18:11:36 -07006475 maxSpeedMCS = 1;
6476 if (currentRate > maxRate)
6477 {
6478 maxRate = currentRate;
6479 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +05306480
Leo Chang6f8870f2013-03-26 18:11:36 -07006481 }
6482 else
6483#endif /* WLAN_FEATURE_11AC */
6484 {
6485 if (rate_flags & eHAL_TX_RATE_HT40)
6486 {
6487 rateFlag |= 1;
6488 }
6489 if (rate_flags & eHAL_TX_RATE_SGI)
6490 {
6491 rateFlag |= 2;
6492 }
6493
6494 for (i = 0; i < MCSLeng; i++)
6495 {
6496 temp = sizeof(supported_mcs_rate) / sizeof(supported_mcs_rate[0]);
6497 for (j = 0; j < temp; j++)
6498 {
6499 if (supported_mcs_rate[j].beacon_rate_index == MCSRates[i])
6500 {
6501 currentRate = supported_mcs_rate[j].supported_rate[rateFlag];
6502 break;
6503 }
6504 }
6505 if ((j < temp) && (currentRate > maxRate))
6506 {
6507 maxRate = currentRate;
6508 maxSpeedMCS = 1;
6509 maxMCSIdx = supported_mcs_rate[j].beacon_rate_index;
6510 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006511 }
6512 }
6513 }
6514
Gopichand Nakkala4c705372013-04-24 13:20:33 +05306515 else if (!(rate_flags & eHAL_TX_RATE_LEGACY))
6516 {
6517 maxRate = myRate;
6518 maxSpeedMCS = 1;
6519 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
6520 }
6521
Jeff Johnson295189b2012-06-20 16:38:30 -07006522 // make sure we report a value at least as big as our current rate
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07006523 if (((maxRate < myRate) && (0 == rssidx)) ||
6524 (0 == maxRate))
Jeff Johnson295189b2012-06-20 16:38:30 -07006525 {
6526 maxRate = myRate;
6527 if (rate_flags & eHAL_TX_RATE_LEGACY)
6528 {
6529 maxSpeedMCS = 0;
6530 }
6531 else
6532 {
6533 maxSpeedMCS = 1;
6534 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
6535 }
6536 }
6537
Gopichand Nakkala4c705372013-04-24 13:20:33 +05306538 if (rate_flags & eHAL_TX_RATE_LEGACY)
Jeff Johnson295189b2012-06-20 16:38:30 -07006539 {
6540 sinfo->txrate.legacy = maxRate;
6541#ifdef LINKSPEED_DEBUG_ENABLED
6542 pr_info("Reporting legacy rate %d\n", sinfo->txrate.legacy);
6543#endif //LINKSPEED_DEBUG_ENABLED
6544 }
6545 else
6546 {
6547 sinfo->txrate.mcs = maxMCSIdx;
Leo Chang6f8870f2013-03-26 18:11:36 -07006548#ifdef WLAN_FEATURE_11AC
6549 sinfo->txrate.nss = 1;
6550 if (rate_flags & eHAL_TX_RATE_VHT80)
6551 {
6552 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
Gopichand Nakkala4c705372013-04-24 13:20:33 +05306553 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
Leo Chang6f8870f2013-03-26 18:11:36 -07006554 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +05306555 else if (rate_flags & eHAL_TX_RATE_VHT40)
Leo Chang6f8870f2013-03-26 18:11:36 -07006556 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +05306557 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
6558 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
6559 }
6560 else if (rate_flags & eHAL_TX_RATE_VHT20)
6561 {
6562 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
6563 }
6564#endif /* WLAN_FEATURE_11AC */
6565 if (rate_flags & (eHAL_TX_RATE_HT20 | eHAL_TX_RATE_HT40))
6566 {
6567 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
6568 if (rate_flags & eHAL_TX_RATE_HT40)
6569 {
6570 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
6571 }
Leo Chang6f8870f2013-03-26 18:11:36 -07006572 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006573 if (rate_flags & eHAL_TX_RATE_SGI)
6574 {
6575 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
6576 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +05306577
Jeff Johnson295189b2012-06-20 16:38:30 -07006578#ifdef LINKSPEED_DEBUG_ENABLED
6579 pr_info("Reporting MCS rate %d flags %x\n",
6580 sinfo->txrate.mcs,
6581 sinfo->txrate.flags );
6582#endif //LINKSPEED_DEBUG_ENABLED
6583 }
6584 }
6585 else
6586 {
6587 // report current rate instead of max rate
6588
6589 if (rate_flags & eHAL_TX_RATE_LEGACY)
6590 {
6591 //provide to the UI in units of 100kbps
6592 sinfo->txrate.legacy = myRate;
6593#ifdef LINKSPEED_DEBUG_ENABLED
6594 pr_info("Reporting actual legacy rate %d\n", sinfo->txrate.legacy);
6595#endif //LINKSPEED_DEBUG_ENABLED
6596 }
6597 else
6598 {
6599 //must be MCS
6600 sinfo->txrate.mcs = pAdapter->hdd_stats.ClassA_stat.mcs_index;
Leo Chang6f8870f2013-03-26 18:11:36 -07006601#ifdef WLAN_FEATURE_11AC
6602 sinfo->txrate.nss = 1;
6603 if (rate_flags & eHAL_TX_RATE_VHT80)
6604 {
6605 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
6606 }
6607 else
6608#endif /* WLAN_FEATURE_11AC */
6609 {
6610 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
6611 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006612 if (rate_flags & eHAL_TX_RATE_SGI)
6613 {
6614 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
6615 }
6616 if (rate_flags & eHAL_TX_RATE_HT40)
6617 {
6618 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
6619 }
Leo Chang6f8870f2013-03-26 18:11:36 -07006620#ifdef WLAN_FEATURE_11AC
6621 else if (rate_flags & eHAL_TX_RATE_VHT80)
6622 {
6623 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
6624 }
6625#endif /* WLAN_FEATURE_11AC */
Jeff Johnson295189b2012-06-20 16:38:30 -07006626#ifdef LINKSPEED_DEBUG_ENABLED
6627 pr_info("Reporting actual MCS rate %d flags %x\n",
6628 sinfo->txrate.mcs,
6629 sinfo->txrate.flags );
6630#endif //LINKSPEED_DEBUG_ENABLED
6631 }
6632 }
6633 sinfo->filled |= STATION_INFO_TX_BITRATE;
6634
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -07006635 sinfo->tx_packets =
6636 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[0] +
6637 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[1] +
6638 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[2] +
6639 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[3];
6640
6641 sinfo->tx_retries =
6642 pAdapter->hdd_stats.summary_stat.retry_cnt[0] +
6643 pAdapter->hdd_stats.summary_stat.retry_cnt[1] +
6644 pAdapter->hdd_stats.summary_stat.retry_cnt[2] +
6645 pAdapter->hdd_stats.summary_stat.retry_cnt[3];
6646
6647 sinfo->tx_failed =
6648 pAdapter->hdd_stats.summary_stat.fail_cnt[0] +
6649 pAdapter->hdd_stats.summary_stat.fail_cnt[1] +
6650 pAdapter->hdd_stats.summary_stat.fail_cnt[2] +
6651 pAdapter->hdd_stats.summary_stat.fail_cnt[3];
6652
6653 sinfo->filled |=
6654 STATION_INFO_TX_PACKETS |
6655 STATION_INFO_TX_RETRIES |
6656 STATION_INFO_TX_FAILED;
6657
6658 EXIT();
6659 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07006660}
6661
6662static int wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
6663 struct net_device *dev, bool mode, v_SINT_t timeout)
6664{
6665 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +05306666 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07006667 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306668 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07006669
Jeff Johnsone7245742012-09-05 17:12:55 -07006670 ENTER();
6671
Jeff Johnson295189b2012-06-20 16:38:30 -07006672 if (NULL == pAdapter)
6673 {
6674 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL\n", __func__);
6675 return -ENODEV;
6676 }
6677
Gopichand Nakkala20c4c042013-04-19 22:08:55 +05306678 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306679 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +05306680
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306681 if (0 != status)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306682 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306683 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6684 "%s: HDD context is not valid", __func__);
6685 return status;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306686 }
6687
Gopichand Nakkala20c4c042013-04-19 22:08:55 +05306688 if ((DRIVER_POWER_MODE_AUTO == !mode) &&
6689 (TRUE == pHddCtx->hdd_wlan_suspended) &&
6690 (pHddCtx->cfg_ini->fhostArpOffload) &&
6691 (eConnectionState_Associated ==
6692 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
6693 {
6694 vos_status = hdd_conf_hostarpoffload(pAdapter, TRUE);
6695 if (!VOS_IS_STATUS_SUCCESS(vos_status))
6696 {
6697 hddLog(VOS_TRACE_LEVEL_INFO,
6698 "%s:Failed to enable ARPOFFLOAD Feature %d\n",
6699 __func__, vos_status);
6700 }
6701 }
6702
Jeff Johnson295189b2012-06-20 16:38:30 -07006703 /**The get power cmd from the supplicant gets updated by the nl only
6704 *on successful execution of the function call
6705 *we are oppositely mapped w.r.t mode in the driver
6706 **/
6707 vos_status = wlan_hdd_enter_bmps(pAdapter, !mode);
6708
Jeff Johnsone7245742012-09-05 17:12:55 -07006709 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07006710 if (VOS_STATUS_E_FAILURE == vos_status)
6711 {
6712 return -EINVAL;
6713 }
6714 return 0;
6715}
6716
6717
6718#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
6719static int wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
6720 struct net_device *netdev,
6721 u8 key_index)
6722{
Jeff Johnsone7245742012-09-05 17:12:55 -07006723 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07006724 return 0;
6725}
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306726#endif //LINUX_VERSION_CODE
Jeff Johnson295189b2012-06-20 16:38:30 -07006727
6728#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
6729static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
6730 struct net_device *dev,
6731 struct ieee80211_txq_params *params)
6732{
Jeff Johnsone7245742012-09-05 17:12:55 -07006733 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07006734 return 0;
6735}
6736#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
6737static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
6738 struct ieee80211_txq_params *params)
6739{
Jeff Johnsone7245742012-09-05 17:12:55 -07006740 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07006741 return 0;
6742}
6743#endif //LINUX_VERSION_CODE
6744
6745static int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
6746 struct net_device *dev, u8 *mac)
6747{
6748 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306749 hdd_context_t *pHddCtx;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08006750 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306751 int status;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08006752 v_U8_t staId;
Jeff Johnson295189b2012-06-20 16:38:30 -07006753
Jeff Johnsone7245742012-09-05 17:12:55 -07006754 ENTER();
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306755 if ( NULL == pAdapter )
Jeff Johnson295189b2012-06-20 16:38:30 -07006756 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306757 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006758 return -EINVAL;
6759 }
6760
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306761 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
6762 status = wlan_hdd_validate_context(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07006763
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306764 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006765 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306766 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6767 "%s: HDD context is not valid", __func__);
6768 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006769 }
6770
Jeff Johnson295189b2012-06-20 16:38:30 -07006771 if ( (WLAN_HDD_SOFTAP == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -07006772 || (WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -07006773 )
6774 {
6775 if( NULL == mac )
6776 {
6777 v_U16_t i;
6778 for(i = 0; i < WLAN_MAX_STA_COUNT; i++)
6779 {
6780 if(pAdapter->aStaInfo[i].isUsed)
6781 {
6782 u8 *macAddr = pAdapter->aStaInfo[i].macAddrSTA.bytes;
6783 hddLog(VOS_TRACE_LEVEL_INFO,
6784 "%s: Delete STA with MAC::"
6785 "%02x:%02x:%02x:%02x:%02x:%02x",
6786 __func__,
6787 macAddr[0], macAddr[1], macAddr[2],
6788 macAddr[3], macAddr[4], macAddr[5]);
6789 hdd_softap_sta_deauth(pAdapter, macAddr);
6790 }
6791 }
6792 }
6793 else
6794 {
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08006795
6796 vos_status = hdd_softap_GetStaId(pAdapter,(v_MACADDR_t *)mac, &staId);
6797 if (!VOS_IS_STATUS_SUCCESS(vos_status))
6798 {
6799 hddLog(VOS_TRACE_LEVEL_INFO,
6800 "%s: Skip this DEL STA as this is not used::"
6801 "%02x:%02x:%02x:%02x:%02x:%02x",
6802 __func__,
6803 mac[0], mac[1], mac[2],
6804 mac[3], mac[4], mac[5]);
6805 return -ENOENT;
6806 }
6807
6808 if( pAdapter->aStaInfo[staId].isDeauthInProgress == TRUE)
6809 {
6810 hddLog(VOS_TRACE_LEVEL_INFO,
6811 "%s: Skip this DEL STA as deauth is in progress::"
6812 "%02x:%02x:%02x:%02x:%02x:%02x",
6813 __func__,
6814 mac[0], mac[1], mac[2],
6815 mac[3], mac[4], mac[5]);
6816 return -ENOENT;
6817 }
6818
6819 pAdapter->aStaInfo[staId].isDeauthInProgress = TRUE;
6820
Jeff Johnson295189b2012-06-20 16:38:30 -07006821 hddLog(VOS_TRACE_LEVEL_INFO,
6822 "%s: Delete STA with MAC::"
6823 "%02x:%02x:%02x:%02x:%02x:%02x",
6824 __func__,
6825 mac[0], mac[1], mac[2],
6826 mac[3], mac[4], mac[5]);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08006827
6828 vos_status = hdd_softap_sta_deauth(pAdapter, mac);
6829 if (!VOS_IS_STATUS_SUCCESS(vos_status))
6830 {
6831 pAdapter->aStaInfo[staId].isDeauthInProgress = FALSE;
6832 hddLog(VOS_TRACE_LEVEL_INFO,
6833 "%s: STA removal failed for ::"
6834 "%02x:%02x:%02x:%02x:%02x:%02x",
6835 __func__,
6836 mac[0], mac[1], mac[2],
6837 mac[3], mac[4], mac[5]);
6838 return -ENOENT;
6839 }
6840
Jeff Johnson295189b2012-06-20 16:38:30 -07006841 }
6842 }
6843
6844 EXIT();
6845
6846 return 0;
6847}
6848
Hoonki Lee11f7dda2013-02-14 16:55:44 -08006849static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
6850 struct net_device *dev, u8 *mac, struct station_parameters *params)
6851{
Gopichand Nakkalab977a972013-02-18 19:15:09 -08006852 int status = -EPERM;
Hoonki Lee11f7dda2013-02-14 16:55:44 -08006853#ifdef FEATURE_WLAN_TDLS
6854 u32 mask, set;
Hoonki Lee11f7dda2013-02-14 16:55:44 -08006855 ENTER();
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006856 mask = params->sta_flags_mask;
6857
6858 set = params->sta_flags_set;
6859
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07006860#ifdef WLAN_FEATURE_TDLS_DEBUG
6861 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6862 "%s: mask 0x%x set 0x%x " MAC_ADDRESS_STR,
6863 __func__, mask, set, MAC_ADDR_ARRAY(mac));
6864#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006865
6866 if (mask & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
6867 if (set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006868 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 0, NULL);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006869 }
6870 }
6871#endif
Gopichand Nakkalab977a972013-02-18 19:15:09 -08006872 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -07006873}
6874
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006875
6876#ifdef FEATURE_WLAN_LFR
6877static int wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
Jeff Johnsond13512a2012-07-17 11:42:19 -07006878 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006879{
6880#define MAX_PMKSAIDS_IN_CACHE 8
6881 static tPmkidCacheInfo PMKIDCache[MAX_PMKSAIDS_IN_CACHE]; // HDD Local cache
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306882 static tANI_U32 i; // HDD Local Cache index
6883 tANI_U32 j=0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006884 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6885 tHalHandle halHandle;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306886 eHalStatus result;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306887 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006888 tANI_U8 BSSIDMatched = 0;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306889 hdd_context_t *pHddCtx;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306890
Jeff Johnsone7245742012-09-05 17:12:55 -07006891 ENTER();
6892
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306893 // Validate pAdapter
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306894 if ( NULL == pAdapter )
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006895 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306896 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006897 return -EINVAL;
6898 }
6899
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306900 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
6901 status = wlan_hdd_validate_context(pHddCtx);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006902
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306903 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006904 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306905 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6906 "%s: HDD context is not valid", __func__);
6907 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006908 }
6909
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306910 // Retrieve halHandle
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006911 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
6912
6913 for (j = 0; j < i; j++)
6914 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306915 if(vos_mem_compare(PMKIDCache[j].BSSID,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006916 pmksa->bssid, WNI_CFG_BSSID_LEN))
6917 {
6918 /* BSSID matched previous entry. Overwrite it. */
6919 BSSIDMatched = 1;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306920 vos_mem_copy(PMKIDCache[j].BSSID,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006921 pmksa->bssid, WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306922 vos_mem_copy(PMKIDCache[j].PMKID,
6923 pmksa->pmkid,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006924 CSR_RSN_PMKID_SIZE);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306925 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Reusing cache entry %d.",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006926 __func__, j );
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006927 dump_bssid(pmksa->bssid);
6928 dump_pmkid(halHandle, pmksa->pmkid);
6929 break;
6930 }
6931 }
6932
Madan Mohan Koyyalamudic4b317d2012-10-18 19:43:08 -07006933 /* Check we compared all entries,if then take the first slot now */
6934 if(j == MAX_PMKSAIDS_IN_CACHE) i=0;
6935
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006936 if (!BSSIDMatched)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306937 {
6938 // Now, we DON'T have a BSSID match, so take a new entry in the cache.
6939 vos_mem_copy(PMKIDCache[i].BSSID,
6940 pmksa->bssid, ETHER_ADDR_LEN);
6941 vos_mem_copy(PMKIDCache[i].PMKID,
6942 pmksa->pmkid,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006943 CSR_RSN_PMKID_SIZE);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306944 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Adding a new cache entry %d.",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006945 __func__, i );
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006946 dump_bssid(pmksa->bssid);
6947 dump_pmkid(halHandle, pmksa->pmkid);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306948 // Increment the HDD Local Cache index
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006949 // The "i=0" doesn't work for the call to sme_RoamSetPMKIDCache() - LFR FIXME
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306950 if (i<=(MAX_PMKSAIDS_IN_CACHE-1)) i++; else i=0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006951 }
6952
6953
6954 // Calling csrRoamSetPMKIDCache to configure the PMKIDs into the cache
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306955 //hddLog(LOG1, FL("%s: Calling csrRoamSetPMKIDCache with %d cache entries."),
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006956 // __func__, i );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306957 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Calling csrRoamSetPMKIDCache with %d cache entries.",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006958 __func__, i );
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006959 // Finally set the PMKSA ID Cache in CSR
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306960 result = sme_RoamSetPMKIDCache(halHandle,pAdapter->sessionId,
6961 PMKIDCache,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006962 i );
6963 return 0;
6964}
6965
6966
6967static int wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
Jeff Johnsond13512a2012-07-17 11:42:19 -07006968 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006969{
Jeff Johnsone7245742012-09-05 17:12:55 -07006970 ENTER();
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006971 // TODO: Implement this later.
6972 return 0;
6973}
6974
6975static int wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
6976{
Jeff Johnsone7245742012-09-05 17:12:55 -07006977 ENTER();
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006978 // TODO: Implement this later.
6979 return 0;
6980}
6981#endif
6982
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07006983#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306984static int wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07006985 struct net_device *dev, struct cfg80211_update_ft_ies_params *ftie)
6986{
6987 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6988 hdd_station_ctx_t *pHddStaCtx;
6989
6990 if (NULL == pAdapter)
6991 {
6992 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL\n", __func__);
6993 return -ENODEV;
6994 }
6995
6996 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6997
6998 // Added for debug on reception of Re-assoc Req.
6999 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
7000 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307001 hddLog(LOGE, FL("Called with Ie of length = %d when not associated\n"),
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07007002 ftie->ie_len);
7003 hddLog(LOGE, FL("Should be Re-assoc Req IEs\n"));
7004 }
7005
7006#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307007 hddLog(LOGE, FL("%s called with Ie of length = %d\n"), __func__,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07007008 ftie->ie_len);
7009#endif
7010
7011 // Pass the received FT IEs to SME
Gopichand Nakkala356fb102013-03-06 12:34:04 +05307012 sme_SetFTIEs( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
7013 (const u8 *)ftie->ie,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07007014 ftie->ie_len);
7015 return 0;
7016}
7017#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007018
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05307019#ifdef FEATURE_WLAN_SCAN_PNO
7020
7021void hdd_cfg80211_sched_scan_done_callback(void *callbackContext,
7022 tSirPrefNetworkFoundInd *pPrefNetworkFoundInd)
7023{
7024 int ret;
7025 hdd_adapter_t* pAdapter = (hdd_adapter_t*)callbackContext;
7026 hdd_context_t *pHddCtx;
7027
7028 if (NULL == pAdapter)
7029 {
7030 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
7031 "%s: HDD adapter is Null", __func__);
7032 return ;
7033 }
7034
7035 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7036 if (NULL == pHddCtx)
7037 {
7038 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7039 "%s: HDD context is Null!!!", __func__);
7040 return ;
7041 }
7042
7043 ret = wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter);
7044
7045 if (0 > ret)
7046 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
7047
7048 cfg80211_sched_scan_results(pHddCtx->wiphy);
7049}
7050
7051/*
7052 * FUNCTION: wlan_hdd_cfg80211_sched_scan_start
7053 * NL interface to enable PNO
7054 */
7055static int wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
7056 struct net_device *dev, struct cfg80211_sched_scan_request *request)
7057{
7058 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
7059 tpSirPNOScanReq pPnoRequest = NULL;
7060 hdd_context_t *pHddCtx;
7061 tHalHandle hHal;
7062 v_U32_t i, indx, num_ch;
7063 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN];
7064 u8 channels_allowed[WNI_CFG_VALID_CHANNEL_LIST_LEN];
7065 v_U32_t num_channels_allowed = WNI_CFG_VALID_CHANNEL_LIST_LEN;
7066 eHalStatus status = eHAL_STATUS_FAILURE;
7067
7068 if (NULL == pAdapter)
7069 {
7070 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
7071 "%s: HDD adapter is Null", __func__);
7072 return -ENODEV;
7073 }
7074
7075 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7076 if (NULL == pHddCtx)
7077 {
7078 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7079 "%s: HDD context is Null!!!", __func__);
7080 return -ENODEV;
7081 }
7082
7083 if (pHddCtx->isLogpInProgress)
7084 {
7085 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
7086 "%s: LOGP in Progress. Ignore!!!", __func__);
7087 return -EAGAIN;
7088 }
7089
7090 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
7091 if (NULL == hHal)
7092 {
7093 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7094 "%s: HAL context is Null!!!", __func__);
7095 return -EAGAIN;
7096 }
7097
7098 pPnoRequest = (tpSirPNOScanReq) vos_mem_malloc(sizeof (tSirPNOScanReq));
7099 if (NULL == pPnoRequest)
7100 {
7101 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
7102 "%s: vos_mem_malloc failed", __func__);
7103 return -ENODEV;
7104 }
7105
7106 pPnoRequest->enable = 1; /*Enable PNO */
7107 pPnoRequest->ucNetworksCount = request->n_match_sets;
7108
7109 if (( !pPnoRequest->ucNetworksCount ) ||
7110 ( pPnoRequest->ucNetworksCount > SIR_PNO_MAX_SUPP_NETWORKS ))
7111 {
7112 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7113 "Network input is not correct");
7114 goto error;
7115 }
7116
7117 if ( SIR_PNO_MAX_NETW_CHANNELS_EX < request->n_channels )
7118 {
7119 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7120 "Incorrect number of channels");
7121 goto error;
7122 }
7123
7124 /* Framework provides one set of channels(all)
7125 * common for all saved profile */
7126 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
7127 channels_allowed, &num_channels_allowed))
7128 {
7129 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7130 "%s: failed to get valid channel list", __func__);
7131 goto error;
7132 }
7133 /* Checking each channel against allowed channel list */
7134 num_ch = 0;
7135 for (i = 0; i < request->n_channels; i++)
7136 {
7137 for (indx = 0; indx < num_channels_allowed; indx++)
7138 {
7139 if (request->channels[i]->hw_value == channels_allowed[indx])
7140 {
7141 valid_ch[num_ch++] = request->channels[i]->hw_value;
7142 break ;
7143 }
7144 }
7145 }
7146
7147 /* Filling per profile params */
7148 for (i = 0; i < pPnoRequest->ucNetworksCount; i++)
7149 {
7150 pPnoRequest->aNetworks[i].ssId.length =
7151 request->match_sets[i].ssid.ssid_len;
7152
7153 if (( 0 == pPnoRequest->aNetworks[i].ssId.length ) ||
7154 ( pPnoRequest->aNetworks[i].ssId.length > 32 ) )
7155 {
7156 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7157 "SSID Len %d is not correct for network %d",
7158 pPnoRequest->aNetworks[i].ssId.length, i);
7159 goto error;
7160 }
7161
7162 memcpy(pPnoRequest->aNetworks[i].ssId.ssId,
7163 request->match_sets[i].ssid.ssid,
7164 request->match_sets[i].ssid.ssid_len);
7165 pPnoRequest->aNetworks[i].authentication = 0; /*eAUTH_TYPE_ANY*/
7166 pPnoRequest->aNetworks[i].encryption = 0; /*eED_ANY*/
7167 pPnoRequest->aNetworks[i].bcastNetwType = 0; /*eBCAST_UNKNOWN*/
7168
7169 /*Copying list of valid channel into request */
7170 memcpy(pPnoRequest->aNetworks[i].aChannels, valid_ch, num_ch);
7171 pPnoRequest->aNetworks[i].ucChannelCount = num_ch;
7172
7173 pPnoRequest->aNetworks[i].rssiThreshold = 0; //Default value
7174 }
7175
7176 /* framework provides interval in ms */
7177 pPnoRequest->scanTimers.ucScanTimersCount = 1;
7178 pPnoRequest->scanTimers.aTimerValues[0].uTimerValue =
7179 (request->interval)/1000;
7180 pPnoRequest->scanTimers.aTimerValues[0].uTimerRepeat = 0;
7181 pPnoRequest->modePNO = SIR_PNO_MODE_ON_SUSPEND;
7182
7183 status = sme_SetPreferredNetworkList(WLAN_HDD_GET_HAL_CTX(pAdapter),
7184 pPnoRequest, pAdapter->sessionId,
7185 hdd_cfg80211_sched_scan_done_callback, pAdapter);
7186 if (eHAL_STATUS_SUCCESS != status)
7187 {
7188 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7189 "Failed to enable PNO");
7190 goto error;
7191 }
7192
7193error:
7194 vos_mem_free(pPnoRequest);
7195 return status;
7196}
7197
7198/*
7199 * FUNCTION: wlan_hdd_cfg80211_sched_scan_stop
7200 * NL interface to disable PNO
7201 */
7202static int wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
7203 struct net_device *dev)
7204{
7205 eHalStatus status = eHAL_STATUS_FAILURE;
7206 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
7207 hdd_context_t *pHddCtx;
7208 tHalHandle hHal;
7209 tpSirPNOScanReq pPnoRequest = NULL;
7210
7211 ENTER();
7212
7213 if (NULL == pAdapter)
7214 {
7215 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
7216 "%s: HDD adapter is Null", __func__);
7217 return -ENODEV;
7218 }
7219
7220 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7221 if (NULL == pHddCtx)
7222 {
7223 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7224 "%s: HDD context is Null!!!", __func__);
7225 return -ENODEV;
7226 }
7227
7228 if (pHddCtx->isLogpInProgress)
7229 {
7230 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
7231 "%s: LOGP in Progress. Ignore!!!", __func__);
7232 return -EAGAIN;
7233 }
7234
7235 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
7236 if (NULL == hHal)
7237 {
7238 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7239 "%s: HAL context is Null!!!", __func__);
7240 return -EAGAIN;
7241 }
7242
7243 pPnoRequest = (tpSirPNOScanReq) vos_mem_malloc(sizeof (tSirPNOScanReq));
7244 if (NULL == pPnoRequest)
7245 {
7246 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
7247 "%s: vos_mem_malloc failed", __func__);
7248 return -ENODEV;
7249 }
7250
7251 memset(pPnoRequest, 0, sizeof (tSirPNOScanReq));
7252 pPnoRequest->enable = 0; /* Disable PNO */
7253 pPnoRequest->ucNetworksCount = 0;
7254
7255 status = sme_SetPreferredNetworkList(hHal, pPnoRequest,
7256 pAdapter->sessionId,
7257 NULL, pAdapter);
7258 if (eHAL_STATUS_SUCCESS != status)
7259 {
7260 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7261 "Failed to disabled PNO");
7262 }
7263
7264 vos_mem_free(pPnoRequest);
7265
7266 EXIT();
7267 return status;
7268}
7269
7270#endif /*FEATURE_WLAN_SCAN_PNO*/
7271
7272
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007273#ifdef FEATURE_WLAN_TDLS
7274static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
7275 u8 *peer, u8 action_code, u8 dialog_token,
7276 u16 status_code, const u8 *buf, size_t len)
7277{
7278
7279 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
7280 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007281 u8 peerMac[6];
7282 VOS_STATUS status;
Gopichand Nakkala05922802013-03-14 12:23:19 -07007283 int max_sta_failed = 0;
Hoonki Leea34dd892013-02-05 22:56:02 -08007284 int responder;
Hoonki Leed37cbb32013-04-20 00:31:14 -07007285 long rc;
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007286
Hoonki Lee11f7dda2013-02-14 16:55:44 -08007287 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007288 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307289 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007290 "Invalid arguments");
7291 return -EINVAL;
7292 }
7293
Sameer Thalappil75ea31a2013-02-21 19:38:16 -08007294 if (pHddCtx->isLogpInProgress)
7295 {
7296 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7297 "%s:LOGP in Progress. Ignore!!!", __func__);
Gopichand Nakkala05922802013-03-14 12:23:19 -07007298 wlan_hdd_tdls_set_link_status(pAdapter, peer, eTDLS_LINK_IDLE);
Sameer Thalappil75ea31a2013-02-21 19:38:16 -08007299 return -EBUSY;
7300 }
7301
Hoonki Lee27511902013-03-14 18:19:06 -07007302 if (eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode)
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007303 {
Hoonki Lee27511902013-03-14 18:19:06 -07007304 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
7305 "%s: TDLS mode is disabled OR not enabled in FW."
7306 MAC_ADDRESS_STR " action %d declined.",
7307 __func__, MAC_ADDR_ARRAY(peer), action_code);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007308 return -ENOTSUPP;
7309 }
Lee Hoonkic1262f22013-01-24 21:59:00 -08007310
Hoonki Lee27511902013-03-14 18:19:06 -07007311 /* other than teardown frame, other mgmt frames are not sent if disabled */
7312 if (SIR_MAC_TDLS_TEARDOWN != action_code)
7313 {
7314 /* if tdls_mode is disabled to respond to peer's request */
7315 if (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode)
7316 {
7317 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
7318 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07007319 " TDLS mode is disabled. action %d declined.",
7320 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee27511902013-03-14 18:19:06 -07007321
7322 return -ENOTSUPP;
7323 }
7324 }
7325
Gopichand Nakkalab977a972013-02-18 19:15:09 -08007326 if (WLAN_IS_TDLS_SETUP_ACTION(action_code))
7327 {
Hoonki Leefb8df672013-04-10 18:20:34 -07007328 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, peer, TRUE, TRUE))
Gopichand Nakkalab977a972013-02-18 19:15:09 -08007329 {
7330 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007331 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07007332 " TDLS setup is ongoing. action %d declined.",
7333 __func__, MAC_ADDR_ARRAY(peer), action_code);
7334 return -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -08007335 }
7336 }
7337
Hoonki Lee11f7dda2013-02-14 16:55:44 -08007338 if (SIR_MAC_TDLS_SETUP_REQ == action_code ||
7339 SIR_MAC_TDLS_SETUP_RSP == action_code )
Lee Hoonkic1262f22013-01-24 21:59:00 -08007340 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -08007341 if (HDD_MAX_NUM_TDLS_STA <= wlan_hdd_tdlsConnectedPeers(pAdapter))
Lee Hoonkic1262f22013-01-24 21:59:00 -08007342 {
7343 /* supplicant still sends tdls_mgmt(SETUP_REQ) even after
7344 we return error code at 'add_station()'. Hence we have this
7345 check again in addtion to add_station().
7346 Anyway, there is no hard to double-check. */
Hoonki Lee11f7dda2013-02-14 16:55:44 -08007347 if (SIR_MAC_TDLS_SETUP_REQ == action_code)
Lee Hoonkic1262f22013-01-24 21:59:00 -08007348 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007349 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7350 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07007351 " TDLS Max peer already connected. action %d declined.",
7352 __func__, MAC_ADDR_ARRAY(peer), action_code);
Gopichand Nakkala05922802013-03-14 12:23:19 -07007353 goto error;
Lee Hoonkic1262f22013-01-24 21:59:00 -08007354 }
7355 else
7356 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -08007357 /* maximum reached. tweak to send error code to peer and return
7358 error code to supplicant */
Lee Hoonkic1262f22013-01-24 21:59:00 -08007359 status_code = eSIR_MAC_UNSPEC_FAILURE_STATUS;
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007360 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7361 "%s: " MAC_ADDRESS_STR
7362 " TDLS Max peer already connected send response status %d",
7363 __func__, MAC_ADDR_ARRAY(peer), status_code);
Gopichand Nakkala05922802013-03-14 12:23:19 -07007364 max_sta_failed = -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -08007365 /* fall through to send setup resp with failure status
7366 code */
Lee Hoonkic1262f22013-01-24 21:59:00 -08007367 }
7368 }
Hoonki Lee11f7dda2013-02-14 16:55:44 -08007369 else
7370 {
7371 hddTdlsPeer_t *pTdlsPeer;
Gopichand Nakkala4327a152013-03-04 23:22:42 -08007372 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007373 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Hoonki Lee11f7dda2013-02-14 16:55:44 -08007374 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007375 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07007376 "%s:" MAC_ADDRESS_STR " already connected. action %d declined.",
7377 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee11f7dda2013-02-14 16:55:44 -08007378 return -EPERM;
7379 }
7380 }
Lee Hoonkic1262f22013-01-24 21:59:00 -08007381 }
Hoonki Lee11f7dda2013-02-14 16:55:44 -08007382 vos_mem_copy(peerMac, peer, 6);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007383
Hoonki Lee1090c6a2013-01-16 17:40:54 -08007384#ifdef WLAN_FEATURE_TDLS_DEBUG
7385 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007386 "%s: " MAC_ADDRESS_STR " action %d, dialog_token %d status %d, len = %d",
7387 "tdls_mgmt", MAC_ADDR_ARRAY(peer),
7388 action_code, dialog_token, status_code, len);
Hoonki Lee1090c6a2013-01-16 17:40:54 -08007389#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007390
Hoonki Leea34dd892013-02-05 22:56:02 -08007391 /*Except teardown responder will not be used so just make 0*/
7392 responder = 0;
Hoonki Lee11f7dda2013-02-14 16:55:44 -08007393 if (SIR_MAC_TDLS_TEARDOWN == action_code)
Hoonki Leea34dd892013-02-05 22:56:02 -08007394 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -07007395
7396 hddTdlsPeer_t *pTdlsPeer;
7397 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peerMac);
7398
7399 if(pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
7400 responder = pTdlsPeer->is_responder;
7401 else
Hoonki Leea34dd892013-02-05 22:56:02 -08007402 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -07007403 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7404 "%s: " MAC_ADDRESS_STR " peer doesn't exist or not connected %d dialog_token %d status %d, len = %d",
7405 __func__, MAC_ADDR_ARRAY(peer), (NULL == pTdlsPeer) ? -1 : pTdlsPeer->link_status,
7406 dialog_token, status_code, len);
7407 return -EPERM;
Hoonki Leea34dd892013-02-05 22:56:02 -08007408 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007409 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007410
Hoonki Lee14621352013-04-16 17:51:19 -07007411 if ((SIR_MAC_TDLS_SETUP_RSP == action_code) ||
7412 (SIR_MAC_TDLS_DIS_RSP == action_code))
7413 {
7414 if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter)))
7415 {
7416 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
7417 "%s: Sending Disc/Setup Rsp Frame.Disable BMPS", __func__);
7418 hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
7419 }
7420 wlan_hdd_tdls_set_cap(pAdapter, peerMac, eTDLS_CAP_SUPPORTED);
7421 }
7422
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007423 /* make sure doesn't call send_mgmt() while it is pending */
7424 if (TDLS_CTX_MAGIC == pAdapter->mgmtTxCompletionStatus)
7425 {
7426 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7427 "%s: " MAC_ADDRESS_STR " action %d couldn't sent, as one is pending. return EBUSY\n",
7428 __func__, MAC_ADDR_ARRAY(peer), action_code);
7429 return -EBUSY;
7430 }
7431
7432 pAdapter->mgmtTxCompletionStatus = TDLS_CTX_MAGIC;
Gopichand Nakkalab977a972013-02-18 19:15:09 -08007433 INIT_COMPLETION(pAdapter->tdls_mgmt_comp);
7434
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007435 status = sme_SendTdlsMgmtFrame(WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
Hoonki Leea34dd892013-02-05 22:56:02 -08007436 peerMac, action_code, dialog_token, status_code, (tANI_U8 *)buf, len, responder);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007437
Gopichand Nakkalab977a972013-02-18 19:15:09 -08007438 if (VOS_STATUS_SUCCESS != status)
7439 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007440 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7441 "%s: sme_SendTdlsMgmtFrame failed!", __func__);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007442 pAdapter->mgmtTxCompletionStatus = FALSE;
Hoonki Lee14621352013-04-16 17:51:19 -07007443 wlan_hdd_tdls_check_bmps(pAdapter);
7444 goto error;
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007445 }
7446
Hoonki Leed37cbb32013-04-20 00:31:14 -07007447 rc = wait_for_completion_interruptible_timeout(&pAdapter->tdls_mgmt_comp,
7448 msecs_to_jiffies(WAIT_TIME_TDLS_MGMT));
7449
7450 if ((rc <= 0) || (TRUE != pAdapter->mgmtTxCompletionStatus))
Gopichand Nakkalab977a972013-02-18 19:15:09 -08007451 {
Hoonki Leed37cbb32013-04-20 00:31:14 -07007452 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7453 "%s: Mgmt Tx Completion failed status %ld TxCompletion %lu",
7454 __func__, rc, pAdapter->mgmtTxCompletionStatus);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007455 pAdapter->mgmtTxCompletionStatus = FALSE;
Hoonki Leed37cbb32013-04-20 00:31:14 -07007456 wlan_hdd_tdls_check_bmps(pAdapter);
7457 goto error;
Gopichand Nakkalab977a972013-02-18 19:15:09 -08007458 }
7459
Gopichand Nakkala05922802013-03-14 12:23:19 -07007460 if (max_sta_failed)
Hoonki Lee14621352013-04-16 17:51:19 -07007461 {
7462 wlan_hdd_tdls_check_bmps(pAdapter);
Gopichand Nakkala05922802013-03-14 12:23:19 -07007463 return max_sta_failed;
Hoonki Lee14621352013-04-16 17:51:19 -07007464 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -08007465
Hoonki Leea34dd892013-02-05 22:56:02 -08007466 if (SIR_MAC_TDLS_SETUP_RSP == action_code)
7467 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -08007468 wlan_hdd_tdls_set_responder(pAdapter, peerMac, TRUE);
Hoonki Leea34dd892013-02-05 22:56:02 -08007469 }
7470 else if (SIR_MAC_TDLS_SETUP_CNF == action_code)
7471 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -08007472 wlan_hdd_tdls_set_responder(pAdapter, peerMac, FALSE);
Hoonki Leea34dd892013-02-05 22:56:02 -08007473 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007474
7475 return 0;
Gopichand Nakkala05922802013-03-14 12:23:19 -07007476error:
7477 /* max_sta_failed ; we didn't set to CONNECTING for this case,
7478 because we already know that this transaction will be failed,
7479 but we weren't sure if supplicant call DISABLE_LINK or not. So,
7480 to be safe, do not change the state mahine.
7481 */
7482 if(max_sta_failed == 0 &&
7483 (WLAN_IS_TDLS_SETUP_ACTION(action_code)))
7484 wlan_hdd_tdls_set_link_status(pAdapter, peerMac, eTDLS_LINK_IDLE);
7485 return -EPERM;
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007486}
7487
7488static int wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
7489 u8 *peer, enum nl80211_tdls_operation oper)
7490{
7491 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
7492 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307493 int status;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05307494#ifdef FEATURE_WLAN_TDLS_OXYGEN_DISAPPEAR_AP
7495 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05307496 tANI_U8 staIdx;
7497#endif
Hoonki Lee1090c6a2013-01-16 17:40:54 -08007498#ifdef WLAN_FEATURE_TDLS_DEBUG
7499 const char *tdls_oper_str[]= {
7500 "NL80211_TDLS_DISCOVERY_REQ",
7501 "NL80211_TDLS_SETUP",
7502 "NL80211_TDLS_TEARDOWN",
7503 "NL80211_TDLS_ENABLE_LINK",
7504 "NL80211_TDLS_DISABLE_LINK",
7505 "NL80211_TDLS_UNKONW_OPER"};
7506#endif
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007507 hddTdlsPeer_t *pTdlsPeer;
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007508
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307509 if ( NULL == peer )
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007510 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -08007511 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chilam Ngc4244af2013-04-01 15:37:32 -07007512 "%s: Invalid arguments", __func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007513 return -EINVAL;
7514 }
Hoonki Lee1090c6a2013-01-16 17:40:54 -08007515
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307516 status = wlan_hdd_validate_context(pHddCtx);
7517
7518 if (0 != status)
Sameer Thalappil75ea31a2013-02-21 19:38:16 -08007519 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307520 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7521 "%s: HDD context is not valid", __func__);
7522 return status;
Sameer Thalappil75ea31a2013-02-21 19:38:16 -08007523 }
7524
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007525 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer);
7526
7527 if ( NULL == pTdlsPeer ) {
7528 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR " (oper %d) not exsting. ignored",
7529 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
7530 return -EINVAL;
7531 }
7532
Hoonki Lee1090c6a2013-01-16 17:40:54 -08007533#ifdef WLAN_FEATURE_TDLS_DEBUG
7534 if((int)oper > 4)
7535 oper = 5;
7536
7537 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007538 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
7539 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007540 tdls_oper_str[(int)oper]);
Hoonki Lee1090c6a2013-01-16 17:40:54 -08007541#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007542
7543 if( FALSE == pHddCtx->cfg_ini->fEnableTDLSSupport ||
Hoonki Lee1090c6a2013-01-16 17:40:54 -08007544 FALSE == sme_IsFeatureSupportedByFW(TDLS))
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007545 {
Hoonki Lee1090c6a2013-01-16 17:40:54 -08007546 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chilam Ngc4244af2013-04-01 15:37:32 -07007547 "TDLS Disabled in INI OR not enabled in FW. "
7548 "Cannot process TDLS commands");
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007549 return -ENOTSUPP;
7550 }
7551
7552 switch (oper) {
7553 case NL80211_TDLS_ENABLE_LINK:
7554 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007555 VOS_STATUS status;
7556
Gopichand Nakkala2f4a2822013-04-17 11:22:01 -07007557 if (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
7558 {
7559 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Staion Index %u "
7560 MAC_ADDRESS_STR " failed",
7561 __func__, pTdlsPeer->staId, MAC_ADDR_ARRAY(peer));
7562 return -EINVAL;
7563 }
7564
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007565 if (eTDLS_LINK_CONNECTED != pTdlsPeer->link_status)
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007566 {
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -07007567 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer, eTDLS_LINK_CONNECTED);
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007568 /* start TDLS client registration with TL */
7569 status = hdd_roamRegisterTDLSSTA( pAdapter, peer, pTdlsPeer->staId, pTdlsPeer->signature);
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -07007570 if (VOS_STATUS_SUCCESS == status)
7571 {
Hoonki Lee14621352013-04-16 17:51:19 -07007572 if (pTdlsPeer->is_responder == 0)
7573 {
7574 v_U8_t staId = (v_U8_t)pTdlsPeer->staId;
7575
7576 wlan_hdd_tdls_timer_restart(pAdapter,
7577 &pTdlsPeer->initiatorWaitTimeoutTimer,
7578 WAIT_TIME_TDLS_INITIATOR);
7579 /* suspend initiator TX until it receives direct packet from the
7580 reponder or WAIT_TIME_TDLS_INITIATOR timer expires */
7581 WLANTL_SuspendDataTx( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
7582 &staId, NULL);
7583 }
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -07007584 wlan_hdd_tdls_increment_peer_count(pAdapter);
7585 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007586 wlan_hdd_tdls_check_bmps(pAdapter);
7587 }
7588
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007589 }
7590 break;
7591 case NL80211_TDLS_DISABLE_LINK:
Lee Hoonkic1262f22013-01-24 21:59:00 -08007592 {
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007593 if(TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
Lee Hoonkic1262f22013-01-24 21:59:00 -08007594 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007595 long status;
7596
7597 INIT_COMPLETION(pAdapter->tdls_del_station_comp);
7598
Lee Hoonkic1262f22013-01-24 21:59:00 -08007599 sme_DeleteTdlsPeerSta( WLAN_HDD_GET_HAL_CTX(pAdapter),
7600 pAdapter->sessionId, peer );
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007601
7602 status = wait_for_completion_interruptible_timeout(&pAdapter->tdls_del_station_comp,
7603 msecs_to_jiffies(WAIT_TIME_TDLS_DEL_STA));
7604 if (status <= 0)
7605 {
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007606 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer, eTDLS_LINK_IDLE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007607 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7608 "%s: Del station failed status %ld",
7609 __func__, status);
7610 return -EPERM;
7611 }
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007612 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer, eTDLS_LINK_IDLE);
Lee Hoonkic1262f22013-01-24 21:59:00 -08007613 }
7614 else
7615 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007616 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7617 "%s: TDLS Peer Station doesn't exist.", __func__);
Lee Hoonkic1262f22013-01-24 21:59:00 -08007618 }
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05307619#ifdef FEATURE_WLAN_TDLS_OXYGEN_DISAPPEAR_AP
7620 if (pHddTdlsCtx->defer_link_lost_indication)
7621 {
7622 if (( TRUE == pHddCtx->cfg_ini->fEnableTDLSOxygenSupport ) &&
7623 (wlan_hdd_tdlsConnectedPeers(pAdapter) == 0))
7624 {
7625 status = wlan_hdd_disconnect(pAdapter, eCSR_DISCONNECT_REASON_UNSPECIFIED);
7626 if ( 0 != status)
7627 {
7628 hddLog(VOS_TRACE_LEVEL_ERROR,
7629 "%s wlan_hdd_disconnect failure, returned %d \n",
7630 __func__, (int)status );
7631 return -EINVAL;
7632 }
7633 }
7634 }
7635#endif
Lee Hoonkic1262f22013-01-24 21:59:00 -08007636 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007637 break;
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007638 case NL80211_TDLS_TEARDOWN:
7639 case NL80211_TDLS_SETUP:
7640 case NL80211_TDLS_DISCOVERY_REQ:
7641 /* We don't support in-driver setup/teardown/discovery */
7642 return -ENOTSUPP;
7643 default:
7644 return -ENOTSUPP;
7645 }
7646 return 0;
7647}
Chilam NG571c65a2013-01-19 12:27:36 +05307648
7649int wlan_hdd_cfg80211_send_tdls_discover_req(struct wiphy *wiphy,
7650 struct net_device *dev, u8 *peer)
7651{
7652 hddLog(VOS_TRACE_LEVEL_INFO, "tdls send discover req: %x %x %x %x %x %x",
7653 peer[0], peer[1], peer[2], peer[3], peer[4], peer[5]);
7654
7655 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
7656 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, NULL, 0);
7657}
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007658#endif
7659
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05307660#ifdef WLAN_FEATURE_GTK_OFFLOAD
7661/*
7662 * FUNCTION: wlan_hdd_cfg80211_update_replayCounterCallback
7663 * Callback rountine called upon receiving response for
7664 * get offload info
7665 */
7666void wlan_hdd_cfg80211_update_replayCounterCallback(void *callbackContext,
7667 tpSirGtkOffloadGetInfoRspParams pGtkOffloadGetInfoRsp)
7668{
7669
7670 hdd_adapter_t *pAdapter = (hdd_adapter_t *)callbackContext;
7671
7672 ENTER();
7673
7674 if (NULL == pAdapter)
7675 {
7676 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
7677 "%s: HDD adapter is Null", __func__);
7678 return ;
7679 }
7680
7681 if (NULL == pGtkOffloadGetInfoRsp)
7682 {
7683 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7684 "%s: pGtkOffloadGetInfoRsp is Null", __func__);
7685 return ;
7686 }
7687
7688 if (VOS_STATUS_SUCCESS != pGtkOffloadGetInfoRsp->ulStatus)
7689 {
7690 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7691 "%s: wlan Failed to get replay counter value",
7692 __func__);
7693 return ;
7694 }
7695
7696 /* Update replay counter to NL */
7697 cfg80211_gtk_rekey_notify(pAdapter->dev, pGtkOffloadGetInfoRsp->bssId,
7698 (tANI_U8 *)&pGtkOffloadGetInfoRsp->ullKeyReplayCounter, GFP_KERNEL);
7699}
7700
7701/*
7702 * FUNCTION: wlan_hdd_cfg80211_set_rekey_data
7703 * This function is used to offload GTK rekeying job to the firmware.
7704 */
7705int wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
7706 struct cfg80211_gtk_rekey_data *data)
7707{
7708 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
7709 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
7710 hdd_station_ctx_t *pHddStaCtx;
7711 tHalHandle hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307712 int result;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05307713 tpSirGtkOffloadParams pGtkOffloadReqParams;
7714 eHalStatus status = eHAL_STATUS_FAILURE;
7715
7716 ENTER();
7717
7718 if (NULL == pAdapter)
7719 {
7720 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
7721 "%s: HDD adapter is Null", __func__);
7722 return -ENODEV;
7723 }
7724
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307725 result = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05307726
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307727 if (0 != result)
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05307728 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307729 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7730 "%s: HDD context is not valid", __func__);
7731 return result;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05307732 }
7733
7734 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7735 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
7736 if (NULL == hHal)
7737 {
7738 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7739 "%s: HAL context is Null!!!", __func__);
7740 return -EAGAIN;
7741 }
7742
7743 pGtkOffloadReqParams =
7744 &pHddStaCtx->gtkOffloadRequestParams.gtkOffloadReqParams;
7745
7746 pGtkOffloadReqParams->ulFlags = GTK_OFFLOAD_ENABLE;
7747 memcpy(pGtkOffloadReqParams->aKCK, data->kck, NL80211_KCK_LEN);
7748 memcpy(pGtkOffloadReqParams->aKEK, data->kek, NL80211_KEK_LEN);
7749 memcpy(pGtkOffloadReqParams->bssId, &pHddStaCtx->conn_info.bssId,
7750 WNI_CFG_BSSID_LEN);
7751 memcpy(&pGtkOffloadReqParams->ullKeyReplayCounter, &data->replay_ctr,
7752 sizeof (tANI_U64));
7753
7754 if (TRUE == pHddCtx->hdd_wlan_suspended)
7755 {
7756 /* if wlan is suspended, enable GTK offload directly from here */
7757 status = sme_SetGTKOffload(hHal, pGtkOffloadReqParams,
7758 pAdapter->sessionId);
7759
7760 if (eHAL_STATUS_SUCCESS != status)
7761 {
7762 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7763 "%s: sme_SetGTKOffload failed, returned %d",
7764 __func__, status);
7765 return status;
7766 }
7767 pHddStaCtx->gtkOffloadRequestParams.requested = FALSE;
7768 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
7769 "%s: sme_SetGTKOffload successfull", __func__);
7770 }
7771 else
7772 {
7773 pHddStaCtx->gtkOffloadRequestParams.requested = TRUE;
7774 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
7775 "%s: wlan not suspended GTKOffload request is stored",
7776 __func__);
7777 return eHAL_STATUS_SUCCESS;
7778 }
7779 return status;
7780}
7781#endif /*WLAN_FEATURE_GTK_OFFLOAD*/
7782
Jeff Johnson295189b2012-06-20 16:38:30 -07007783/* cfg80211_ops */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307784static struct cfg80211_ops wlan_hdd_cfg80211_ops =
Jeff Johnson295189b2012-06-20 16:38:30 -07007785{
7786 .add_virtual_intf = wlan_hdd_add_virtual_intf,
7787 .del_virtual_intf = wlan_hdd_del_virtual_intf,
7788 .change_virtual_intf = wlan_hdd_cfg80211_change_iface,
7789 .change_station = wlan_hdd_change_station,
7790#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
7791 .add_beacon = wlan_hdd_cfg80211_add_beacon,
7792 .del_beacon = wlan_hdd_cfg80211_del_beacon,
7793 .set_beacon = wlan_hdd_cfg80211_set_beacon,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007794#else
7795 .start_ap = wlan_hdd_cfg80211_start_ap,
7796 .change_beacon = wlan_hdd_cfg80211_change_beacon,
7797 .stop_ap = wlan_hdd_cfg80211_stop_ap,
Jeff Johnson295189b2012-06-20 16:38:30 -07007798#endif
7799 .change_bss = wlan_hdd_cfg80211_change_bss,
7800 .add_key = wlan_hdd_cfg80211_add_key,
7801 .get_key = wlan_hdd_cfg80211_get_key,
7802 .del_key = wlan_hdd_cfg80211_del_key,
7803 .set_default_key = wlan_hdd_cfg80211_set_default_key,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -08007804#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07007805 .set_channel = wlan_hdd_cfg80211_set_channel,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -08007806#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007807 .scan = wlan_hdd_cfg80211_scan,
7808 .connect = wlan_hdd_cfg80211_connect,
7809 .disconnect = wlan_hdd_cfg80211_disconnect,
7810 .join_ibss = wlan_hdd_cfg80211_join_ibss,
7811 .leave_ibss = wlan_hdd_cfg80211_leave_ibss,
7812 .set_wiphy_params = wlan_hdd_cfg80211_set_wiphy_params,
7813 .set_tx_power = wlan_hdd_cfg80211_set_txpower,
7814 .get_tx_power = wlan_hdd_cfg80211_get_txpower,
Jeff Johnson295189b2012-06-20 16:38:30 -07007815 .remain_on_channel = wlan_hdd_cfg80211_remain_on_channel,
7816 .cancel_remain_on_channel = wlan_hdd_cfg80211_cancel_remain_on_channel,
7817 .mgmt_tx = wlan_hdd_action,
7818#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
7819 .mgmt_tx_cancel_wait = wlan_hdd_cfg80211_mgmt_tx_cancel_wait,
7820 .set_default_mgmt_key = wlan_hdd_set_default_mgmt_key,
7821 .set_txq_params = wlan_hdd_set_txq_params,
7822#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007823 .get_station = wlan_hdd_cfg80211_get_station,
7824 .set_power_mgmt = wlan_hdd_cfg80211_set_power_mgmt,
7825 .del_station = wlan_hdd_cfg80211_del_station,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007826 .add_station = wlan_hdd_cfg80211_add_station,
7827#ifdef FEATURE_WLAN_LFR
7828 .set_pmksa = wlan_hdd_cfg80211_set_pmksa,
7829 .del_pmksa = wlan_hdd_cfg80211_del_pmksa,
7830 .flush_pmksa = wlan_hdd_cfg80211_flush_pmksa,
7831#endif
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07007832#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
7833 .update_ft_ies = wlan_hdd_cfg80211_update_ft_ies,
7834#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007835#ifdef FEATURE_WLAN_TDLS
7836 .tdls_mgmt = wlan_hdd_cfg80211_tdls_mgmt,
7837 .tdls_oper = wlan_hdd_cfg80211_tdls_oper,
7838#endif
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05307839#ifdef WLAN_FEATURE_GTK_OFFLOAD
7840 .set_rekey_data = wlan_hdd_cfg80211_set_rekey_data,
7841#endif /* WLAN_FEATURE_GTK_OFFLOAD */
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05307842#ifdef FEATURE_WLAN_SCAN_PNO
7843 .sched_scan_start = wlan_hdd_cfg80211_sched_scan_start,
7844 .sched_scan_stop = wlan_hdd_cfg80211_sched_scan_stop,
7845#endif /*FEATURE_WLAN_SCAN_PNO */
Jeff Johnson295189b2012-06-20 16:38:30 -07007846};
7847