blob: 55f8af208643ffac3ddfabe71acd555a6b598ccc [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 Johnson295189b2012-06-20 16:38:30 -0700325 [NL80211_IFTYPE_P2P_CLIENT] = {
326 .tx = 0xffff,
327 .rx = BIT(SIR_MAC_MGMT_ACTION) |
328 BIT(SIR_MAC_MGMT_PROBE_REQ),
329 },
330 [NL80211_IFTYPE_P2P_GO] = {
331 /* This is also same as for SoftAP */
332 .tx = 0xffff,
333 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
334 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
335 BIT(SIR_MAC_MGMT_PROBE_REQ) |
336 BIT(SIR_MAC_MGMT_DISASSOC) |
337 BIT(SIR_MAC_MGMT_AUTH) |
338 BIT(SIR_MAC_MGMT_DEAUTH) |
339 BIT(SIR_MAC_MGMT_ACTION),
340 },
Jeff Johnson295189b2012-06-20 16:38:30 -0700341};
342
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800343#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800344static const struct ieee80211_iface_limit
345wlan_hdd_iface_limit[] = {
346 {
Sunil Ravia72c3992013-01-31 06:12:22 -0800347 /* max = 3 ; Our driver create two interfaces during driver init
348 * wlan0 and p2p0 interfaces. p2p0 is considered as station
349 * interface until a group is formed. In JB architecture, once the
350 * group is formed, interface type of p2p0 is changed to P2P GO or
351 * Client.
352 * When supplicant remove the group, it first issue a set interface
353 * cmd to change the mode back to Station. In JB this works fine as
354 * we advertize two station type interface during driver init.
355 * Some vendors create separate interface for P2P GO/Client,
356 * after group formation(Third one). But while group remove
357 * supplicant first tries to change the mode(3rd interface) to STATION
358 * But as we advertized only two sta type interfaces nl80211 was
359 * returning error for the third one which was leading to failure in
360 * delete interface. Ideally while removing the group, supplicant
361 * should not try to change the 3rd interface mode to Station type.
362 * Till we get a fix in wpa_supplicant, we advertize max STA
363 * interface type to 3
364 */
365 .max = 3,
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800366 .types = BIT(NL80211_IFTYPE_STATION),
367 },
368 {
369 .max = 1,
370 .types = BIT(NL80211_IFTYPE_AP),
371 },
372 {
373 .max = 1,
374 .types = BIT(NL80211_IFTYPE_P2P_GO) |
375 BIT(NL80211_IFTYPE_P2P_CLIENT),
376 },
377};
378
379/* By default, only single channel concurrency is allowed */
380static struct ieee80211_iface_combination
381wlan_hdd_iface_combination = {
382 .limits = wlan_hdd_iface_limit,
383 .num_different_channels = 1,
Sunil Ravia72c3992013-01-31 06:12:22 -0800384 /*
385 * max = WLAN_MAX_INTERFACES ; JellyBean architecture creates wlan0
386 * and p2p0 interfaces during driver init
387 * Some vendors create separate interface for P2P operations.
388 * wlan0: STA interface
389 * p2p0: P2P Device interface, action frames goes
390 * through this interface.
391 * p2p-xx: P2P interface, After GO negotiation this interface is
392 * created for p2p operations(GO/CLIENT interface).
393 */
394 .max_interfaces = WLAN_MAX_INTERFACES,
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800395 .n_limits = ARRAY_SIZE(wlan_hdd_iface_limit),
396 .beacon_int_infra_match = false,
397};
398#endif
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800399
Jeff Johnson295189b2012-06-20 16:38:30 -0700400static struct cfg80211_ops wlan_hdd_cfg80211_ops;
401
402/* Data rate 100KBPS based on IE Index */
403struct index_data_rate_type
404{
405 v_U8_t beacon_rate_index;
406 v_U16_t supported_rate[4];
407};
408
409/* 11B, 11G Rate table include Basic rate and Extended rate
410 The IDX field is the rate index
411 The HI field is the rate when RSSI is strong or being ignored
412 (in this case we report actual rate)
413 The MID field is the rate when RSSI is moderate
414 (in this case we cap 11b rates at 5.5 and 11g rates at 24)
415 The LO field is the rate when RSSI is low
416 (in this case we don't report rates, actual current rate used)
417 */
418static const struct
419{
420 v_U8_t beacon_rate_index;
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -0700421 v_U16_t supported_rate[4];
Jeff Johnson295189b2012-06-20 16:38:30 -0700422} supported_data_rate[] =
423{
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -0700424/* IDX HI HM LM LO (RSSI-based index */
425 {2, { 10, 10, 10, 0}},
426 {4, { 20, 20, 10, 0}},
427 {11, { 55, 20, 10, 0}},
428 {12, { 60, 55, 20, 0}},
429 {18, { 90, 55, 20, 0}},
430 {22, {110, 55, 20, 0}},
431 {24, {120, 90, 60, 0}},
432 {36, {180, 120, 60, 0}},
433 {44, {220, 180, 60, 0}},
434 {48, {240, 180, 90, 0}},
435 {66, {330, 180, 90, 0}},
436 {72, {360, 240, 90, 0}},
437 {96, {480, 240, 120, 0}},
438 {108, {540, 240, 120, 0}}
Jeff Johnson295189b2012-06-20 16:38:30 -0700439};
440
441/* MCS Based rate table */
442static struct index_data_rate_type supported_mcs_rate[] =
443{
444/* MCS L20 L40 S20 S40 */
445 {0, {65, 135, 72, 150}},
446 {1, {130, 270, 144, 300}},
447 {2, {195, 405, 217, 450}},
448 {3, {260, 540, 289, 600}},
449 {4, {390, 810, 433, 900}},
450 {5, {520, 1080, 578, 1200}},
451 {6, {585, 1215, 650, 1350}},
452 {7, {650, 1350, 722, 1500}}
453};
454
Leo Chang6f8870f2013-03-26 18:11:36 -0700455#ifdef WLAN_FEATURE_11AC
456
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530457#define DATA_RATE_11AC_MCS_MASK 0x03
Leo Chang6f8870f2013-03-26 18:11:36 -0700458
459struct index_vht_data_rate_type
460{
461 v_U8_t beacon_rate_index;
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530462 v_U16_t supported_VHT80_rate[2];
463 v_U16_t supported_VHT40_rate[2];
464 v_U16_t supported_VHT20_rate[2];
Leo Chang6f8870f2013-03-26 18:11:36 -0700465};
466
467typedef enum
468{
469 DATA_RATE_11AC_MAX_MCS_7,
470 DATA_RATE_11AC_MAX_MCS_8,
471 DATA_RATE_11AC_MAX_MCS_9,
472 DATA_RATE_11AC_MAX_MCS_NA
473} eDataRate11ACMaxMcs;
474
475/* MCS Based VHT rate table */
476static struct index_vht_data_rate_type supported_vht_mcs_rate[] =
477{
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530478/* MCS L80 S80 L40 S40 L20 S40*/
479 {0, {293, 325}, {135, 150}, {65, 72}},
480 {1, {585, 650}, {270, 300}, {130, 144}},
481 {2, {878, 975}, {405, 450}, {195, 217}},
482 {3, {1170, 1300}, {540, 600}, {260, 289}},
483 {4, {1755, 1950}, {810, 900}, {390, 433}},
484 {5, {2340, 2600}, {1080, 1200}, {520, 578}},
485 {6, {2633, 2925}, {1215, 1350}, {585, 650}},
486 {7, {2925, 3250}, {1350, 1500}, {650, 722}},
487 {8, {3510, 3900}, {1620, 1800}, {780, 867}},
488 {9, {3900, 4333}, {1800, 2000}, {780, 867}}
Leo Chang6f8870f2013-03-26 18:11:36 -0700489};
490#endif /* WLAN_FEATURE_11AC */
491
Jeff Johnson295189b2012-06-20 16:38:30 -0700492extern struct net_device_ops net_ops_struct;
493
494/*
495 * FUNCTION: wlan_hdd_cfg80211_init
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530496 * This function is called by hdd_wlan_startup()
497 * during initialization.
Jeff Johnson295189b2012-06-20 16:38:30 -0700498 * This function is used to initialize and register wiphy structure.
499 */
500struct wiphy *wlan_hdd_cfg80211_init(int priv_size)
501{
502 struct wiphy *wiphy;
503 ENTER();
504
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530505 /*
506 * Create wiphy device
Jeff Johnson295189b2012-06-20 16:38:30 -0700507 */
508 wiphy = wiphy_new(&wlan_hdd_cfg80211_ops, priv_size);
509
510 if (!wiphy)
511 {
512 /* Print error and jump into err label and free the memory */
513 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wiphy init failed", __func__);
514 return NULL;
515 }
516
517 return wiphy;
518}
519
520/*
521 * FUNCTION: wlan_hdd_cfg80211_update_band
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530522 * This function is called from the supplicant through a
Jeff Johnson295189b2012-06-20 16:38:30 -0700523 * private ioctl to change the band value
524 */
525int wlan_hdd_cfg80211_update_band(struct wiphy *wiphy, eCsrBand eBand)
526{
Jeff Johnsone7245742012-09-05 17:12:55 -0700527 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -0700528 switch(eBand)
529 {
530 case eCSR_BAND_24:
531 wiphy->bands[IEEE80211_BAND_2GHZ] = &wlan_hdd_band_2_4_GHZ;
532 wiphy->bands[IEEE80211_BAND_5GHZ] = NULL;
533 break;
534 case eCSR_BAND_5G:
Madan Mohan Koyyalamudi6f6390c2012-09-24 13:57:46 -0700535 wiphy->bands[IEEE80211_BAND_2GHZ] = &wlan_hdd_band_p2p_2_4_GHZ;
Jeff Johnson295189b2012-06-20 16:38:30 -0700536 wiphy->bands[IEEE80211_BAND_5GHZ] = &wlan_hdd_band_5_GHZ;
537 break;
538 case eCSR_BAND_ALL:
539 default:
540 wiphy->bands[IEEE80211_BAND_2GHZ] = &wlan_hdd_band_2_4_GHZ;
541 wiphy->bands[IEEE80211_BAND_5GHZ] = &wlan_hdd_band_5_GHZ;
542 }
543 return 0;
544}
545/*
546 * FUNCTION: wlan_hdd_cfg80211_init
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530547 * This function is called by hdd_wlan_startup()
548 * during initialization.
Jeff Johnson295189b2012-06-20 16:38:30 -0700549 * This function is used to initialize and register wiphy structure.
550 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530551int wlan_hdd_cfg80211_register(struct device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -0700552 struct wiphy *wiphy,
553 hdd_config_t *pCfg
554 )
555{
Jeff Johnsone7245742012-09-05 17:12:55 -0700556 ENTER();
557
Jeff Johnson295189b2012-06-20 16:38:30 -0700558 /* Now bind the underlying wlan device with wiphy */
559 set_wiphy_dev(wiphy, dev);
560
561 wiphy->mgmt_stypes = wlan_hdd_txrx_stypes;
562
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -0700563 wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY;
Jeff Johnson295189b2012-06-20 16:38:30 -0700564
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700565#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -0700566 wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME
567 | WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD
568 | WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL
Jeff Johnsone7245742012-09-05 17:12:55 -0700569 | WIPHY_FLAG_OFFCHAN_TX;
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700570#endif
Srinivas Girigowda640728a2013-03-28 12:21:54 -0700571#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_CCX) || defined(FEATURE_WLAN_LFR)
572 if (pCfg->isFastTransitionEnabled
James Zmuda77fb5ae2013-01-29 08:00:17 -0800573#ifdef FEATURE_WLAN_LFR
Srinivas Girigowda640728a2013-03-28 12:21:54 -0700574 || pCfg->isFastRoamIniFeatureEnabled
575#endif
576#ifdef FEATURE_WLAN_CCX
577 || pCfg->isCcxIniFeatureEnabled
578#endif
579 )
580 {
581 wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM;
582 }
James Zmuda77fb5ae2013-01-29 08:00:17 -0800583#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -0800584#ifdef FEATURE_WLAN_TDLS
585 wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS
586 | WIPHY_FLAG_TDLS_EXTERNAL_SETUP;
587#endif
588
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -0700589 /* even with WIPHY_FLAG_CUSTOM_REGULATORY,
590 driver can still register regulatory callback and
591 it will get CRDA setting in wiphy->band[], but
592 driver need to determine what to do with both
593 regulatory settings */
594 wiphy->reg_notifier = wlan_hdd_crda_reg_notifier;
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700595
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530596 wiphy->max_scan_ssids = MAX_SCAN_SSID;
597
Jeff Johnson295189b2012-06-20 16:38:30 -0700598 wiphy->max_scan_ie_len = 200 ; //TODO: define a macro
599
600 /* Supports STATION & AD-HOC modes right now */
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530601 wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -0700602 | BIT(NL80211_IFTYPE_ADHOC)
Jeff Johnson295189b2012-06-20 16:38:30 -0700603 | BIT(NL80211_IFTYPE_P2P_CLIENT)
604 | BIT(NL80211_IFTYPE_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -0700605 | BIT(NL80211_IFTYPE_AP);
606
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800607#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800608 if( pCfg->enableMCC )
609 {
610 /* Currently, supports up to two channels */
611 wlan_hdd_iface_combination.num_different_channels = 2;
612
613 if( !pCfg->allowMCCGODiffBI )
614 wlan_hdd_iface_combination.beacon_int_infra_match = true;
615
616 }
617 wiphy->iface_combinations = &wlan_hdd_iface_combination;
618 wiphy->n_iface_combinations = 1;
619#endif
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800620
Jeff Johnson295189b2012-06-20 16:38:30 -0700621 /* Before registering we need to update the ht capabilitied based
622 * on ini values*/
623 if( !pCfg->ShortGI20MhzEnable )
624 {
625 wlan_hdd_band_2_4_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
626 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
627 wlan_hdd_band_p2p_2_4_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
628 }
629
630 if( !pCfg->ShortGI40MhzEnable )
631 {
632 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_40;
633 }
634
635 if( !pCfg->nChannelBondingMode5GHz )
636 {
637 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
638 }
639
640 /*Initialize band capability*/
641 switch(pCfg->nBandCapability)
642 {
643 case eCSR_BAND_24:
644 wiphy->bands[IEEE80211_BAND_2GHZ] = &wlan_hdd_band_2_4_GHZ;
645 break;
646 case eCSR_BAND_5G:
Jeff Johnson295189b2012-06-20 16:38:30 -0700647 wiphy->bands[IEEE80211_BAND_2GHZ] = &wlan_hdd_band_p2p_2_4_GHZ;
Jeff Johnson295189b2012-06-20 16:38:30 -0700648 wiphy->bands[IEEE80211_BAND_5GHZ] = &wlan_hdd_band_5_GHZ;
649 break;
650 case eCSR_BAND_ALL:
651 default:
652 wiphy->bands[IEEE80211_BAND_2GHZ] = &wlan_hdd_band_2_4_GHZ;
653 wiphy->bands[IEEE80211_BAND_5GHZ] = &wlan_hdd_band_5_GHZ;
654 }
655 /*Initialise the supported cipher suite details*/
656 wiphy->cipher_suites = hdd_cipher_suites;
657 wiphy->n_cipher_suites = ARRAY_SIZE(hdd_cipher_suites);
658
659 /*signal strength in mBm (100*dBm) */
660 wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
661
662#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Jeff Johnson295189b2012-06-20 16:38:30 -0700663 wiphy->max_remain_on_channel_duration = 1000;
664#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700665
666 /* Register our wiphy dev with cfg80211 */
667 if (0 > wiphy_register(wiphy))
668 {
669 /* print eror */
670 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
671 return -EIO;
672 }
673
674 EXIT();
675 return 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530676}
Jeff Johnson295189b2012-06-20 16:38:30 -0700677
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -0700678/* In this function we will try to get default country code from crda.
679 If the gCrdaDefaultCountryCode is configured in ini file,
680 we will try to call user space crda to get the regulatory settings for
681 that country. We will timeout if we can't get it from crda.
682 It's called by hdd_wlan_startup() after wlan_hdd_cfg80211_register.
683*/
684int wlan_hdd_get_crda_regd_entry(struct wiphy *wiphy, hdd_config_t *pCfg)
685{
686 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
687 if (memcmp(pCfg->crdaDefaultCountryCode,
688 CFG_CRDA_DEFAULT_COUNTRY_CODE_DEFAULT , 2) != 0)
689 {
690 init_completion(&pHddCtx->driver_crda_req);
691 regulatory_hint(wiphy, pCfg->crdaDefaultCountryCode);
692 wait_for_completion_interruptible_timeout(&pHddCtx->driver_crda_req,
693 CRDA_WAIT_TIME);
Yunsen Wange3ba1fb2013-04-05 15:04:43 -0700694 /* if the country is not found from current regulatory.bin,
695 fall back to world domain */
696 if (is_crda_regulatory_entry_valid() == VOS_FALSE)
697 crda_regulatory_entry_default(pCfg->crdaDefaultCountryCode, NUM_REG_DOMAINS-1);
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -0700698 }
699 return 0;
700}
701
Jeff Johnson295189b2012-06-20 16:38:30 -0700702/* In this function we will do all post VOS start initialization.
703 In this function we will register for all frame in which supplicant
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530704 is interested.
Jeff Johnson295189b2012-06-20 16:38:30 -0700705*/
706void wlan_hdd_cfg80211_post_voss_start(hdd_adapter_t* pAdapter)
707{
Jeff Johnson295189b2012-06-20 16:38:30 -0700708 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
709 /* Register for all P2P action, public action etc frames */
710 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
711
Jeff Johnsone7245742012-09-05 17:12:55 -0700712 ENTER();
713
Jeff Johnson295189b2012-06-20 16:38:30 -0700714 /* Right now we are registering these frame when driver is getting
715 initialized. Once we will move to 2.6.37 kernel, in which we have
716 frame register ops, we will move this code as a part of that */
717 /* GAS Initial Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530718 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Jeff Johnson295189b2012-06-20 16:38:30 -0700719 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
720
721 /* GAS Initial Response */
722 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
723 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530724
Jeff Johnson295189b2012-06-20 16:38:30 -0700725 /* GAS Comeback Request */
726 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
727 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
728
729 /* GAS Comeback Response */
730 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
731 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
732
733 /* P2P Public Action */
734 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530735 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -0700736 P2P_PUBLIC_ACTION_FRAME_SIZE );
737
738 /* P2P Action */
739 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
740 (v_U8_t*)P2P_ACTION_FRAME,
741 P2P_ACTION_FRAME_SIZE );
Chet Lanctot186b5732013-03-18 10:26:30 -0700742
Gopichand Nakkalae3d56e72013-04-21 23:33:32 +0530743 /* WNM BSS Transition Request frame */
744 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
745 (v_U8_t*)WNM_BSS_ACTION_FRAME,
746 WNM_BSS_ACTION_FRAME_SIZE );
747
Chet Lanctot186b5732013-03-18 10:26:30 -0700748#ifdef WLAN_FEATURE_11W
749 /* SA Query Response Action Frame */
750 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
751 (v_U8_t*)SA_QUERY_FRAME_RSP,
752 SA_QUERY_FRAME_RSP_SIZE );
753#endif /* WLAN_FEATURE_11W */
Jeff Johnson295189b2012-06-20 16:38:30 -0700754}
755
756void wlan_hdd_cfg80211_pre_voss_stop(hdd_adapter_t* pAdapter)
757{
Jeff Johnson295189b2012-06-20 16:38:30 -0700758 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
759 /* Register for all P2P action, public action etc frames */
760 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
761
Jeff Johnsone7245742012-09-05 17:12:55 -0700762 ENTER();
763
Jeff Johnson295189b2012-06-20 16:38:30 -0700764 /* Right now we are registering these frame when driver is getting
765 initialized. Once we will move to 2.6.37 kernel, in which we have
766 frame register ops, we will move this code as a part of that */
767 /* GAS Initial Request */
768
769 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
770 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
771
772 /* GAS Initial Response */
773 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
774 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530775
Jeff Johnson295189b2012-06-20 16:38:30 -0700776 /* GAS Comeback Request */
777 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
778 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
779
780 /* GAS Comeback Response */
781 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
782 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
783
784 /* P2P Public Action */
785 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530786 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -0700787 P2P_PUBLIC_ACTION_FRAME_SIZE );
788
789 /* P2P Action */
790 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
791 (v_U8_t*)P2P_ACTION_FRAME,
792 P2P_ACTION_FRAME_SIZE );
Chet Lanctot186b5732013-03-18 10:26:30 -0700793
794#ifdef WLAN_FEATURE_11W
795 /* SA Query Response Action Frame */
796 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
797 (v_U8_t*)SA_QUERY_FRAME_RSP,
798 SA_QUERY_FRAME_RSP_SIZE );
799#endif /* WLAN_FEATURE_11W */
Jeff Johnson295189b2012-06-20 16:38:30 -0700800}
801
802#ifdef FEATURE_WLAN_WAPI
803void wlan_hdd_cfg80211_set_key_wapi(hdd_adapter_t* pAdapter, u8 key_index,
804 const u8 *mac_addr, u8 *key , int key_Len)
805{
806 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
807 tCsrRoamSetKey setKey;
808 v_BOOL_t isConnected = TRUE;
809 int status = 0;
810 v_U32_t roamId= 0xFF;
811 tANI_U8 *pKeyPtr = NULL;
812 int n = 0;
813
814 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",
815 __func__,pAdapter->device_mode);
816
Gopichand Nakkalae7480202013-02-11 15:24:22 +0530817 vos_mem_zero(&setKey, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -0700818 setKey.keyId = key_index; // Store Key ID
819 setKey.encType = eCSR_ENCRYPT_TYPE_WPI; // SET WAPI Encryption
820 setKey.keyDirection = eSIR_TX_RX; // Key Directionn both TX and RX
821 setKey.paeRole = 0 ; // the PAE role
822 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
823 {
824 vos_set_macaddr_broadcast( (v_MACADDR_t *)setKey.peerMac );
825 }
826 else
827 {
828 isConnected = hdd_connIsConnected(pHddStaCtx);
829 vos_mem_copy(setKey.peerMac,&pHddStaCtx->conn_info.bssId,WNI_CFG_BSSID_LEN);
830 }
831 setKey.keyLength = key_Len;
832 pKeyPtr = setKey.Key;
833 memcpy( pKeyPtr, key, key_Len);
834
835 hddLog(VOS_TRACE_LEVEL_INFO,"\n%s: WAPI KEY LENGTH:0x%04x",
836 __func__, key_Len);
837 for (n = 0 ; n < key_Len; n++)
838 hddLog(VOS_TRACE_LEVEL_INFO, "%s WAPI KEY Data[%d]:%02x ",
839 __func__,n,setKey.Key[n]);
840
841 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
842 if ( isConnected )
843 {
844 status= sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
845 pAdapter->sessionId, &setKey, &roamId );
846 }
847 if ( status != 0 )
848 {
849 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
850 "[%4d] sme_RoamSetKey returned ERROR status= %d",
851 __LINE__, status );
852 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
853 }
854}
855#endif /* FEATURE_WLAN_WAPI*/
856
857#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530858int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -0700859 beacon_data_t **ppBeacon,
860 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700861#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530862int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700863 beacon_data_t **ppBeacon,
864 struct cfg80211_beacon_data *params,
865 int dtim_period)
866#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530867{
Jeff Johnson295189b2012-06-20 16:38:30 -0700868 int size;
869 beacon_data_t *beacon = NULL;
870 beacon_data_t *old = NULL;
871 int head_len,tail_len;
872
Jeff Johnsone7245742012-09-05 17:12:55 -0700873 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -0700874 if (params->head && !params->head_len)
875 return -EINVAL;
876
877 old = pAdapter->sessionCtx.ap.beacon;
878
879 if (!params->head && !old)
880 return -EINVAL;
881
882 if (params->tail && !params->tail_len)
883 return -EINVAL;
884
885#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,38))
886 /* Kernel 3.0 is not updating dtim_period for set beacon */
887 if (!params->dtim_period)
888 return -EINVAL;
889#endif
890
891 if(params->head)
892 head_len = params->head_len;
893 else
894 head_len = old->head_len;
895
896 if(params->tail || !old)
897 tail_len = params->tail_len;
898 else
899 tail_len = old->tail_len;
900
901 size = sizeof(beacon_data_t) + head_len + tail_len;
902
903 beacon = kzalloc(size, GFP_KERNEL);
904
905 if( beacon == NULL )
906 return -ENOMEM;
907
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700908#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -0700909 if(params->dtim_period || !old )
910 beacon->dtim_period = params->dtim_period;
911 else
912 beacon->dtim_period = old->dtim_period;
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700913#else
914 if(dtim_period || !old )
915 beacon->dtim_period = dtim_period;
916 else
917 beacon->dtim_period = old->dtim_period;
918#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530919
Jeff Johnson295189b2012-06-20 16:38:30 -0700920 beacon->head = ((u8 *) beacon) + sizeof(beacon_data_t);
921 beacon->tail = beacon->head + head_len;
922 beacon->head_len = head_len;
923 beacon->tail_len = tail_len;
924
925 if(params->head) {
926 memcpy (beacon->head,params->head,beacon->head_len);
927 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530928 else {
Jeff Johnson295189b2012-06-20 16:38:30 -0700929 if(old)
930 memcpy (beacon->head,old->head,beacon->head_len);
931 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530932
Jeff Johnson295189b2012-06-20 16:38:30 -0700933 if(params->tail) {
934 memcpy (beacon->tail,params->tail,beacon->tail_len);
935 }
936 else {
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530937 if(old)
Jeff Johnson295189b2012-06-20 16:38:30 -0700938 memcpy (beacon->tail,old->tail,beacon->tail_len);
939 }
940
941 *ppBeacon = beacon;
942
943 kfree(old);
944
945 return 0;
946
947}
Jeff Johnson295189b2012-06-20 16:38:30 -0700948
949v_U8_t* wlan_hdd_cfg80211_get_ie_ptr(v_U8_t *pIes, int length, v_U8_t eid)
950{
951 int left = length;
952 v_U8_t *ptr = pIes;
953 v_U8_t elem_id,elem_len;
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530954
Jeff Johnson295189b2012-06-20 16:38:30 -0700955 while(left >= 2)
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530956 {
Jeff Johnson295189b2012-06-20 16:38:30 -0700957 elem_id = ptr[0];
958 elem_len = ptr[1];
959 left -= 2;
960 if(elem_len > left)
961 {
962 hddLog(VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -0700963 FL("****Invalid IEs eid = %d elem_len=%d left=%d*****"),
Jeff Johnson295189b2012-06-20 16:38:30 -0700964 eid,elem_len,left);
965 return NULL;
966 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530967 if (elem_id == eid)
Jeff Johnson295189b2012-06-20 16:38:30 -0700968 {
969 return ptr;
970 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530971
Jeff Johnson295189b2012-06-20 16:38:30 -0700972 left -= elem_len;
973 ptr += (elem_len + 2);
974 }
975 return NULL;
976}
977
Jeff Johnson295189b2012-06-20 16:38:30 -0700978/* Check if rate is 11g rate or not */
979static int wlan_hdd_rate_is_11g(u8 rate)
980{
981 u8 gRateArray[8] = {12, 18, 24, 36, 48, 72, 96, 104}; /* actual rate * 2 */
982 u8 i;
983 for (i = 0; i < 8; i++)
984 {
985 if(rate == gRateArray[i])
986 return TRUE;
987 }
988 return FALSE;
989}
990
991/* Check for 11g rate and set proper 11g only mode */
992static void wlan_hdd_check_11gmode(u8 *pIe, u8* require_ht,
993 u8* pCheckRatesfor11g, eSapPhyMode* pSapHw_mode)
994{
995 u8 i, num_rates = pIe[0];
996
997 pIe += 1;
998 for ( i = 0; i < num_rates; i++)
999 {
1000 if( *pCheckRatesfor11g && (TRUE == wlan_hdd_rate_is_11g(pIe[i] & RATE_MASK)))
1001 {
1002 /* If rate set have 11g rate than change the mode to 11G */
1003 *pSapHw_mode = eSAP_DOT11_MODE_11g;
1004 if (pIe[i] & BASIC_RATE_MASK)
1005 {
1006 /* If we have 11g rate as basic rate, it means mode
1007 is 11g only mode.
1008 */
1009 *pSapHw_mode = eSAP_DOT11_MODE_11g_ONLY;
1010 *pCheckRatesfor11g = FALSE;
1011 }
1012 }
1013 else if((BASIC_RATE_MASK | WLAN_BSS_MEMBERSHIP_SELECTOR_HT_PHY) == pIe[i])
1014 {
1015 *require_ht = TRUE;
1016 }
1017 }
1018 return;
1019}
1020
1021static void wlan_hdd_set_sapHwmode(hdd_adapter_t *pHostapdAdapter)
1022{
1023 tsap_Config_t *pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
1024 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
1025 struct ieee80211_mgmt *pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
1026 u8 checkRatesfor11g = TRUE;
1027 u8 require_ht = FALSE;
1028 u8 *pIe=NULL;
1029
1030 pConfig->SapHw_mode= eSAP_DOT11_MODE_11b;
1031
1032 pIe = wlan_hdd_cfg80211_get_ie_ptr(&pMgmt_frame->u.beacon.variable[0],
1033 pBeacon->head_len, WLAN_EID_SUPP_RATES);
1034 if (pIe != NULL)
1035 {
1036 pIe += 1;
1037 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
1038 &pConfig->SapHw_mode);
1039 }
1040
1041 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
1042 WLAN_EID_EXT_SUPP_RATES);
1043 if (pIe != NULL)
1044 {
1045
1046 pIe += 1;
1047 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
1048 &pConfig->SapHw_mode);
1049 }
1050
1051 if( pConfig->channel > 14 )
1052 {
1053 pConfig->SapHw_mode= eSAP_DOT11_MODE_11a;
1054 }
1055
1056 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
1057 WLAN_EID_HT_CAPABILITY);
1058
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301059 if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07001060 {
1061 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n;
1062 if(require_ht)
1063 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n_ONLY;
1064 }
1065}
1066
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05301067static int wlan_hdd_add_ie(hdd_adapter_t* pHostapdAdapter, v_U8_t *genie,
1068 v_U8_t *total_ielen, v_U8_t *oui, v_U8_t oui_size)
1069{
1070 v_U8_t ielen = 0;
1071 v_U8_t *pIe = NULL;
1072 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
1073
1074 pIe = wlan_hdd_get_vendor_oui_ie_ptr(oui, oui_size,
1075 pBeacon->tail, pBeacon->tail_len);
1076
1077 if (pIe)
1078 {
1079 ielen = pIe[1] + 2;
1080 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
1081 {
1082 vos_mem_copy(&genie[*total_ielen], pIe, ielen);
1083 }
1084 else
1085 {
1086 hddLog( VOS_TRACE_LEVEL_ERROR, "**Ie Length is too big***");
1087 return -EINVAL;
1088 }
1089 *total_ielen += ielen;
1090 }
1091 return 0;
1092}
1093
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001094#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07001095static int wlan_hdd_cfg80211_update_apies(hdd_adapter_t* pHostapdAdapter,
1096 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001097#else
1098static int wlan_hdd_cfg80211_update_apies(hdd_adapter_t* pHostapdAdapter,
1099 struct cfg80211_beacon_data *params)
1100#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07001101{
1102 v_U8_t *genie;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05301103 v_U8_t total_ielen = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07001104 v_U8_t addIE[1] = {0};
Jeff Johnsone7245742012-09-05 17:12:55 -07001105 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07001106
1107 genie = vos_mem_malloc(MAX_GENIE_LEN);
1108
1109 if(genie == NULL) {
1110
1111 return -ENOMEM;
1112 }
1113
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05301114 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
1115 &total_ielen, WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07001116 {
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05301117 ret = -EINVAL;
1118 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001119 }
1120
1121#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05301122 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
1123 &total_ielen, WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE))
1124 {
1125 ret = -EINVAL;
1126 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001127 }
1128#endif
1129
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05301130 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
1131 &total_ielen, P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07001132 {
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05301133 ret = -EINVAL;
1134 goto done;
1135 }
1136
1137 if (WLAN_HDD_SOFTAP == pHostapdAdapter->device_mode)
1138 {
1139 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
1140 &total_ielen, SS_OUI_TYPE, SS_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07001141 {
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05301142 ret = -EINVAL;
1143 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001144 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001145 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001146
1147 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1148 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, genie, total_ielen, NULL,
1149 eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
1150 {
1151 hddLog(LOGE,
1152 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001153 ret = -EINVAL;
1154 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001155 }
1156
1157 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1158 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
1159 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
1160 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
1161 ==eHAL_STATUS_FAILURE)
1162 {
1163 hddLog(LOGE,
1164 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001165 ret = -EINVAL;
1166 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001167 }
1168
1169 // Added for ProResp IE
1170 if ( (params->proberesp_ies != NULL) && (params->proberesp_ies_len != 0) )
1171 {
1172 u16 rem_probe_resp_ie_len = params->proberesp_ies_len;
1173 u8 probe_rsp_ie_len[3] = {0};
1174 u8 counter = 0;
1175 /* Check Probe Resp Length if it is greater then 255 then Store
1176 Probe Resp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1 &
1177 WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are not able
1178 Store More then 255 bytes into One Variable.
1179 */
1180 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
1181 {
1182 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
1183 {
1184 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
1185 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
1186 }
1187 else
1188 {
1189 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
1190 rem_probe_resp_ie_len = 0;
1191 }
1192 }
1193
1194 rem_probe_resp_ie_len = 0;
1195
1196 if (probe_rsp_ie_len[0] > 0)
1197 {
1198 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1199 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
1200 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
1201 probe_rsp_ie_len[0], NULL,
1202 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
1203 {
1204 hddLog(LOGE,
1205 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001206 ret = -EINVAL;
1207 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001208 }
1209 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
1210 }
1211
1212 if (probe_rsp_ie_len[1] > 0)
1213 {
1214 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1215 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
1216 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
1217 probe_rsp_ie_len[1], NULL,
1218 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
1219 {
1220 hddLog(LOGE,
1221 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001222 ret = -EINVAL;
1223 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001224 }
1225 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
1226 }
1227
1228 if (probe_rsp_ie_len[2] > 0)
1229 {
1230 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1231 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
1232 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
1233 probe_rsp_ie_len[2], NULL,
1234 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
1235 {
1236 hddLog(LOGE,
1237 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001238 ret = -EINVAL;
1239 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001240 }
1241 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
1242 }
1243
1244 if (probe_rsp_ie_len[1] == 0 )
1245 {
1246 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1247 WNI_CFG_PROBE_RSP_ADDNIE_DATA2, (tANI_U8*)addIE, 0, NULL,
1248 eANI_BOOLEAN_FALSE) )
1249 {
1250 hddLog(LOGE,
1251 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM\n");
1252 }
1253 }
1254
1255 if (probe_rsp_ie_len[2] == 0 )
1256 {
1257 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1258 WNI_CFG_PROBE_RSP_ADDNIE_DATA3, (tANI_U8*)addIE, 0, NULL,
1259 eANI_BOOLEAN_FALSE) )
1260 {
1261 hddLog(LOGE,
1262 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM\n");
1263 }
1264 }
1265
1266 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1267 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
1268 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
1269 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
1270 == eHAL_STATUS_FAILURE)
1271 {
1272 hddLog(LOGE,
1273 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001274 ret = -EINVAL;
1275 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001276 }
1277 }
1278 else
1279 {
1280 // Reset WNI_CFG_PROBE_RSP Flags
1281 wlan_hdd_reset_prob_rspies(pHostapdAdapter);
1282
1283 hddLog(VOS_TRACE_LEVEL_INFO,
1284 "%s: No Probe Response IE received in set beacon",
1285 __func__);
1286 }
1287
1288 // Added for AssocResp IE
1289 if ( (params->assocresp_ies != NULL) && (params->assocresp_ies_len != 0) )
1290 {
1291 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1292 WNI_CFG_ASSOC_RSP_ADDNIE_DATA, (tANI_U8*)params->assocresp_ies,
1293 params->assocresp_ies_len, NULL,
1294 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
1295 {
1296 hddLog(LOGE,
1297 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001298 ret = -EINVAL;
1299 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001300 }
1301
1302 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1303 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 1, NULL,
1304 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
1305 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
1306 == eHAL_STATUS_FAILURE)
1307 {
1308 hddLog(LOGE,
1309 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001310 ret = -EINVAL;
1311 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001312 }
1313 }
1314 else
1315 {
1316 hddLog(VOS_TRACE_LEVEL_INFO,
1317 "%s: No Assoc Response IE received in set beacon",
1318 __func__);
1319
1320 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1321 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
1322 eANI_BOOLEAN_FALSE) )
1323 {
1324 hddLog(LOGE,
1325 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM\n");
1326 }
1327 }
1328
Jeff Johnsone7245742012-09-05 17:12:55 -07001329done:
Jeff Johnson295189b2012-06-20 16:38:30 -07001330 vos_mem_free(genie);
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05301331 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07001332}
Jeff Johnson295189b2012-06-20 16:38:30 -07001333
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301334/*
Jeff Johnson295189b2012-06-20 16:38:30 -07001335 * FUNCTION: wlan_hdd_validate_operation_channel
1336 * called by wlan_hdd_cfg80211_start_bss() and
1337 * wlan_hdd_cfg80211_set_channel()
1338 * This function validates whether given channel is part of valid
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301339 * channel list.
1340 */
Jeff Johnson295189b2012-06-20 16:38:30 -07001341static VOS_STATUS wlan_hdd_validate_operation_channel(hdd_adapter_t *pAdapter,int channel)
1342{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301343
Jeff Johnson295189b2012-06-20 16:38:30 -07001344 v_U32_t num_ch = 0;
1345 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN];
1346 u32 indx = 0;
1347 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05301348 v_U8_t fValidChannel = FALSE, count = 0;
1349 hdd_config_t *hdd_pConfig_ini= (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301350
Jeff Johnson295189b2012-06-20 16:38:30 -07001351 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
1352
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05301353 if ( hdd_pConfig_ini->sapAllowAllChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -07001354 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05301355 /* Validate the channel */
1356 for (count = RF_CHAN_1 ; count <= RF_CHAN_165 ; count++)
Jeff Johnson295189b2012-06-20 16:38:30 -07001357 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05301358 if ( channel == rfChannels[count].channelNum )
1359 {
1360 fValidChannel = TRUE;
1361 break;
1362 }
1363 }
1364 if (fValidChannel != TRUE)
1365 {
1366 hddLog(VOS_TRACE_LEVEL_ERROR,
1367 "%s: Invalid Channel [%d]", __func__, channel);
1368 return VOS_STATUS_E_FAILURE;
Jeff Johnson295189b2012-06-20 16:38:30 -07001369 }
1370 }
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05301371 else
Jeff Johnson295189b2012-06-20 16:38:30 -07001372 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05301373 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
1374 valid_ch, &num_ch))
1375 {
1376 hddLog(VOS_TRACE_LEVEL_ERROR,
1377 "%s: failed to get valid channel list", __func__);
1378 return VOS_STATUS_E_FAILURE;
1379 }
1380 for (indx = 0; indx < num_ch; indx++)
1381 {
1382 if (channel == valid_ch[indx])
1383 {
1384 break;
1385 }
1386 }
1387
1388 if (indx >= num_ch)
1389 {
1390 hddLog(VOS_TRACE_LEVEL_ERROR,
1391 "%s: Invalid Channel [%d]", __func__, channel);
1392 return VOS_STATUS_E_FAILURE;
1393 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001394 }
1395 return VOS_STATUS_SUCCESS;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301396
Jeff Johnson295189b2012-06-20 16:38:30 -07001397}
1398
Viral Modi3a32cc52013-02-08 11:14:52 -08001399/**
1400 * FUNCTION: wlan_hdd_cfg80211_set_channel
1401 * This function is used to set the channel number
1402 */
1403static int wlan_hdd_cfg80211_set_channel( struct wiphy *wiphy, struct net_device *dev,
1404 struct ieee80211_channel *chan,
1405 enum nl80211_channel_type channel_type
1406 )
1407{
1408 v_U32_t num_ch = 0;
Jeff Johnson4416a782013-03-25 14:17:50 -07001409 int channel = 0;
Viral Modi3a32cc52013-02-08 11:14:52 -08001410 hdd_adapter_t *pAdapter = NULL;
1411 int freq = chan->center_freq; /* freq is in MHZ */
1412
1413 ENTER();
1414
1415 if( NULL == dev )
1416 {
1417 hddLog(VOS_TRACE_LEVEL_ERROR,
1418 "%s: Called with dev = NULL.\n", __func__);
1419 return -ENODEV;
1420 }
1421 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
1422
1423 hddLog(VOS_TRACE_LEVEL_INFO,
1424 "%s: device_mode = %d freq = %d \n",__func__,
1425 pAdapter->device_mode, chan->center_freq);
1426 if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress)
1427 {
1428 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:LOGP in Progress. Ignore!!!",__func__);
1429 return -EAGAIN;
1430 }
1431
1432 /*
1433 * Do freq to chan conversion
1434 * TODO: for 11a
1435 */
1436
1437 channel = ieee80211_frequency_to_channel(freq);
1438
1439 /* Check freq range */
1440 if ((WNI_CFG_CURRENT_CHANNEL_STAMIN > channel) ||
1441 (WNI_CFG_CURRENT_CHANNEL_STAMAX < channel))
1442 {
1443 hddLog(VOS_TRACE_LEVEL_ERROR,
1444 "%s: Channel [%d] is outside valid range from %d to %d\n",
1445 __func__, channel, WNI_CFG_CURRENT_CHANNEL_STAMIN,
1446 WNI_CFG_CURRENT_CHANNEL_STAMAX);
1447 return -EINVAL;
1448 }
1449
1450 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
1451
Gopichand Nakkala6ab19562013-03-07 13:59:42 +05301452 if ((WLAN_HDD_SOFTAP != pAdapter->device_mode) &&
1453 (WLAN_HDD_P2P_GO != pAdapter->device_mode))
Viral Modi3a32cc52013-02-08 11:14:52 -08001454 {
1455 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pAdapter,channel))
1456 {
1457 hddLog(VOS_TRACE_LEVEL_ERROR,
1458 "%s: Invalid Channel [%d] \n", __func__, channel);
1459 return -EINVAL;
1460 }
1461 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
1462 "%s: set channel to [%d] for device mode =%d",
1463 __func__, channel,pAdapter->device_mode);
1464 }
1465 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Viral Modi3a32cc52013-02-08 11:14:52 -08001466 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Viral Modi3a32cc52013-02-08 11:14:52 -08001467 )
1468 {
1469 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
1470 tCsrRoamProfile * pRoamProfile = &pWextState->roamProfile;
1471 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
1472
1473 if (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState)
1474 {
1475 /* Link is up then return cant set channel*/
1476 hddLog( VOS_TRACE_LEVEL_ERROR,
1477 "%s: IBSS Associated, can't set the channel\n", __func__);
1478 return -EINVAL;
1479 }
1480
1481 num_ch = pRoamProfile->ChannelInfo.numOfChannels = 1;
1482 pHddStaCtx->conn_info.operationChannel = channel;
1483 pRoamProfile->ChannelInfo.ChannelList =
1484 &pHddStaCtx->conn_info.operationChannel;
1485 }
1486 else if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Viral Modi3a32cc52013-02-08 11:14:52 -08001487 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Viral Modi3a32cc52013-02-08 11:14:52 -08001488 )
1489 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05301490 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
1491 {
1492 if(VOS_STATUS_SUCCESS !=
1493 wlan_hdd_validate_operation_channel(pAdapter,channel))
1494 {
1495 hddLog(VOS_TRACE_LEVEL_ERROR,
1496 "%s: Invalid Channel [%d] \n", __func__, channel);
1497 return -EINVAL;
1498 }
1499 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
1500 }
1501 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
Viral Modi3a32cc52013-02-08 11:14:52 -08001502 {
1503 hdd_config_t *cfg_param = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
1504
1505 /* If auto channel selection is configured as enable/ 1 then ignore
1506 channel set by supplicant
1507 */
1508 if ( cfg_param->apAutoChannelSelection )
1509 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05301510 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel =
1511 AUTO_CHANNEL_SELECT;
Viral Modi3a32cc52013-02-08 11:14:52 -08001512 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
1513 "%s: set channel to auto channel (0) for device mode =%d",
1514 __func__, pAdapter->device_mode);
1515 }
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05301516 else
1517 {
1518 if(VOS_STATUS_SUCCESS !=
1519 wlan_hdd_validate_operation_channel(pAdapter,channel))
1520 {
1521 hddLog(VOS_TRACE_LEVEL_ERROR,
1522 "%s: Invalid Channel [%d] \n", __func__, channel);
1523 return -EINVAL;
1524 }
1525 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
1526 }
Viral Modi3a32cc52013-02-08 11:14:52 -08001527 }
1528 }
1529 else
1530 {
1531 hddLog(VOS_TRACE_LEVEL_FATAL,
1532 "%s: Invalid device mode failed to set valid channel", __func__);
1533 return -EINVAL;
1534 }
1535 EXIT();
1536 return 0;
1537}
1538
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301539/*
Madan Mohan Koyyalamudi59381622012-11-28 01:56:47 +05301540 * FUNCTION: wlan_hdd_select_cbmode
1541 * called by wlan_hdd_cfg80211_start_bss() and
1542 * This function selects the cbmode based on primary channel
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301543 */
Madan Mohan Koyyalamudi527935a2012-12-04 16:41:16 -08001544VOS_STATUS wlan_sap_select_cbmode(void *pAdapter,eSapPhyMode SapHw_mode, v_U8_t channel)
Madan Mohan Koyyalamudi59381622012-11-28 01:56:47 +05301545{
1546 tSmeConfigParams smeConfig;
Madan Mohan Koyyalamudi527935a2012-12-04 16:41:16 -08001547 hdd_context_t *pHddCtx = ( hdd_context_t *) pAdapter;
1548 hdd_config_t *pConfigIni = ((hdd_context_t *)(pAdapter))->cfg_ini;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301549
Madan Mohan Koyyalamudi59381622012-11-28 01:56:47 +05301550 if(
1551#ifdef WLAN_FEATURE_11AC
Madan Mohan Koyyalamudi527935a2012-12-04 16:41:16 -08001552 SapHw_mode != eSAP_DOT11_MODE_11ac &&
1553 SapHw_mode != eSAP_DOT11_MODE_11ac_ONLY &&
Madan Mohan Koyyalamudi59381622012-11-28 01:56:47 +05301554#endif
Madan Mohan Koyyalamudi527935a2012-12-04 16:41:16 -08001555 SapHw_mode != eSAP_DOT11_MODE_11n &&
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301556 SapHw_mode != eSAP_DOT11_MODE_11n_ONLY
Madan Mohan Koyyalamudi59381622012-11-28 01:56:47 +05301557 )
1558 {
1559 return VOS_STATUS_SUCCESS;
1560 }
1561
1562 if (!pConfigIni->nChannelBondingMode5GHz) {
1563 return VOS_STATUS_SUCCESS;
1564 }
1565
Madan Mohan Koyyalamudi527935a2012-12-04 16:41:16 -08001566 //channel = pSapConfig->channel;
Madan Mohan Koyyalamudi59381622012-11-28 01:56:47 +05301567 vos_mem_zero(&smeConfig, sizeof (tSmeConfigParams));
1568
1569 sme_GetConfigParam(pHddCtx->hHal, &smeConfig);
1570
1571#ifdef WLAN_FEATURE_11AC
1572
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301573 if ( SapHw_mode == eSAP_DOT11_MODE_11ac ||
Madan Mohan Koyyalamudi527935a2012-12-04 16:41:16 -08001574 SapHw_mode == eSAP_DOT11_MODE_11ac_ONLY )
Madan Mohan Koyyalamudi59381622012-11-28 01:56:47 +05301575 {
1576 if ( channel== 36 || channel == 52 || channel == 100 ||
1577 channel == 116 || channel == 149 )
1578 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301579 smeConfig.csrConfig.channelBondingMode5GHz =
Madan Mohan Koyyalamudi59381622012-11-28 01:56:47 +05301580 PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_LOW - 1;
1581 }
1582 else if ( channel == 40 || channel == 56 || channel == 104 ||
1583 channel == 120 || channel == 153 )
1584 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301585 smeConfig.csrConfig.channelBondingMode5GHz =
Madan Mohan Koyyalamudi59381622012-11-28 01:56:47 +05301586 PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_LOW - 1;
1587 }
1588 else if ( channel == 44 || channel == 60 || channel == 108 ||
1589 channel == 124 || channel == 157 )
1590 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301591 smeConfig.csrConfig.channelBondingMode5GHz =
Madan Mohan Koyyalamudi59381622012-11-28 01:56:47 +05301592 PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_HIGH -1;
1593 }
1594 else if ( channel == 48 || channel == 64 || channel == 112 ||
1595 channel == 128 || channel == 161 )
1596 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301597 smeConfig.csrConfig.channelBondingMode5GHz =
Madan Mohan Koyyalamudi59381622012-11-28 01:56:47 +05301598 PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_HIGH - 1;
1599 }
Shailender Karmuchi84f11f02013-02-12 17:11:45 -08001600 else if ( channel == 165 )
1601 {
1602 smeConfig.csrConfig.channelBondingMode5GHz = 0;
1603 }
Madan Mohan Koyyalamudi59381622012-11-28 01:56:47 +05301604 }
1605#endif
Madan Mohan Koyyalamudi527935a2012-12-04 16:41:16 -08001606 if ( SapHw_mode == eSAP_DOT11_MODE_11n ||
1607 SapHw_mode == eSAP_DOT11_MODE_11n_ONLY )
Madan Mohan Koyyalamudi59381622012-11-28 01:56:47 +05301608 {
1609 if ( channel== 40 || channel == 48 || channel == 56 ||
1610 channel == 64 || channel == 104 || channel == 112 ||
1611 channel == 120 || channel == 128 || channel == 136 ||
1612 channel == 144 || channel == 153 || channel == 161 )
1613 {
1614 smeConfig.csrConfig.channelBondingMode5GHz = 1;
1615 }
1616 else if ( channel== 36 || channel == 44 || channel == 52 ||
1617 channel == 60 || channel == 100 || channel == 108 ||
1618 channel == 116 || channel == 124 || channel == 132 ||
1619 channel == 140 || channel == 149 || channel == 157 )
1620 {
1621 smeConfig.csrConfig.channelBondingMode5GHz = 2;
1622 }
Shailender Karmuchi84f11f02013-02-12 17:11:45 -08001623 else if ( channel == 165 )
1624 {
1625 smeConfig.csrConfig.channelBondingMode5GHz = 0;
1626 }
Madan Mohan Koyyalamudi59381622012-11-28 01:56:47 +05301627 }
1628 pr_info ("cbmode selected=%ld\n",smeConfig.csrConfig.channelBondingMode5GHz);
1629
1630 sme_UpdateConfig (pHddCtx->hHal,&smeConfig);
1631 return VOS_STATUS_SUCCESS;
1632}
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001633
Jeff Johnson295189b2012-06-20 16:38:30 -07001634#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
1635static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
1636 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001637#else
1638static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
1639 struct cfg80211_beacon_data *params,
1640 const u8 *ssid, size_t ssid_len,
1641 enum nl80211_hidden_ssid hidden_ssid)
1642#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07001643{
1644 tsap_Config_t *pConfig;
1645 beacon_data_t *pBeacon = NULL;
1646 struct ieee80211_mgmt *pMgmt_frame;
1647 v_U8_t *pIe=NULL;
1648 v_U16_t capab_info;
1649 eCsrAuthType RSNAuthType;
1650 eCsrEncryptionType RSNEncryptType;
1651 eCsrEncryptionType mcRSNEncryptType;
1652 int status = VOS_STATUS_SUCCESS;
1653 tpWLAN_SAPEventCB pSapEventCallback;
1654 hdd_hostapd_state_t *pHostapdState;
1655 v_U8_t wpaRsnIEdata[(SIR_MAC_MAX_IE_LENGTH * 2)+4]; //Max ie length 255 * 2(WPA+RSN) + 2 bytes (vendor specific ID) * 2
1656 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05301657 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07001658 struct qc_mac_acl_entry *acl_entry = NULL;
1659 v_SINT_t i;
Madan Mohan Koyyalamudi543172b2012-12-05 16:40:18 -08001660 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07001661
1662 ENTER();
1663
1664 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter);
1665
1666 pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
1667
1668 pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
1669
1670 pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
1671
1672 pConfig->beacon_int = pMgmt_frame->u.beacon.beacon_int;
1673
1674 //channel is already set in the set_channel Call back
1675 //pConfig->channel = pCommitConfig->channel;
1676
1677 /*Protection parameter to enable or disable*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301678 pConfig->protEnabled =
Jeff Johnson295189b2012-06-20 16:38:30 -07001679 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtEnabled;
1680
1681 pConfig->dtim_period = pBeacon->dtim_period;
1682
1683 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"****pConfig->dtim_period=%d***\n",
1684 pConfig->dtim_period);
1685
1686
Madan Mohan Koyyalamudie0ca11f2012-11-27 15:57:52 -08001687 if (pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson32d95a32012-09-10 13:15:23 -07001688 {
1689 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -07001690 WLAN_EID_COUNTRY);
Jeff Johnson32d95a32012-09-10 13:15:23 -07001691 if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07001692 {
Jeff Johnson32d95a32012-09-10 13:15:23 -07001693 tANI_BOOLEAN restartNeeded;
Jeff Johnson32d95a32012-09-10 13:15:23 -07001694 pConfig->ieee80211d = 1;
1695 vos_mem_copy(pConfig->countryCode, &pIe[2], 3);
1696 sme_setRegInfo(hHal, pConfig->countryCode);
1697 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
Jeff Johnson295189b2012-06-20 16:38:30 -07001698 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07001699 else
1700 {
1701 pConfig->ieee80211d = 0;
1702 }
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05301703 /*
1704 * If auto channel is configured i.e. channel is 0,
1705 * so skip channel validation.
1706 */
1707 if( AUTO_CHANNEL_SELECT != pConfig->channel )
1708 {
1709 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pHostapdAdapter,pConfig->channel))
1710 {
1711 hddLog(VOS_TRACE_LEVEL_ERROR,
1712 "%s: Invalid Channel [%d] \n", __func__, pConfig->channel);
1713 return -EINVAL;
1714 }
1715 }
1716 else
1717 {
1718 if(1 != pHddCtx->is_dynamic_channel_range_set)
1719 {
1720 hdd_config_t *hdd_pConfig= (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini;
1721 WLANSAP_SetChannelRange(hHal, hdd_pConfig->apStartChannelNum,
1722 hdd_pConfig->apEndChannelNum,hdd_pConfig->apOperatingBand);
1723 }
1724 pHddCtx->is_dynamic_channel_range_set = 0;
1725 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001726 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07001727 else
Jeff Johnson295189b2012-06-20 16:38:30 -07001728 {
1729 pConfig->ieee80211d = 0;
1730 }
1731 pConfig->authType = eSAP_AUTO_SWITCH;
1732
1733 capab_info = pMgmt_frame->u.beacon.capab_info;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301734
1735 pConfig->privacy = (pMgmt_frame->u.beacon.capab_info &
Jeff Johnson295189b2012-06-20 16:38:30 -07001736 WLAN_CAPABILITY_PRIVACY) ? VOS_TRUE : VOS_FALSE;
1737
1738 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uPrivacy = pConfig->privacy;
1739
1740 /*Set wps station to configured*/
1741 pIe = wlan_hdd_get_wps_ie_ptr(pBeacon->tail, pBeacon->tail_len);
1742
1743 if(pIe)
1744 {
1745 if(pIe[1] < (2 + WPS_OUI_TYPE_SIZE))
1746 {
1747 hddLog( VOS_TRACE_LEVEL_ERROR, "**Wps Ie Length is too small***\n");
1748 return -EINVAL;
1749 }
1750 else if(memcmp(&pIe[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) == 0)
1751 {
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07001752 hddLog( VOS_TRACE_LEVEL_INFO, "** WPS IE(len %d) ***", (pIe[1]+2));
Jeff Johnson295189b2012-06-20 16:38:30 -07001753 /* Check 15 bit of WPS IE as it contain information for wps state
1754 * WPS state
1755 */
1756 if(SAP_WPS_ENABLED_UNCONFIGURED == pIe[15])
1757 {
1758 pConfig->wps_state = SAP_WPS_ENABLED_UNCONFIGURED;
1759 } else if(SAP_WPS_ENABLED_CONFIGURED == pIe[15])
1760 {
1761 pConfig->wps_state = SAP_WPS_ENABLED_CONFIGURED;
1762 }
1763 }
1764 }
1765 else
1766 {
1767 pConfig->wps_state = SAP_WPS_DISABLED;
1768 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301769 pConfig->fwdWPSPBCProbeReq = 1; // Forward WPS PBC probe request frame up
Jeff Johnson295189b2012-06-20 16:38:30 -07001770
1771 pConfig->RSNWPAReqIELength = 0;
1772 pConfig->pRSNWPAReqIE = NULL;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301773 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -07001774 WLAN_EID_RSN);
1775 if(pIe && pIe[1])
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301776 {
Jeff Johnson295189b2012-06-20 16:38:30 -07001777 pConfig->RSNWPAReqIELength = pIe[1] + 2;
1778 memcpy(&wpaRsnIEdata[0], pIe, pConfig->RSNWPAReqIELength);
1779 pConfig->pRSNWPAReqIE = &wpaRsnIEdata[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301780 /* The actual processing may eventually be more extensive than
1781 * this. Right now, just consume any PMKIDs that are sent in
Jeff Johnson295189b2012-06-20 16:38:30 -07001782 * by the app.
1783 * */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301784 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -07001785 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
1786 &RSNEncryptType,
1787 &mcRSNEncryptType,
1788 &RSNAuthType,
1789 pConfig->pRSNWPAReqIE[1]+2,
1790 pConfig->pRSNWPAReqIE );
1791
1792 if( VOS_STATUS_SUCCESS == status )
1793 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301794 /* Now copy over all the security attributes you have
1795 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -07001796 * */
1797 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
1798 pConfig->mcRSNEncryptType = mcRSNEncryptType;
1799 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
1800 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05301801 hddLog( LOG1, FL("CSR AuthType = %d, "
Jeff Johnson295189b2012-06-20 16:38:30 -07001802 "EncryptionType = %d mcEncryptionType = %d\n"),
1803 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
1804 }
1805 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301806
Jeff Johnson295189b2012-06-20 16:38:30 -07001807 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE,
1808 pBeacon->tail, pBeacon->tail_len);
1809
1810 if(pIe && pIe[1] && (pIe[0] == DOT11F_EID_WPA))
1811 {
1812 if (pConfig->pRSNWPAReqIE)
1813 {
1814 /*Mixed mode WPA/WPA2*/
1815 memcpy((&wpaRsnIEdata[0] + pConfig->RSNWPAReqIELength), pIe, pIe[1] + 2);
1816 pConfig->RSNWPAReqIELength += pIe[1] + 2;
1817 }
1818 else
1819 {
1820 pConfig->RSNWPAReqIELength = pIe[1] + 2;
1821 memcpy(&wpaRsnIEdata[0], pIe, pConfig->RSNWPAReqIELength);
1822 pConfig->pRSNWPAReqIE = &wpaRsnIEdata[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301823 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -07001824 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
1825 &RSNEncryptType,
1826 &mcRSNEncryptType,
1827 &RSNAuthType,
1828 pConfig->pRSNWPAReqIE[1]+2,
1829 pConfig->pRSNWPAReqIE );
1830
1831 if( VOS_STATUS_SUCCESS == status )
1832 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301833 /* Now copy over all the security attributes you have
1834 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -07001835 * */
1836 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
1837 pConfig->mcRSNEncryptType = mcRSNEncryptType;
1838 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
1839 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05301840 hddLog( LOG1, FL("CSR AuthType = %d, "
Jeff Johnson295189b2012-06-20 16:38:30 -07001841 "EncryptionType = %d mcEncryptionType = %d\n"),
1842 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
1843 }
1844 }
1845 }
1846
Jeff Johnson4416a782013-03-25 14:17:50 -07001847 if (pConfig->RSNWPAReqIELength > sizeof wpaRsnIEdata) {
1848 hddLog( VOS_TRACE_LEVEL_ERROR, "**RSNWPAReqIELength is too large***");
1849 return -EINVAL;
1850 }
1851
Jeff Johnson295189b2012-06-20 16:38:30 -07001852 pConfig->SSIDinfo.ssidHidden = VOS_FALSE;
1853
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001854#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07001855 if (params->ssid != NULL)
1856 {
1857 memcpy(pConfig->SSIDinfo.ssid.ssId, params->ssid, params->ssid_len);
1858 pConfig->SSIDinfo.ssid.length = params->ssid_len;
1859 if (params->hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
1860 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
1861 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001862#else
1863 if (ssid != NULL)
1864 {
1865 memcpy(pConfig->SSIDinfo.ssid.ssId, ssid, ssid_len);
1866 pConfig->SSIDinfo.ssid.length = ssid_len;
1867 if (hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
1868 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
1869 }
1870#endif
1871
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301872 vos_mem_copy(pConfig->self_macaddr.bytes,
Jeff Johnson295189b2012-06-20 16:38:30 -07001873 pHostapdAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301874
Jeff Johnson295189b2012-06-20 16:38:30 -07001875 /* default value */
1876 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
1877 pConfig->num_accept_mac = 0;
1878 pConfig->num_deny_mac = 0;
1879
1880 pIe = wlan_hdd_get_vendor_oui_ie_ptr(BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
1881 pBeacon->tail, pBeacon->tail_len);
1882
1883 /* pIe for black list is following form:
1884 type : 1 byte
1885 length : 1 byte
1886 OUI : 4 bytes
1887 acl type : 1 byte
1888 no of mac addr in black list: 1 byte
1889 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301890 */
1891 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07001892 {
1893 pConfig->SapMacaddr_acl = pIe[6];
1894 pConfig->num_deny_mac = pIe[7];
1895 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no deny mac = %d\n",
1896 pIe[6], pIe[7]);
1897 if (pConfig->num_deny_mac > MAX_MAC_ADDRESS_DENIED)
1898 pConfig->num_deny_mac = MAX_MAC_ADDRESS_DENIED;
1899 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
1900 for (i = 0; i < pConfig->num_deny_mac; i++)
1901 {
1902 vos_mem_copy(&pConfig->deny_mac[i], acl_entry->addr, sizeof(qcmacaddr));
1903 acl_entry++;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301904 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001905 }
1906 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
1907 pBeacon->tail, pBeacon->tail_len);
1908
1909 /* pIe for white list is following form:
1910 type : 1 byte
1911 length : 1 byte
1912 OUI : 4 bytes
1913 acl type : 1 byte
1914 no of mac addr in white list: 1 byte
1915 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301916 */
1917 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07001918 {
1919 pConfig->SapMacaddr_acl = pIe[6];
1920 pConfig->num_accept_mac = pIe[7];
1921 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no accept mac = %d\n",
1922 pIe[6], pIe[7]);
1923 if (pConfig->num_accept_mac > MAX_MAC_ADDRESS_ACCEPTED)
1924 pConfig->num_accept_mac = MAX_MAC_ADDRESS_ACCEPTED;
1925 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
1926 for (i = 0; i < pConfig->num_accept_mac; i++)
1927 {
1928 vos_mem_copy(&pConfig->accept_mac[i], acl_entry->addr, sizeof(qcmacaddr));
1929 acl_entry++;
1930 }
1931 }
1932 wlan_hdd_set_sapHwmode(pHostapdAdapter);
1933
Jeff Johnsone7245742012-09-05 17:12:55 -07001934#ifdef WLAN_FEATURE_11AC
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -08001935 /* Overwrite the hostapd setting for HW mode only for 11ac.
1936 * This is valid only if mode is set to 11n in hostapd and either AUTO or 11ac in .ini .
1937 * Otherwise, leave whatever is set in hostapd (a OR b OR g OR n mode) */
1938 if( ((pConfig->SapHw_mode == eSAP_DOT11_MODE_11n) ||
1939 (pConfig->SapHw_mode == eSAP_DOT11_MODE_11n_ONLY)) &&
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301940 (((WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->dot11Mode == eHDD_DOT11_MODE_AUTO) ||
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -08001941 ((WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->dot11Mode == eHDD_DOT11_MODE_11ac) ||
1942 ((WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->dot11Mode == eHDD_DOT11_MODE_11ac_ONLY)) )
Jeff Johnsone7245742012-09-05 17:12:55 -07001943 {
1944 pConfig->SapHw_mode = eSAP_DOT11_MODE_11ac;
1945 }
1946#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301947
Madan Mohan Koyyalamudi527935a2012-12-04 16:41:16 -08001948 if( AUTO_CHANNEL_SELECT != pConfig->channel)
1949 wlan_sap_select_cbmode((WLAN_HDD_GET_CTX(pHostapdAdapter)),pConfig->SapHw_mode,pConfig->channel);
Jeff Johnson295189b2012-06-20 16:38:30 -07001950 // ht_capab is not what the name conveys,this is used for protection bitmap
1951 pConfig->ht_capab =
1952 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtection;
1953
1954 if ( 0 != wlan_hdd_cfg80211_update_apies(pHostapdAdapter, params) )
1955 {
1956 hddLog(LOGE, FL("SAP Not able to set AP IEs"));
1957 return -EINVAL;
1958 }
1959
1960 //Uapsd Enabled Bit
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301961 pConfig->UapsdEnable =
Jeff Johnson295189b2012-06-20 16:38:30 -07001962 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apUapsdEnabled;
1963 //Enable OBSS protection
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301964 pConfig->obssProtEnabled =
1965 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apOBSSProtEnabled;
Jeff Johnson295189b2012-06-20 16:38:30 -07001966
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301967 hddLog(LOGW, FL("SOftAP macaddress : "MAC_ADDRESS_STR"\n"),
Jeff Johnson295189b2012-06-20 16:38:30 -07001968 MAC_ADDR_ARRAY(pHostapdAdapter->macAddressCurrent.bytes));
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301969 hddLog(LOGW,FL("ssid =%s\n"), pConfig->SSIDinfo.ssid.ssId);
Jeff Johnson295189b2012-06-20 16:38:30 -07001970 hddLog(LOGW,FL("beaconint=%d, channel=%d\n"), (int)pConfig->beacon_int,
1971 (int)pConfig->channel);
1972 hddLog(LOGW,FL("hw_mode=%x\n"), pConfig->SapHw_mode);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301973 hddLog(LOGW,FL("privacy=%d, authType=%d\n"), pConfig->privacy,
1974 pConfig->authType);
Jeff Johnson295189b2012-06-20 16:38:30 -07001975 hddLog(LOGW,FL("RSN/WPALen=%d, \n"),(int)pConfig->RSNWPAReqIELength);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301976 hddLog(LOGW,FL("Uapsd = %d\n"),pConfig->UapsdEnable);
Jeff Johnson295189b2012-06-20 16:38:30 -07001977 hddLog(LOGW,FL("ProtEnabled = %d, OBSSProtEnabled = %d\n"),
1978 pConfig->protEnabled, pConfig->obssProtEnabled);
1979
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301980 if(test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -07001981 {
1982 //Bss already started. just return.
1983 //TODO Probably it should update some beacon params.
1984 hddLog( LOGE, "Bss Already started...Ignore the request");
1985 EXIT();
1986 return 0;
1987 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301988
Jeff Johnson295189b2012-06-20 16:38:30 -07001989 pConfig->persona = pHostapdAdapter->device_mode;
1990
1991 pSapEventCallback = hdd_hostapd_SAPEventCB;
1992 if(WLANSAP_StartBss(pVosContext, pSapEventCallback, pConfig,
1993 (v_PVOID_t)pHostapdAdapter->dev) != VOS_STATUS_SUCCESS)
1994 {
1995 hddLog(LOGE,FL("SAP Start Bss fail\n"));
1996 return -EINVAL;
1997 }
1998
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301999 hddLog(LOG1,
Jeff Johnson295189b2012-06-20 16:38:30 -07002000 FL("Waiting for Scan to complete(auto mode) and BSS to start"));
2001
2002 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302003
Jeff Johnson295189b2012-06-20 16:38:30 -07002004 if (!VOS_IS_STATUS_SUCCESS(status))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302005 {
2006 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07002007 ("ERROR: HDD vos wait for single_event failed!!\n"));
2008 VOS_ASSERT(0);
2009 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302010
Jeff Johnson295189b2012-06-20 16:38:30 -07002011 //Succesfully started Bss update the state bit.
2012 set_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags);
2013
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07002014#ifdef WLAN_FEATURE_P2P_DEBUG
2015 if (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO)
2016 {
2017 if(globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED)
2018 {
2019 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
2020 hddLog(LOGE,"[P2P State] From Go nego completed to "
Jeff Johnson1250df42012-12-10 14:31:52 -08002021 "Non-autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07002022 }
2023 else if(globalP2PConnectionStatus == P2P_NOT_ACTIVE)
2024 {
2025 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
2026 hddLog(LOGE,"[P2P State] From Inactive to "
Jeff Johnson1250df42012-12-10 14:31:52 -08002027 "Autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07002028 }
2029 }
2030#endif
2031
Jeff Johnson295189b2012-06-20 16:38:30 -07002032 pHostapdState->bCommit = TRUE;
2033 EXIT();
2034
2035 return 0;
2036}
2037
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002038#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302039static int wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy,
2040 struct net_device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -07002041 struct beacon_parameters *params)
2042{
2043 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302044 int status=VOS_STATUS_SUCCESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07002045
2046 ENTER();
2047
2048 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "device mode=%d\n",pAdapter->device_mode);
2049
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002050 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
2051 {
2052 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2053 "%s:LOGP in Progress. Ignore!!!", __func__);
2054 return -EAGAIN;
2055 }
2056
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302057 if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07002058 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07002059 )
2060 {
2061 beacon_data_t *old,*new;
2062
2063 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302064
Jeff Johnson295189b2012-06-20 16:38:30 -07002065 if (old)
2066 return -EALREADY;
2067
2068 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
2069
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302070 if(status != VOS_STATUS_SUCCESS)
Jeff Johnson295189b2012-06-20 16:38:30 -07002071 {
2072 hddLog(VOS_TRACE_LEVEL_FATAL,
2073 "%s:Error!!! Allocating the new beacon\n",__func__);
2074 return -EINVAL;
2075 }
2076
2077 pAdapter->sessionCtx.ap.beacon = new;
2078
2079 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
2080 }
2081
2082 EXIT();
2083 return status;
2084}
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302085
2086static int wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07002087 struct net_device *dev,
2088 struct beacon_parameters *params)
2089{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302090 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnson295189b2012-06-20 16:38:30 -07002091 int status=VOS_STATUS_SUCCESS;
2092
2093 ENTER();
2094
2095 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",
2096 __func__,pAdapter->device_mode);
2097
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002098 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
2099 {
2100 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2101 "%s:LOGP in Progress. Ignore!!!", __func__);
2102 return -EAGAIN;
2103 }
2104
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302105 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07002106 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302107 )
Jeff Johnson295189b2012-06-20 16:38:30 -07002108 {
2109 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302110
Jeff Johnson295189b2012-06-20 16:38:30 -07002111 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302112
Jeff Johnson295189b2012-06-20 16:38:30 -07002113 if (!old)
2114 return -ENOENT;
2115
2116 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
2117
2118 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302119 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson295189b2012-06-20 16:38:30 -07002120 "%s: Error!!! Allocating the new beacon\n",__func__);
2121 return -EINVAL;
2122 }
2123
2124 pAdapter->sessionCtx.ap.beacon = new;
2125
2126 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
2127 }
2128
2129 EXIT();
2130 return status;
2131}
2132
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002133#endif //(LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
2134
2135#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07002136static int wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy,
2137 struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002138#else
2139static int wlan_hdd_cfg80211_stop_ap (struct wiphy *wiphy,
2140 struct net_device *dev)
2141#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07002142{
2143 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnsone7245742012-09-05 17:12:55 -07002144 hdd_context_t *pHddCtx = NULL;
2145 hdd_scaninfo_t *pScanInfo = NULL;
2146 hdd_adapter_t *staAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07002147 VOS_STATUS status = 0;
2148
2149 ENTER();
2150
2151 if (NULL == pAdapter)
2152 {
2153 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002154 "%s: HDD adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002155 return -ENODEV;
2156 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07002157
Jeff Johnson4416a782013-03-25 14:17:50 -07002158 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07002159 if (NULL == pHddCtx)
2160 {
2161 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002162 "%s: HDD context is Null", __func__);
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07002163 return -ENODEV;
2164 }
Jeff Johnson4416a782013-03-25 14:17:50 -07002165 if (pHddCtx->isLogpInProgress)
2166 {
2167 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2168 "%s:LOGP in Progress. Ignore!!!", __func__);
2169 return -EAGAIN;
2170 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07002171
2172 staAdapter = hdd_get_adapter(pAdapter->pHddCtx, WLAN_HDD_INFRA_STATION);
2173 if (NULL == staAdapter)
2174 {
2175 staAdapter = hdd_get_adapter(pAdapter->pHddCtx, WLAN_HDD_P2P_CLIENT);
2176 if (NULL == staAdapter)
2177 {
2178 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002179 "%s: HDD adapter context is Null", __func__);
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07002180 return -ENODEV;
2181 }
2182 }
2183
2184 pScanInfo = &pHddCtx->scan_info;
2185
Jeff Johnson4416a782013-03-25 14:17:50 -07002186 if (pHddCtx->isLogpInProgress)
Jeff Johnson295189b2012-06-20 16:38:30 -07002187 {
2188 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:LOGP in Progress. Ignore!!!",__func__);
2189 return -EAGAIN;
2190 }
2191
2192 pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
2193
2194 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",
2195 __func__,pAdapter->device_mode);
2196
Jeff Johnsone7245742012-09-05 17:12:55 -07002197 if ((pScanInfo != NULL) && pScanInfo->mScanPending)
2198 {
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -08002199 INIT_COMPLETION(pScanInfo->abortscan_event_var);
Jeff Johnsone7245742012-09-05 17:12:55 -07002200 hdd_abort_mac_scan(staAdapter->pHddCtx);
2201 status = wait_for_completion_interruptible_timeout(
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -08002202 &pScanInfo->abortscan_event_var,
Jeff Johnsone7245742012-09-05 17:12:55 -07002203 msecs_to_jiffies(WLAN_WAIT_TIME_ABORTSCAN));
2204 if (!status)
2205 {
2206 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Jeff Johnson902c9832012-12-10 14:28:09 -08002207 "%s: Timeout occurred while waiting for abortscan" ,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002208 __func__);
Jeff Johnsone7245742012-09-05 17:12:55 -07002209 VOS_ASSERT(pScanInfo->mScanPending);
2210 return 0;
2211 }
2212 }
2213
Jeff Johnson295189b2012-06-20 16:38:30 -07002214 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07002215 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07002216 )
2217 {
2218 beacon_data_t *old;
2219
2220 old = pAdapter->sessionCtx.ap.beacon;
2221
2222 if (!old)
2223 return -ENOENT;
2224
Jeff Johnson295189b2012-06-20 16:38:30 -07002225 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07002226
2227 mutex_lock(&pHddCtx->sap_lock);
2228 if(test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
2229 {
Jeff Johnson4416a782013-03-25 14:17:50 -07002230 if ( VOS_STATUS_SUCCESS == (status = WLANSAP_StopBss(pHddCtx->pvosContext) ) )
Jeff Johnson295189b2012-06-20 16:38:30 -07002231 {
2232 hdd_hostapd_state_t *pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
2233
2234 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
2235
2236 if (!VOS_IS_STATUS_SUCCESS(status))
2237 {
2238 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2239 ("ERROR: HDD vos wait for single_event failed!!\n"));
2240 VOS_ASSERT(0);
2241 }
2242 }
2243 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
2244 }
2245 mutex_unlock(&pHddCtx->sap_lock);
2246
2247 if(status != VOS_STATUS_SUCCESS)
2248 {
2249 hddLog(VOS_TRACE_LEVEL_FATAL,
2250 "%s:Error!!! Stopping the BSS\n",__func__);
2251 return -EINVAL;
2252 }
2253
Jeff Johnson4416a782013-03-25 14:17:50 -07002254 if (ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -07002255 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 0,NULL, eANI_BOOLEAN_FALSE)
2256 ==eHAL_STATUS_FAILURE)
2257 {
2258 hddLog(LOGE,
2259 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM\n");
2260 }
2261
Jeff Johnson4416a782013-03-25 14:17:50 -07002262 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -07002263 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
2264 eANI_BOOLEAN_FALSE) )
2265 {
2266 hddLog(LOGE,
2267 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM\n");
2268 }
2269
2270 // Reset WNI_CFG_PROBE_RSP Flags
2271 wlan_hdd_reset_prob_rspies(pAdapter);
2272
2273 pAdapter->sessionCtx.ap.beacon = NULL;
2274 kfree(old);
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07002275#ifdef WLAN_FEATURE_P2P_DEBUG
2276 if((pAdapter->device_mode == WLAN_HDD_P2P_GO) &&
2277 (globalP2PConnectionStatus == P2P_GO_COMPLETED_STATE))
2278 {
2279 hddLog(LOGE,"[P2P State] From GO completed to Inactive state "
2280 "GO got removed");
2281 globalP2PConnectionStatus = P2P_NOT_ACTIVE;
2282 }
2283#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07002284 }
2285 EXIT();
2286 return status;
2287}
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002288
2289#if (LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
2290
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302291static int wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
2292 struct net_device *dev,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002293 struct cfg80211_ap_settings *params)
2294{
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302295 hdd_adapter_t *pAdapter;
2296 hdd_context_t *pHddCtx;
2297 int status = 0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002298
2299 ENTER();
2300
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302301 if (NULL == dev)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07002302 {
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302303 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
2304 "%s: Device is Null", __func__);
2305 return -ENODEV;
2306 }
2307
2308 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2309 if (NULL == pAdapter)
2310 {
2311 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
2312 "%s: HDD adapter is Null", __func__);
2313 return -ENODEV;
2314 }
2315
2316 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
2317 {
2318 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
2319 "%s: HDD adapter magic is invalid", __func__);
2320 return -ENODEV;
2321 }
2322
2323 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2324 if (NULL == pHddCtx)
2325 {
2326 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
2327 "%s: HDD context is Null", __func__);
2328 return -ENODEV;
2329 }
2330
2331 if (pHddCtx->isLogpInProgress)
2332 {
2333 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
2334 "%s: LOGP in Progress. Ignore!!!", __func__);
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07002335 return -EAGAIN;
2336 }
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302337
2338 if (pHddCtx->isLoadUnloadInProgress)
2339 {
2340 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
2341 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
2342 return -EAGAIN;
2343 }
2344
2345 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device mode = %d",
2346 __func__, pAdapter->device_mode);
2347
2348 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002349 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002350 )
2351 {
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302352 beacon_data_t *old, *new;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002353
2354 old = pAdapter->sessionCtx.ap.beacon;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302355
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002356 if (old)
2357 return -EALREADY;
2358
2359 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter, &new, &params->beacon, params->dtim_period);
2360
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302361 if (status != 0)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002362 {
2363 hddLog(VOS_TRACE_LEVEL_FATAL,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302364 "%s:Error!!! Allocating the new beacon", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002365 return -EINVAL;
2366 }
2367 pAdapter->sessionCtx.ap.beacon = new;
Viral Modi3a32cc52013-02-08 11:14:52 -08002368#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
2369 wlan_hdd_cfg80211_set_channel(wiphy, dev, params->channel, params->channel_type);
2370#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002371 status = wlan_hdd_cfg80211_start_bss(pAdapter, &params->beacon, params->ssid,
2372 params->ssid_len, params->hidden_ssid);
2373 }
2374
2375 EXIT();
2376 return status;
2377}
2378
2379
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302380static int wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002381 struct net_device *dev,
2382 struct cfg80211_beacon_data *params)
2383{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302384 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002385 int status=VOS_STATUS_SUCCESS;
2386
2387 ENTER();
2388
2389 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",
2390 __func__, pAdapter->device_mode);
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07002391 if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress)
2392 {
2393 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:LOGP in Progress. Ignore!!!",__func__);
2394 return -EAGAIN;
2395 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002396
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302397 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002398 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302399 )
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002400 {
2401 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302402
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002403 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302404
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002405 if (!old)
2406 return -ENOENT;
2407
2408 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter, &new, params, 0);
2409
2410 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302411 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002412 "%s: Error!!! Allocating the new beacon\n",__func__);
2413 return -EINVAL;
2414 }
2415
2416 pAdapter->sessionCtx.ap.beacon = new;
2417
2418 status = wlan_hdd_cfg80211_start_bss(pAdapter, params, NULL, 0, 0);
2419 }
2420
2421 EXIT();
2422 return status;
2423}
2424
2425#endif //(LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
2426
Jeff Johnson295189b2012-06-20 16:38:30 -07002427
2428static int wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
2429 struct net_device *dev,
2430 struct bss_parameters *params)
2431{
2432 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2433
2434 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302435
Jeff Johnson295189b2012-06-20 16:38:30 -07002436 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",
2437 __func__,pAdapter->device_mode);
2438
2439 if((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07002440 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302441 )
Jeff Johnson295189b2012-06-20 16:38:30 -07002442 {
2443 /* ap_isolate == -1 means that in change bss, upper layer doesn't
2444 * want to update this parameter */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302445 if (-1 != params->ap_isolate)
Jeff Johnson295189b2012-06-20 16:38:30 -07002446 {
2447 pAdapter->sessionCtx.ap.apDisableIntraBssFwd = !!params->ap_isolate;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302448 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002449 }
2450
2451 EXIT();
2452 return 0;
2453}
2454
2455/*
2456 * FUNCTION: wlan_hdd_cfg80211_change_iface
2457 * This function is used to set the interface type (INFRASTRUCTURE/ADHOC)
2458 */
2459int wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
2460 struct net_device *ndev,
2461 enum nl80211_iftype type,
2462 u32 *flags,
2463 struct vif_params *params
2464 )
2465{
2466 struct wireless_dev *wdev;
2467 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
2468 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
Mohit Khanna0f232092012-09-11 14:46:08 -07002469 hdd_adapter_t *pP2pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07002470 tCsrRoamProfile *pRoamProfile = NULL;
2471 eCsrRoamBssType LastBSSType;
2472 hdd_config_t *pConfig = pHddCtx->cfg_ini;
2473 eMib_dot11DesiredBssType connectedBssType;
2474 VOS_STATUS status;
2475
2476 ENTER();
2477
2478 if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress)
2479 {
2480 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:LOGP in Progress. Ignore!!!",__func__);
2481 return -EAGAIN;
2482 }
2483
2484 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
2485 __func__, pAdapter->device_mode);
2486
2487 wdev = ndev->ieee80211_ptr;
2488
2489#ifdef WLAN_BTAMP_FEATURE
2490 if((NL80211_IFTYPE_P2P_CLIENT == type)||
2491 (NL80211_IFTYPE_ADHOC == type)||
2492 (NL80211_IFTYPE_AP == type)||
2493 (NL80211_IFTYPE_P2P_GO == type))
2494 {
2495 pHddCtx->isAmpAllowed = VOS_FALSE;
2496 // stop AMP traffic
2497 status = WLANBAP_StopAmp();
2498 if(VOS_STATUS_SUCCESS != status )
2499 {
2500 pHddCtx->isAmpAllowed = VOS_TRUE;
2501 hddLog(VOS_TRACE_LEVEL_FATAL,
2502 "%s: Failed to stop AMP", __func__);
2503 return -EINVAL;
2504 }
2505 }
2506#endif //WLAN_BTAMP_FEATURE
2507 /* Reset the current device mode bit mask*/
2508 wlan_hdd_clear_concurrency_mode(pHddCtx, pAdapter->device_mode);
2509
2510 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -07002511 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnsone7245742012-09-05 17:12:55 -07002512 || (pAdapter->device_mode == WLAN_HDD_P2P_DEVICE)
Jeff Johnson295189b2012-06-20 16:38:30 -07002513 )
2514 {
2515 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
2516 pRoamProfile = &pWextState->roamProfile;
2517 LastBSSType = pRoamProfile->BSSType;
2518
2519 switch (type)
2520 {
2521 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -07002522 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -07002523 hddLog(VOS_TRACE_LEVEL_INFO,
2524 "%s: setting interface Type to INFRASTRUCTURE", __func__);
2525 pRoamProfile->BSSType = eCSR_BSS_TYPE_INFRASTRUCTURE;
Jeff Johnsone7245742012-09-05 17:12:55 -07002526#ifdef WLAN_FEATURE_11AC
2527 if(pConfig->dot11Mode == eHDD_DOT11_MODE_AUTO)
2528 {
2529 pConfig->dot11Mode = eHDD_DOT11_MODE_11ac;
2530 }
2531#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302532 pRoamProfile->phyMode =
Jeff Johnsone7245742012-09-05 17:12:55 -07002533 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07002534 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08002535 //Check for sub-string p2p to confirm its a p2p interface
2536 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302537 {
Gopichand Nakkala864d3552012-12-31 16:08:51 -08002538 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
2539 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
2540 }
2541 else
2542 {
2543 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -07002544 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -08002545 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002546 break;
2547 case NL80211_IFTYPE_ADHOC:
2548 hddLog(VOS_TRACE_LEVEL_INFO,
2549 "%s: setting interface Type to ADHOC", __func__);
2550 pRoamProfile->BSSType = eCSR_BSS_TYPE_START_IBSS;
2551 pRoamProfile->phyMode =
2552 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
2553 wdev->iftype = type;
2554 break;
2555
2556 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -07002557 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07002558 {
2559 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
2560 "%s: setting interface Type to %s", __func__,
2561 (type == NL80211_IFTYPE_AP) ? "SoftAP" : "P2pGo");
2562
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08002563 //Cancel any remain on channel for GO mode
2564 if (NL80211_IFTYPE_P2P_GO == type)
2565 {
2566 wlan_hdd_cancel_existing_remain_on_channel(pAdapter);
2567 }
Mohit Khanna0f232092012-09-11 14:46:08 -07002568 if (NL80211_IFTYPE_AP == type)
2569 {
2570 /* As Loading WLAN Driver one interface being created for p2p device
2571 * address. This will take one HW STA and the max number of clients
2572 * that can connect to softAP will be reduced by one. so while changing
2573 * the interface type to NL80211_IFTYPE_AP (SoftAP) remove p2p0
2574 * interface as it is not required in SoftAP mode.
2575 */
2576
2577 // Get P2P Adapter
2578 pP2pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_DEVICE);
2579
2580 if (pP2pAdapter)
2581 {
2582 hdd_stop_adapter(pHddCtx, pP2pAdapter);
2583 hdd_deinit_adapter(pHddCtx, pP2pAdapter);
2584 hdd_close_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
2585 }
2586 }
2587
Jeff Johnson295189b2012-06-20 16:38:30 -07002588 //De-init the adapter.
2589 hdd_stop_adapter( pHddCtx, pAdapter );
2590 hdd_deinit_adapter( pHddCtx, pAdapter );
2591 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
Jeff Johnson295189b2012-06-20 16:38:30 -07002592 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
2593 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Jeff Johnson32d95a32012-09-10 13:15:23 -07002594
2595 //Disable BMPS and IMPS if enabled
2596 //before starting Go
2597 if(WLAN_HDD_P2P_GO == pAdapter->device_mode)
2598 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302599 if(VOS_STATUS_E_FAILURE ==
Jeff Johnson32d95a32012-09-10 13:15:23 -07002600 hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_P2P_GO))
2601 {
2602 //Fail to Exit BMPS
2603 VOS_ASSERT(0);
2604 }
2605 }
2606
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -07002607 if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) &&
2608 (pConfig->apRandomBssidEnabled))
2609 {
2610 /* To meet Android requirements create a randomized
2611 MAC address of the form 02:1A:11:Fx:xx:xx */
2612 get_random_bytes(&ndev->dev_addr[3], 3);
2613 ndev->dev_addr[0] = 0x02;
2614 ndev->dev_addr[1] = 0x1A;
2615 ndev->dev_addr[2] = 0x11;
2616 ndev->dev_addr[3] |= 0xF0;
2617 memcpy(pAdapter->macAddressCurrent.bytes, ndev->dev_addr,
2618 VOS_MAC_ADDR_SIZE);
2619 pr_info("wlan: Generated HotSpot BSSID "
2620 "%02x:%02x:%02x:%02x:%02x:%02x\n",
2621 ndev->dev_addr[0],
2622 ndev->dev_addr[1],
2623 ndev->dev_addr[2],
2624 ndev->dev_addr[3],
2625 ndev->dev_addr[4],
2626 ndev->dev_addr[5]);
2627 }
2628
Jeff Johnson295189b2012-06-20 16:38:30 -07002629 hdd_set_ap_ops( pAdapter->dev );
2630
2631 status = hdd_init_ap_mode(pAdapter);
2632 if(status != VOS_STATUS_SUCCESS)
2633 {
2634 hddLog(VOS_TRACE_LEVEL_FATAL,
2635 "%s: Error initializing the ap mode", __func__);
2636 return -EINVAL;
2637 }
2638 hdd_set_conparam(1);
2639
Jeff Johnson295189b2012-06-20 16:38:30 -07002640 /*interface type changed update in wiphy structure*/
2641 if(wdev)
2642 {
2643 wdev->iftype = type;
2644 pHddCtx->change_iface = type;
2645 }
2646 else
2647 {
2648 hddLog(VOS_TRACE_LEVEL_ERROR,
2649 "%s: ERROR !!!! Wireless dev is NULL", __func__);
2650 return -EINVAL;
2651 }
2652 goto done;
2653 }
2654
2655 default:
2656 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
2657 __func__);
2658 return -EOPNOTSUPP;
2659 }
2660 }
2661 else if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07002662 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07002663 )
2664 {
2665 switch(type)
2666 {
2667 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -07002668 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -07002669 case NL80211_IFTYPE_ADHOC:
Jeff Johnson32d95a32012-09-10 13:15:23 -07002670 hdd_stop_adapter( pHddCtx, pAdapter );
2671 hdd_deinit_adapter( pHddCtx, pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07002672 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08002673 //Check for sub-string p2p to confirm its a p2p interface
2674 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala864d3552012-12-31 16:08:51 -08002675 {
2676 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
2677 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
2678 }
2679 else
2680 {
2681 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -07002682 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -08002683 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002684 hdd_set_conparam(0);
2685 pHddCtx->change_iface = type;
Jeff Johnson295189b2012-06-20 16:38:30 -07002686 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
2687 hdd_set_station_ops( pAdapter->dev );
2688 status = hdd_init_station_mode( pAdapter );
2689 if( VOS_STATUS_SUCCESS != status )
2690 return -EOPNOTSUPP;
Jeff Johnsone7245742012-09-05 17:12:55 -07002691 /* In case of JB, for P2P-GO, only change interface will be called,
2692 * This is the right place to enable back bmps_imps()
2693 */
2694 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07002695 goto done;
2696 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -07002697 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07002698 wdev->iftype = type;
Jeff Johnson295189b2012-06-20 16:38:30 -07002699 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
2700 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Jeff Johnson295189b2012-06-20 16:38:30 -07002701 goto done;
2702 default:
2703 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
2704 __func__);
2705 return -EOPNOTSUPP;
2706
2707 }
2708
2709 }
2710 else
2711 {
2712 return -EOPNOTSUPP;
2713 }
2714
2715
2716 if(pRoamProfile)
2717 {
2718 if ( LastBSSType != pRoamProfile->BSSType )
2719 {
2720 /*interface type changed update in wiphy structure*/
2721 wdev->iftype = type;
2722
2723 /*the BSS mode changed, We need to issue disconnect
2724 if connected or in IBSS disconnect state*/
2725 if ( hdd_connGetConnectedBssType(
2726 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), &connectedBssType ) ||
2727 ( eCSR_BSS_TYPE_START_IBSS == LastBSSType ) )
2728 {
2729 /*need to issue a disconnect to CSR.*/
2730 INIT_COMPLETION(pAdapter->disconnect_comp_var);
2731 if( eHAL_STATUS_SUCCESS ==
2732 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
2733 pAdapter->sessionId,
2734 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
2735 {
2736 wait_for_completion_interruptible_timeout(
2737 &pAdapter->disconnect_comp_var,
2738 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
2739 }
2740 }
2741 }
2742 }
2743
2744done:
2745 /*set bitmask based on updated value*/
2746 wlan_hdd_set_concurrency_mode(pHddCtx, pAdapter->device_mode);
2747#ifdef WLAN_BTAMP_FEATURE
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302748 if((NL80211_IFTYPE_STATION == type) && (pHddCtx->concurrency_mode <= 1) &&
Jeff Johnson295189b2012-06-20 16:38:30 -07002749 (pHddCtx->no_of_sessions[WLAN_HDD_INFRA_STATION] <=1))
2750 {
2751 //we are ok to do AMP
2752 pHddCtx->isAmpAllowed = VOS_TRUE;
2753 }
2754#endif //WLAN_BTAMP_FEATURE
2755 EXIT();
2756 return 0;
2757}
2758
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002759#ifdef FEATURE_WLAN_TDLS
2760static int wlan_hdd_tdls_add_station(struct wiphy *wiphy,
2761 struct net_device *dev, u8 *mac, bool update, tCsrStaParams *StaParams)
2762{
2763 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2764 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
2765 VOS_STATUS status;
2766
2767 ENTER();
2768
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05302769 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002770 {
2771 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2772 "Invalid arguments");
2773 return -EINVAL;
2774 }
Hoonki Lee27511902013-03-14 18:19:06 -07002775
2776 if ((eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode) ||
2777 (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode))
2778 {
2779 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2780 "%s: TDLS mode is disabled OR not enabled in FW."
2781 MAC_ADDRESS_STR " Request declined.",
2782 __func__, MAC_ADDR_ARRAY(mac));
2783 return -ENOTSUPP;
2784 }
2785
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002786 if (pHddCtx->isLogpInProgress)
2787 {
2788 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2789 "%s:LOGP in Progress. Ignore!!!", __func__);
Gopichand Nakkala05922802013-03-14 12:23:19 -07002790 wlan_hdd_tdls_set_link_status(pAdapter, mac, eTDLS_LINK_IDLE);
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002791 return -EBUSY;
2792 }
2793
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07002794 /* when self is on-going, we dont' want to change link_status */
2795 if ((0 == update) && wlan_hdd_tdls_is_peer_progress(pAdapter, mac))
2796 {
2797 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2798 "%s: " MAC_ADDRESS_STR
2799 " TDLS setup is ongoing. Request declined.",
2800 __func__, MAC_ADDR_ARRAY(mac));
2801 return -EPERM;
2802 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07002803 /* when self is not on-ongoing, we don't want to allow change_station */
2804 if ((1 == update) && !wlan_hdd_tdls_is_peer_progress(pAdapter, mac))
2805 {
2806 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2807 "%s: " MAC_ADDRESS_STR
2808 " TDLS is not connecting. change station declined.",
2809 __func__, MAC_ADDR_ARRAY(mac));
2810 return -EPERM;
2811 }
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;
2875 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL, "Supported rates:");
2876 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 );
2934 v_MACADDR_t STAMacAddress;
Gopichand Nakkalab0856222013-03-12 22:39:05 -07002935#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002936 tCsrStaParams StaParams = {0};
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002937 tANI_U8 isBufSta = 0;
Gopichand Nakkalab0856222013-03-12 22:39:05 -07002938#endif
Jeff Johnsone7245742012-09-05 17:12:55 -07002939 ENTER();
2940
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002941 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
2942 {
2943 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2944 "%s:LOGP in Progress. Ignore!!!", __func__);
2945 return -EAGAIN;
2946 }
2947
Jeff Johnson295189b2012-06-20 16:38:30 -07002948 vos_mem_copy(STAMacAddress.bytes, mac, sizeof(v_MACADDR_t));
2949
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002950 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
2951 || (pAdapter->device_mode == WLAN_HDD_P2P_GO))
Jeff Johnson295189b2012-06-20 16:38:30 -07002952 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002953 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED))
Jeff Johnson295189b2012-06-20 16:38:30 -07002954 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302955 status = hdd_softap_change_STA_state( pAdapter, &STAMacAddress,
Jeff Johnson295189b2012-06-20 16:38:30 -07002956 WLANTL_STA_AUTHENTICATED);
2957
2958 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002959 "%s: Station MAC address does not matching", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002960 return -EINVAL;
2961 }
2962 }
Gopichand Nakkalab0856222013-03-12 22:39:05 -07002963#ifdef FEATURE_WLAN_TDLS
Hoonki Leea6d49be2013-04-05 09:43:25 -07002964 else if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
2965 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)) {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07002966 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
2967 StaParams.capability = params->capability;
2968 StaParams.uapsd_queues = params->uapsd_queues;
2969 StaParams.max_sp = params->max_sp;
2970
2971 if (0 != params->ext_capab_len)
2972 vos_mem_copy(StaParams.extn_capability, params->ext_capab,
2973 sizeof(StaParams.extn_capability));
2974
2975 if (NULL != params->ht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -07002976 {
2977 StaParams.htcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07002978 vos_mem_copy(&StaParams.HTCap, params->ht_capa, sizeof(tSirHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -07002979 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07002980
2981 StaParams.supported_rates_len = params->supported_rates_len;
2982
2983 /* Note : The Maximum sizeof supported_rates sent by the Supplicant is 32.
2984 * The supported_rates array , for all the structures propogating till Add Sta
2985 * to the firmware has to be modified , if the supplicant (ieee80211) is
2986 * modified to send more rates.
2987 */
2988
2989 /* To avoid Data Currption , set to max length to SIR_MAC_MAX_SUPP_RATES
2990 */
2991 if (StaParams.supported_rates_len > SIR_MAC_MAX_SUPP_RATES)
2992 StaParams.supported_rates_len = SIR_MAC_MAX_SUPP_RATES;
2993
2994 if (0 != StaParams.supported_rates_len) {
2995 int i = 0;
2996 vos_mem_copy(StaParams.supported_rates, params->supported_rates,
2997 StaParams.supported_rates_len);
2998 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2999 "Supported Rates with Length %d", StaParams.supported_rates_len);
3000 for (i=0; i < StaParams.supported_rates_len; i++)
3001 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
3002 "[%d]: %0x", i, StaParams.supported_rates[i]);
3003 }
3004
3005 if (NULL != params->vht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -07003006 {
3007 StaParams.vhtcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003008 vos_mem_copy(&StaParams.VHTCap, params->vht_capa, sizeof(tSirVHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -07003009 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003010
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003011 if (0 != params->ext_capab_len ) {
3012 /*Define A Macro : TODO Sunil*/
3013 if ((1<<4) & StaParams.extn_capability[3]) {
3014 isBufSta = 1;
3015 }
3016 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003017 //status = wlan_hdd_tdls_set_peer_caps( mac, params->uapsd_queues,
3018 // params->max_sp, isBufSta);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003019 //if (VOS_STATUS_SUCCESS != status) {
3020 // VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3021 // "%s: wlan_hdd_tdls_set_peer_caps failed!", __func__);
3022 // return -EINVAL;
3023 //}
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003024 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 1, &StaParams);
3025
3026 if (VOS_STATUS_SUCCESS != status) {
3027 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3028 "%s: sme_ChangeTdlsPeerSta failed!", __func__);
3029 return -EINVAL;
3030 }
3031 }
3032 }
Gopichand Nakkalab0856222013-03-12 22:39:05 -07003033#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303034
Jeff Johnsone7245742012-09-05 17:12:55 -07003035 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07003036 return status;
3037}
3038
3039/*
3040 * FUNCTION: wlan_hdd_cfg80211_get_ibss_peer_staidx
3041 * This function is used to get peer station index in IBSS mode
3042 */
3043static u8 wlan_hdd_cfg80211_get_ibss_peer_staidx(hdd_adapter_t* pAdapter)
3044{
3045 u8 idx = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303046 u8 temp[VOS_MAC_ADDR_SIZE] = {0};
Jeff Johnson295189b2012-06-20 16:38:30 -07003047 ENTER();
3048 memset(temp, 0, VOS_MAC_ADDR_SIZE);
3049 for ( idx = 0; idx < HDD_MAX_NUM_IBSS_STA; idx++ )
3050 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303051 if ( (0 !=
3052 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.staId[idx])
Jeff Johnson295189b2012-06-20 16:38:30 -07003053 && memcmp((u8*)&(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.peerMacAddress[idx],
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303054 temp, VOS_MAC_ADDR_SIZE)
Jeff Johnson295189b2012-06-20 16:38:30 -07003055 )
3056 {
3057 return idx;
3058 }
3059 }
3060 return idx;
3061}
3062
3063
3064/*
3065 * FUNCTION: wlan_hdd_cfg80211_add_key
3066 * This function is used to initialize the key information
3067 */
3068#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003069static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07003070 struct net_device *ndev,
3071 u8 key_index, bool pairwise,
3072 const u8 *mac_addr,
3073 struct key_params *params
3074 )
3075#else
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003076static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07003077 struct net_device *ndev,
3078 u8 key_index, const u8 *mac_addr,
3079 struct key_params *params
3080 )
3081#endif
3082{
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003083 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -07003084 tCsrRoamSetKey setKey;
3085 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
3086 int status = 0;
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003087 v_U32_t roamId= 0xFF;
3088 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07003089 hdd_hostapd_state_t *pHostapdState;
3090 VOS_STATUS vos_status;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07003091 eHalStatus halStatus;
Jeff Johnson295189b2012-06-20 16:38:30 -07003092
3093 ENTER();
3094
Jeff Johnson04dd8a82012-06-29 20:41:40 -07003095 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
3096 {
3097 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3098 "%s:LOGP in Progress. Ignore!!!", __func__);
3099 return -EAGAIN;
3100 }
3101
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003102 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
3103 __func__, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07003104
3105 if (CSR_MAX_NUM_KEY <= key_index)
3106 {
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003107 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07003108 key_index);
3109
3110 return -EINVAL;
3111 }
3112
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003113 if (CSR_MAX_KEY_LEN < params->key_len)
3114 {
3115 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key length %d", __func__,
3116 params->key_len);
3117
3118 return -EINVAL;
3119 }
3120
3121 hddLog(VOS_TRACE_LEVEL_INFO,
3122 "%s: called with key index = %d & key length %d",
3123 __func__, key_index, params->key_len);
Jeff Johnson295189b2012-06-20 16:38:30 -07003124
3125 /*extract key idx, key len and key*/
3126 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
3127 setKey.keyId = key_index;
3128 setKey.keyLength = params->key_len;
3129 vos_mem_copy(&setKey.Key[0],params->key, params->key_len);
3130
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003131 switch (params->cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -07003132 {
3133 case WLAN_CIPHER_SUITE_WEP40:
3134 setKey.encType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
3135 break;
3136
3137 case WLAN_CIPHER_SUITE_WEP104:
3138 setKey.encType = eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
3139 break;
3140
3141 case WLAN_CIPHER_SUITE_TKIP:
3142 {
3143 u8 *pKey = &setKey.Key[0];
3144 setKey.encType = eCSR_ENCRYPT_TYPE_TKIP;
3145
3146 vos_mem_zero(pKey, CSR_MAX_KEY_LEN);
3147
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003148 /*Supplicant sends the 32bytes key in this order
Jeff Johnson295189b2012-06-20 16:38:30 -07003149
3150 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003151 | Tk1 |TX-MIC | RX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -07003152 |--------------|----------|----------|
3153 <---16bytes---><--8bytes--><--8bytes-->
3154
3155 */
3156 /*Sme expects the 32 bytes key to be in the below order
3157
3158 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003159 | Tk1 |RX-MIC | TX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -07003160 |--------------|----------|----------|
3161 <---16bytes---><--8bytes--><--8bytes-->
3162 */
3163 /* Copy the Temporal Key 1 (TK1) */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003164 vos_mem_copy(pKey, params->key, 16);
Jeff Johnson295189b2012-06-20 16:38:30 -07003165
3166 /*Copy the rx mic first*/
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003167 vos_mem_copy(&pKey[16], &params->key[24], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -07003168
3169 /*Copy the tx mic */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003170 vos_mem_copy(&pKey[24], &params->key[16], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -07003171
3172
3173 break;
3174 }
3175
3176 case WLAN_CIPHER_SUITE_CCMP:
3177 setKey.encType = eCSR_ENCRYPT_TYPE_AES;
3178 break;
3179
3180#ifdef FEATURE_WLAN_WAPI
3181 case WLAN_CIPHER_SUITE_SMS4:
3182 {
3183 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
3184 wlan_hdd_cfg80211_set_key_wapi(pAdapter, key_index, mac_addr,
3185 params->key, params->key_len);
3186 return 0;
3187 }
3188#endif
Chet Lanctot186b5732013-03-18 10:26:30 -07003189
Jeff Johnson295189b2012-06-20 16:38:30 -07003190#ifdef FEATURE_WLAN_CCX
3191 case WLAN_CIPHER_SUITE_KRK:
3192 setKey.encType = eCSR_ENCRYPT_TYPE_KRK;
3193 break;
3194#endif
Chet Lanctot186b5732013-03-18 10:26:30 -07003195
3196#ifdef WLAN_FEATURE_11W
3197 case WLAN_CIPHER_SUITE_AES_CMAC:
3198 setKey.encType = eCSR_ENCRYPT_TYPE_AES_CMAC;
Chet Lanctot3b5158a2013-03-31 16:45:21 -07003199 break;
Chet Lanctot186b5732013-03-18 10:26:30 -07003200#endif
3201
Jeff Johnson295189b2012-06-20 16:38:30 -07003202 default:
3203 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unsupported cipher type %lu",
3204 __func__, params->cipher);
3205 return -EOPNOTSUPP;
3206 }
3207
3208 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: encryption type %d",
3209 __func__, setKey.encType);
3210
3211
3212
3213 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07003214 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07003215 )
3216 {
3217
3218
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003219 if (
Jeff Johnson295189b2012-06-20 16:38:30 -07003220#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
3221 (!pairwise)
3222#else
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003223 (!mac_addr || is_broadcast_ether_addr(mac_addr))
Jeff Johnson295189b2012-06-20 16:38:30 -07003224#endif
3225 )
3226 {
3227 /* set group key*/
3228 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnson1250df42012-12-10 14:31:52 -08003229 "%s- %d: setting Broadcast key",
Jeff Johnson295189b2012-06-20 16:38:30 -07003230 __func__, __LINE__);
3231 setKey.keyDirection = eSIR_RX_ONLY;
3232 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
3233 }
3234 else
3235 {
3236 /* set pairwise key*/
3237 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3238 "%s- %d: setting pairwise key",
3239 __func__, __LINE__);
3240 setKey.keyDirection = eSIR_TX_RX;
3241 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
3242 }
3243
3244 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003245 if( pHostapdState->bssState == BSS_START )
3246 {
Jeff Johnson295189b2012-06-20 16:38:30 -07003247 status = WLANSAP_SetKeySta( pVosContext, &setKey);
3248
3249 if ( status != eHAL_STATUS_SUCCESS )
3250 {
3251 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3252 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
3253 __LINE__, status );
3254 }
3255 }
3256
3257 /* Saving WEP keys */
3258 else if( eCSR_ENCRYPT_TYPE_WEP40_STATICKEY == setKey.encType ||
3259 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY == setKey.encType )
3260 {
3261 //Save the wep key in ap context. Issue setkey after the BSS is started.
3262 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
3263 vos_mem_copy(&pAPCtx->wepKey[key_index], &setKey, sizeof(tCsrRoamSetKey));
3264 }
3265 else
3266 {
3267 //Save the key in ap context. Issue setkey after the BSS is started.
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003268 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07003269 vos_mem_copy(&pAPCtx->groupKey, &setKey, sizeof(tCsrRoamSetKey));
3270 }
3271 }
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003272 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION) ||
3273 (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT) )
Jeff Johnson295189b2012-06-20 16:38:30 -07003274 {
3275 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
3276 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3277
3278 pWextState->roamProfile.Keys.KeyLength[key_index] = (u8)params->key_len;
3279
Venkata Prathyusha Kuntupalliee2ce712013-01-17 14:09:24 -08003280 pWextState->roamProfile.Keys.defaultIndex = key_index;
3281
3282
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003283 vos_mem_copy(&pWextState->roamProfile.Keys.KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -07003284 params->key, params->key_len);
3285
3286 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
3287
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303288 if (!( ( IW_AUTH_KEY_MGMT_802_1X
3289 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X))
Jeff Johnson295189b2012-06-20 16:38:30 -07003290 && (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType)
3291 )
3292 &&
3293 ( (WLAN_CIPHER_SUITE_WEP40 == params->cipher)
3294 || (WLAN_CIPHER_SUITE_WEP104 == params->cipher)
3295 )
3296 )
3297 {
3298 /* in case of static WEP, macaddr/bssid is not coming from nl80211
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303299 * interface, copy bssid for pairwise key and group macaddr for
Jeff Johnson295189b2012-06-20 16:38:30 -07003300 * group key initialization*/
3301
3302 tCsrRoamProfile *pRoamProfile = &pWextState->roamProfile;
3303
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303304 pWextState->roamProfile.negotiatedUCEncryptionType =
3305 pHddStaCtx->conn_info.ucEncryptionType =
Jeff Johnson295189b2012-06-20 16:38:30 -07003306 ((WLAN_CIPHER_SUITE_WEP40 == params->cipher) ?
3307 eCSR_ENCRYPT_TYPE_WEP40_STATICKEY :
3308 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY);
3309
3310
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303311 hddLog(VOS_TRACE_LEVEL_INFO_MED,
3312 "%s: Negotiated encryption type %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07003313 pWextState->roamProfile.negotiatedUCEncryptionType);
3314
3315 sme_SetCfgPrivacy((tpAniSirGlobal)WLAN_HDD_GET_HAL_CTX(pAdapter),
3316 &pWextState->roamProfile, true);
3317 setKey.keyLength = 0;
3318 setKey.keyDirection = eSIR_TX_RX;
3319
3320#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303321 if (pairwise)
Jeff Johnson295189b2012-06-20 16:38:30 -07003322 {
3323#endif
3324 if (mac_addr)
3325 {
3326 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
3327 }
3328 else
3329 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303330 /* macaddr is NULL, set the peerMac to bssId in case of BSS,
Jeff Johnson295189b2012-06-20 16:38:30 -07003331 * and peerMacAddress in case of IBSS*/
3332 if (eCSR_BSS_TYPE_START_IBSS == pRoamProfile->BSSType)
3333 {
3334 u8 staidx = wlan_hdd_cfg80211_get_ibss_peer_staidx(pAdapter);
3335 if (HDD_MAX_NUM_IBSS_STA != staidx)
3336 {
3337 vos_mem_copy(setKey.peerMac,
3338 &pHddStaCtx->conn_info.peerMacAddress[staidx],
3339 WNI_CFG_BSSID_LEN);
3340
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303341 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003342 else
3343 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303344 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No peerMac found",
Jeff Johnson295189b2012-06-20 16:38:30 -07003345 __func__);
3346 return -EOPNOTSUPP;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303347 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003348 }
3349 else
3350 {
3351 vos_mem_copy(setKey.peerMac,
3352 &pHddStaCtx->conn_info.bssId[0],
3353 WNI_CFG_BSSID_LEN);
3354 }
3355 }
3356#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
3357 }
3358 else
3359 {
3360 /* set group key*/
3361 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3362 "%s- %d: setting Group key",
3363 __func__, __LINE__);
3364 setKey.keyDirection = eSIR_RX_ONLY;
3365 vos_mem_copy(setKey.peerMac, groupmacaddr, WNI_CFG_BSSID_LEN);
3366 }
3367#endif
3368 }
3369 else if (
3370#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
3371 (!pairwise)
3372#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303373 (!mac_addr || is_broadcast_ether_addr(mac_addr))
Jeff Johnson295189b2012-06-20 16:38:30 -07003374#endif
3375 )
3376 {
3377 /* set group key*/
3378 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3379 "%s- %d: setting Group key",
3380 __func__, __LINE__);
3381 setKey.keyDirection = eSIR_RX_ONLY;
3382 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
3383 }
3384 else
3385 {
3386 /* set pairwise key*/
3387 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3388 "%s- %d: setting pairwise key",
3389 __func__, __LINE__);
3390 setKey.keyDirection = eSIR_TX_RX;
3391 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
3392 }
3393
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303394 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -07003395 "%s: set key for peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303396 __func__, setKey.peerMac[0], setKey.peerMac[1],
3397 setKey.peerMac[2], setKey.peerMac[3],
3398 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -07003399 setKey.keyDirection);
3400
3401 vos_status = wlan_hdd_check_ula_done(pAdapter);
3402
3403 if ( vos_status != VOS_STATUS_SUCCESS )
3404 {
3405 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3406 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
3407 __LINE__, vos_status );
3408
3409 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
3410
3411 return -EINVAL;
3412
3413 }
3414
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07003415#ifdef WLAN_FEATURE_VOWIFI_11R
3416 /* The supplicant may attempt to set the PTK once pre-authentication is done.
3417 Save the key in the UMAC and include it in the ADD BSS request */
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07003418 halStatus = sme_FTUpdateKey( WLAN_HDD_GET_HAL_CTX(pAdapter), &setKey);
Gopichand Nakkalad7d13652013-02-15 01:48:00 +05303419 if( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_WAIT )
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07003420 {
Gopichand Nakkalad7d13652013-02-15 01:48:00 +05303421 return -EINVAL;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07003422 }
3423#endif /* WLAN_FEATURE_VOWIFI_11R */
Jeff Johnson295189b2012-06-20 16:38:30 -07003424
3425 /* issue set key request to SME*/
3426 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
3427 pAdapter->sessionId, &setKey, &roamId );
3428
3429 if ( 0 != status )
3430 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303431 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07003432 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
3433 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
3434 return -EINVAL;
3435 }
3436
3437
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303438 /* in case of IBSS as there was no information available about WEP keys during
3439 * IBSS join, group key intialized with NULL key, so re-initialize group key
Jeff Johnson295189b2012-06-20 16:38:30 -07003440 * with correct value*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303441 if ( (eCSR_BSS_TYPE_START_IBSS == pWextState->roamProfile.BSSType) &&
3442 !( ( IW_AUTH_KEY_MGMT_802_1X
3443 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X))
Jeff Johnson295189b2012-06-20 16:38:30 -07003444 && (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType)
3445 )
3446 &&
3447 ( (WLAN_CIPHER_SUITE_WEP40 == params->cipher)
3448 || (WLAN_CIPHER_SUITE_WEP104 == params->cipher)
3449 )
3450 )
3451 {
3452 setKey.keyDirection = eSIR_RX_ONLY;
3453 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
3454
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303455 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -07003456 "%s: set key peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303457 __func__, setKey.peerMac[0], setKey.peerMac[1],
3458 setKey.peerMac[2], setKey.peerMac[3],
3459 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -07003460 setKey.keyDirection);
3461
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303462 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07003463 pAdapter->sessionId, &setKey, &roamId );
3464
3465 if ( 0 != status )
3466 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303467 hddLog(VOS_TRACE_LEVEL_ERROR,
3468 "%s: sme_RoamSetKey failed for group key (IBSS), returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07003469 __func__, status);
3470 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
3471 return -EINVAL;
3472 }
3473 }
3474 }
3475
3476 return 0;
3477}
3478
3479/*
3480 * FUNCTION: wlan_hdd_cfg80211_get_key
3481 * This function is used to get the key information
3482 */
3483#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303484static int wlan_hdd_cfg80211_get_key(
3485 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07003486 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303487 u8 key_index, bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -07003488 const u8 *mac_addr, void *cookie,
3489 void (*callback)(void *cookie, struct key_params*)
3490 )
3491#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303492static int wlan_hdd_cfg80211_get_key(
3493 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07003494 struct net_device *ndev,
3495 u8 key_index, const u8 *mac_addr, void *cookie,
3496 void (*callback)(void *cookie, struct key_params*)
3497 )
3498#endif
3499{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303500 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -07003501 hdd_wext_state_t *pWextState= WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
3502 tCsrRoamProfile *pRoamProfile = &(pWextState->roamProfile);
3503 struct key_params params;
3504
3505 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303506
Jeff Johnson295189b2012-06-20 16:38:30 -07003507 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",
3508 __func__,pAdapter->device_mode);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303509
Jeff Johnson295189b2012-06-20 16:38:30 -07003510 memset(&params, 0, sizeof(params));
3511
3512 if (CSR_MAX_NUM_KEY <= key_index)
3513 {
3514 return -EINVAL;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303515 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003516
3517 switch(pRoamProfile->EncryptionType.encryptionType[0])
3518 {
3519 case eCSR_ENCRYPT_TYPE_NONE:
3520 params.cipher = IW_AUTH_CIPHER_NONE;
3521 break;
3522
3523 case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY:
3524 case eCSR_ENCRYPT_TYPE_WEP40:
3525 params.cipher = WLAN_CIPHER_SUITE_WEP40;
3526 break;
3527
3528 case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY:
3529 case eCSR_ENCRYPT_TYPE_WEP104:
3530 params.cipher = WLAN_CIPHER_SUITE_WEP104;
3531 break;
3532
3533 case eCSR_ENCRYPT_TYPE_TKIP:
3534 params.cipher = WLAN_CIPHER_SUITE_TKIP;
3535 break;
3536
3537 case eCSR_ENCRYPT_TYPE_AES:
3538 params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
3539 break;
3540
3541 default:
3542 params.cipher = IW_AUTH_CIPHER_NONE;
3543 break;
3544 }
3545
3546 params.key_len = pRoamProfile->Keys.KeyLength[key_index];
3547 params.seq_len = 0;
3548 params.seq = NULL;
3549 params.key = &pRoamProfile->Keys.KeyMaterial[key_index][0];
3550 callback(cookie, &params);
3551 return 0;
3552}
3553
3554/*
3555 * FUNCTION: wlan_hdd_cfg80211_del_key
3556 * This function is used to delete the key information
3557 */
3558#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303559static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07003560 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303561 u8 key_index,
3562 bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -07003563 const u8 *mac_addr
3564 )
3565#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303566static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07003567 struct net_device *ndev,
3568 u8 key_index,
3569 const u8 *mac_addr
3570 )
3571#endif
3572{
3573 int status = 0;
3574
3575 //This code needs to be revisited. There is sme_removeKey API, we should
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303576 //plan to use that. After the change to use correct index in setkey,
Jeff Johnson295189b2012-06-20 16:38:30 -07003577 //it is observed that this is invalidating peer
3578 //key index whenever re-key is done. This is affecting data link.
3579 //It should be ok to ignore del_key.
3580#if 0
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303581 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
3582 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07003583 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
3584 tCsrRoamSetKey setKey;
3585 v_U32_t roamId= 0xFF;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303586
Jeff Johnson295189b2012-06-20 16:38:30 -07003587 ENTER();
3588
3589 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device_mode = %d\n",
3590 __func__,pAdapter->device_mode);
3591
3592 if (CSR_MAX_NUM_KEY <= key_index)
3593 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303594 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07003595 key_index);
3596
3597 return -EINVAL;
3598 }
3599
3600 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
3601 setKey.keyId = key_index;
3602
3603 if (mac_addr)
3604 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
3605 else
3606 vos_mem_copy(setKey.peerMac, groupmacaddr, WNI_CFG_BSSID_LEN);
3607
3608 setKey.encType = eCSR_ENCRYPT_TYPE_NONE;
3609
3610 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07003611 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303612 )
3613 {
3614
3615 hdd_hostapd_state_t *pHostapdState =
Jeff Johnson295189b2012-06-20 16:38:30 -07003616 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
3617 if( pHostapdState->bssState == BSS_START)
3618 {
3619 status = WLANSAP_SetKeySta( pVosContext, &setKey);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303620
Jeff Johnson295189b2012-06-20 16:38:30 -07003621 if ( status != eHAL_STATUS_SUCCESS )
3622 {
3623 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3624 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
3625 __LINE__, status );
3626 }
3627 }
3628 }
3629 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303630 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnson295189b2012-06-20 16:38:30 -07003631 )
3632 {
3633 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3634
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303635 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
3636
3637 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -07003638 "%s: delete key for peerMac %2x:%2x:%2x:%2x:%2x:%2x",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303639 __func__, setKey.peerMac[0], setKey.peerMac[1],
3640 setKey.peerMac[2], setKey.peerMac[3],
Jeff Johnson295189b2012-06-20 16:38:30 -07003641 setKey.peerMac[4], setKey.peerMac[5]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303642 if(pAdapter->sessionCtx.station.conn_info.connState ==
3643 eConnectionState_Associated)
Jeff Johnson295189b2012-06-20 16:38:30 -07003644 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303645 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07003646 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303647
Jeff Johnson295189b2012-06-20 16:38:30 -07003648 if ( 0 != status )
3649 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303650 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07003651 "%s: sme_RoamSetKey failure, returned %d",
3652 __func__, status);
3653 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
3654 return -EINVAL;
3655 }
3656 }
3657 }
3658#endif
Jeff Johnsone7245742012-09-05 17:12:55 -07003659 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07003660 return status;
3661}
3662
3663/*
3664 * FUNCTION: wlan_hdd_cfg80211_set_default_key
3665 * This function is used to set the default tx key index
3666 */
3667#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
3668static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
3669 struct net_device *ndev,
3670 u8 key_index,
3671 bool unicast, bool multicast)
3672#else
3673static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
3674 struct net_device *ndev,
3675 u8 key_index)
3676#endif
3677{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303678 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -07003679 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
3680 int status = 0;
3681 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3682
3683 ENTER();
3684
3685 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d key_index = %d \n",
3686 __func__,pAdapter->device_mode, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303687
Jeff Johnson295189b2012-06-20 16:38:30 -07003688 if (CSR_MAX_NUM_KEY <= key_index)
3689 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303690 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07003691 key_index);
3692
3693 return -EINVAL;
3694 }
3695
Jeff Johnson04dd8a82012-06-29 20:41:40 -07003696 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
3697 {
3698 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3699 "%s:LOGP in Progress. Ignore!!!", __func__);
3700 return -EAGAIN;
3701 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303702
Jeff Johnson295189b2012-06-20 16:38:30 -07003703 if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -07003704 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303705 )
Jeff Johnson295189b2012-06-20 16:38:30 -07003706 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303707 if ( (key_index != pWextState->roamProfile.Keys.defaultIndex) &&
3708 (eCSR_ENCRYPT_TYPE_TKIP !=
Jeff Johnson295189b2012-06-20 16:38:30 -07003709 pWextState->roamProfile.EncryptionType.encryptionType[0]) &&
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303710 (eCSR_ENCRYPT_TYPE_AES !=
Jeff Johnson295189b2012-06-20 16:38:30 -07003711 pWextState->roamProfile.EncryptionType.encryptionType[0])
3712 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303713 {
3714 /* if default key index is not same as previous one,
Jeff Johnson295189b2012-06-20 16:38:30 -07003715 * then update the default key index */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303716
Jeff Johnson295189b2012-06-20 16:38:30 -07003717 tCsrRoamSetKey setKey;
3718 v_U32_t roamId= 0xFF;
3719 tCsrKeys *Keys = &pWextState->roamProfile.Keys;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303720
3721 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: default tx key index %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07003722 __func__, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303723
Jeff Johnson295189b2012-06-20 16:38:30 -07003724 Keys->defaultIndex = (u8)key_index;
3725 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
3726 setKey.keyId = key_index;
3727 setKey.keyLength = Keys->KeyLength[key_index];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303728
3729 vos_mem_copy(&setKey.Key[0],
3730 &Keys->KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -07003731 Keys->KeyLength[key_index]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303732
Jeff Johnson295189b2012-06-20 16:38:30 -07003733 setKey.keyDirection = eSIR_TX_ONLY;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303734
3735 vos_mem_copy(setKey.peerMac,
Jeff Johnson295189b2012-06-20 16:38:30 -07003736 &pHddStaCtx->conn_info.bssId[0],
3737 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303738
3739 setKey.encType =
Jeff Johnson295189b2012-06-20 16:38:30 -07003740 pWextState->roamProfile.EncryptionType.encryptionType[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303741
Jeff Johnson295189b2012-06-20 16:38:30 -07003742 /* issue set key request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303743 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07003744 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303745
Jeff Johnson295189b2012-06-20 16:38:30 -07003746 if ( 0 != status )
3747 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303748 hddLog(VOS_TRACE_LEVEL_ERROR,
3749 "%s: sme_RoamSetKey failed, returned %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07003750 status);
3751 return -EINVAL;
3752 }
3753 }
3754 }
3755
3756 /* In SoftAp mode setting key direction for default mode */
3757 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
3758 {
3759 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
3760 pWextState->roamProfile.EncryptionType.encryptionType[0]) &&
3761 (eCSR_ENCRYPT_TYPE_AES !=
3762 pWextState->roamProfile.EncryptionType.encryptionType[0])
3763 )
3764 {
3765 /* Saving key direction for default key index to TX default */
3766 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
3767 pAPCtx->wepKey[key_index].keyDirection = eSIR_TX_DEFAULT;
3768 }
3769 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303770
Jeff Johnson295189b2012-06-20 16:38:30 -07003771 return status;
3772}
3773
Jeff Johnson295189b2012-06-20 16:38:30 -07003774/*
3775 * FUNCTION: wlan_hdd_cfg80211_inform_bss
3776 * This function is used to inform the BSS details to nl80211 interface.
3777 */
3778static struct cfg80211_bss* wlan_hdd_cfg80211_inform_bss(
3779 hdd_adapter_t *pAdapter, tCsrRoamConnectedProfile *roamProfile)
3780{
3781 struct net_device *dev = pAdapter->dev;
3782 struct wireless_dev *wdev = dev->ieee80211_ptr;
3783 struct wiphy *wiphy = wdev->wiphy;
3784 tSirBssDescription *pBssDesc = roamProfile->pBssDesc;
3785 int chan_no;
3786 int ie_length;
3787 const char *ie;
3788 unsigned int freq;
3789 struct ieee80211_channel *chan;
3790 int rssi = 0;
3791 struct cfg80211_bss *bss = NULL;
3792
3793 ENTER();
3794
3795 if( NULL == pBssDesc )
3796 {
3797 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pBssDesc is NULL\n", __func__);
3798 return bss;
3799 }
3800
3801 chan_no = pBssDesc->channelId;
3802 ie_length = GET_IE_LEN_IN_BSS_DESC( pBssDesc->length );
3803 ie = ((ie_length != 0) ? (const char *)&pBssDesc->ieFields: NULL);
3804
3805 if( NULL == ie )
3806 {
3807 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: IE of BSS descriptor is NULL\n", __func__);
3808 return bss;
3809 }
3810
3811#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
3812 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
3813 {
3814 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
3815 }
3816 else
3817 {
3818 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
3819 }
3820#else
3821 freq = ieee80211_channel_to_frequency(chan_no);
3822#endif
3823
3824 chan = __ieee80211_get_channel(wiphy, freq);
3825
3826 bss = cfg80211_get_bss(wiphy, chan, pBssDesc->bssId,
3827 &roamProfile->SSID.ssId[0], roamProfile->SSID.length,
3828 WLAN_CAPABILITY_ESS, WLAN_CAPABILITY_ESS);
3829 if (bss == NULL)
3830 {
3831 rssi = (VOS_MIN ((pBssDesc->rssi + pBssDesc->sinr), 0))*100;
3832
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303833 return (cfg80211_inform_bss(wiphy, chan, pBssDesc->bssId,
3834 le64_to_cpu(*(__le64 *)pBssDesc->timeStamp),
Jeff Johnson295189b2012-06-20 16:38:30 -07003835 pBssDesc->capabilityInfo,
3836 pBssDesc->beaconInterval, ie, ie_length,
3837 rssi, GFP_KERNEL ));
3838}
3839 else
3840 {
3841 return bss;
3842 }
3843}
3844
3845
3846
3847/*
3848 * FUNCTION: wlan_hdd_cfg80211_inform_bss_frame
3849 * This function is used to inform the BSS details to nl80211 interface.
3850 */
3851struct cfg80211_bss*
3852wlan_hdd_cfg80211_inform_bss_frame( hdd_adapter_t *pAdapter,
3853 tSirBssDescription *bss_desc
3854 )
3855{
3856 /*
3857 cfg80211_inform_bss() is not updating ie field of bss entry, if entry
3858 already exists in bss data base of cfg80211 for that particular BSS ID.
3859 Using cfg80211_inform_bss_frame to update the bss entry instead of
3860 cfg80211_inform_bss, But this call expects mgmt packet as input. As of
3861 now there is no possibility to get the mgmt(probe response) frame from PE,
3862 converting bss_desc to ieee80211_mgmt(probe response) and passing to
3863 cfg80211_inform_bss_frame.
3864 */
3865 struct net_device *dev = pAdapter->dev;
3866 struct wireless_dev *wdev = dev->ieee80211_ptr;
3867 struct wiphy *wiphy = wdev->wiphy;
3868 int chan_no = bss_desc->channelId;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08003869#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
3870 qcom_ie_age *qie_age = NULL;
3871 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length ) + sizeof(qcom_ie_age);
3872#else
Jeff Johnson295189b2012-06-20 16:38:30 -07003873 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length );
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08003874#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07003875 const char *ie =
3876 ((ie_length != 0) ? (const char *)&bss_desc->ieFields: NULL);
3877 unsigned int freq;
3878 struct ieee80211_channel *chan;
3879 struct ieee80211_mgmt *mgmt =
3880 kzalloc((sizeof (struct ieee80211_mgmt) + ie_length), GFP_KERNEL);
3881 struct cfg80211_bss *bss_status = NULL;
3882 size_t frame_len = sizeof (struct ieee80211_mgmt) + ie_length;
3883 int rssi = 0;
Jeff Johnsone7245742012-09-05 17:12:55 -07003884#ifdef WLAN_OPEN_SOURCE
3885 struct timespec ts;
3886#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07003887
3888 ENTER();
3889
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -07003890 if (!mgmt)
3891 return NULL;
3892
Jeff Johnson295189b2012-06-20 16:38:30 -07003893 memcpy(mgmt->bssid, bss_desc->bssId, ETH_ALEN);
Jeff Johnsone7245742012-09-05 17:12:55 -07003894
3895#ifdef WLAN_OPEN_SOURCE
3896 /* Android does not want the timestamp from the frame.
3897 Instead it wants a monotonic increasing value */
3898 get_monotonic_boottime(&ts);
3899 mgmt->u.probe_resp.timestamp =
3900 ((u64)ts.tv_sec * 1000000) + (ts.tv_nsec / 1000);
3901#else
3902 /* keep old behavior for non-open source (for now) */
Jeff Johnson295189b2012-06-20 16:38:30 -07003903 memcpy(&mgmt->u.probe_resp.timestamp, bss_desc->timeStamp,
3904 sizeof (bss_desc->timeStamp));
Jeff Johnsone7245742012-09-05 17:12:55 -07003905
3906#endif
3907
Jeff Johnson295189b2012-06-20 16:38:30 -07003908 mgmt->u.probe_resp.beacon_int = bss_desc->beaconInterval;
3909 mgmt->u.probe_resp.capab_info = bss_desc->capabilityInfo;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08003910
3911#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
3912 /* GPS Requirement: need age ie per entry. Using vendor specific. */
3913 /* Assuming this is the last IE, copy at the end */
3914 ie_length -=sizeof(qcom_ie_age);
3915 qie_age = (qcom_ie_age *)(mgmt->u.probe_resp.variable + ie_length);
3916 qie_age->element_id = QCOM_VENDOR_IE_ID;
3917 qie_age->len = QCOM_VENDOR_IE_AGE_LEN;
3918 qie_age->oui_1 = QCOM_OUI1;
3919 qie_age->oui_2 = QCOM_OUI2;
3920 qie_age->oui_3 = QCOM_OUI3;
3921 qie_age->type = QCOM_VENDOR_IE_AGE_TYPE;
3922 qie_age->age = vos_timer_get_system_ticks() - bss_desc->nReceivedTime;
3923#endif
3924
Jeff Johnson295189b2012-06-20 16:38:30 -07003925 memcpy(mgmt->u.probe_resp.variable, ie, ie_length);
3926
3927 mgmt->frame_control |=
3928 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_RESP);
3929
3930#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303931 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ) &&
Jeff Johnson295189b2012-06-20 16:38:30 -07003932 (wiphy->bands[IEEE80211_BAND_2GHZ] != NULL))
3933 {
3934 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
3935 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303936 else if ((chan_no > ARRAY_SIZE(hdd_channels_2_4_GHZ)) &&
Jeff Johnson295189b2012-06-20 16:38:30 -07003937 (wiphy->bands[IEEE80211_BAND_5GHZ] != NULL))
3938
3939 {
3940 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
3941 }
3942 else
3943 {
3944 kfree(mgmt);
3945 return NULL;
3946 }
3947#else
3948 freq = ieee80211_channel_to_frequency(chan_no);
3949#endif
3950 chan = __ieee80211_get_channel(wiphy, freq);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -08003951 /*when the band is changed on the fly using the GUI, three things are done
3952 * 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)
3953 * as part of the scan abort, message willbe queued to PE and we proceed with flushing and changinh the band.
3954 * pe will stop the scanning further and report back the results what ever it had till now by calling the call back function.
3955 * if the time between update band and scandone call back is sufficent enough the band change reflects in SME, SME validates the channels
3956 * and discards the channels correponding to previous band and calls back with zero bss results.
3957 * 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
3958 * all the channels correponding to previous band.this is due to race condition.but those channels are invalid to the new band and so
3959 * this function __ieee80211_get_channel will return NULL.Each time we report scan result with this pointer null warning kernel trace is printed.
3960 * if the scan results contain large number of APs continuosly kernel warning trace is printed and it will lead to apps watch dog bark.
3961 * So drop the bss and continue to next bss.
3962 */
3963 if(chan == NULL)
3964 {
3965 hddLog(VOS_TRACE_LEVEL_INFO, "%s chan pointer is NULL", __func__);
Chilam Ngc4244af2013-04-01 15:37:32 -07003966 kfree(mgmt);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -08003967 return NULL;
3968 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003969 /*To keep the rssi icon of the connected AP in the scan window
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303970 *and the rssi icon of the wireless networks in sync
Jeff Johnson295189b2012-06-20 16:38:30 -07003971 * */
3972 if (( eConnectionState_Associated ==
3973 pAdapter->sessionCtx.station.conn_info.connState ) &&
3974 ( VOS_TRUE == vos_mem_compare(bss_desc->bssId,
3975 pAdapter->sessionCtx.station.conn_info.bssId,
3976 WNI_CFG_BSSID_LEN)))
3977 {
3978 /* supplicant takes the signal strength in terms of mBm(100*dBm) */
3979 rssi = (pAdapter->rssi * 100);
3980 }
3981 else
3982 {
3983 rssi = (VOS_MIN ((bss_desc->rssi + bss_desc->sinr), 0))*100;
3984 }
3985
3986 bss_status = cfg80211_inform_bss_frame(wiphy, chan, mgmt,
3987 frame_len, rssi, GFP_KERNEL);
3988 kfree(mgmt);
3989 return bss_status;
3990}
3991
3992/*
3993 * FUNCTION: wlan_hdd_cfg80211_update_bss_db
3994 * This function is used to update the BSS data base of CFG8011
3995 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303996struct cfg80211_bss* wlan_hdd_cfg80211_update_bss_db( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07003997 tCsrRoamInfo *pRoamInfo
3998 )
3999{
4000 tCsrRoamConnectedProfile roamProfile;
4001 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
4002 struct cfg80211_bss *bss = NULL;
4003
4004 ENTER();
4005
4006 memset(&roamProfile, 0, sizeof(tCsrRoamConnectedProfile));
4007 sme_RoamGetConnectProfile(hHal, pAdapter->sessionId, &roamProfile);
4008
4009 if (NULL != roamProfile.pBssDesc)
4010 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304011 bss = wlan_hdd_cfg80211_inform_bss(pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07004012 &roamProfile);
4013
4014 if (NULL == bss)
4015 {
4016 hddLog(VOS_TRACE_LEVEL_INFO, "%s: cfg80211_inform_bss return NULL",
4017 __func__);
4018 }
4019
4020 sme_RoamFreeConnectProfile(hHal, &roamProfile);
4021 }
4022 else
4023 {
4024 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: roamProfile.pBssDesc is NULL",
4025 __func__);
4026 }
4027 return bss;
4028}
4029
4030/*
4031 * FUNCTION: wlan_hdd_cfg80211_update_bss
4032 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304033static int wlan_hdd_cfg80211_update_bss( struct wiphy *wiphy,
4034 hdd_adapter_t *pAdapter
Jeff Johnson295189b2012-06-20 16:38:30 -07004035 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304036{
Jeff Johnson295189b2012-06-20 16:38:30 -07004037 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
4038 tCsrScanResultInfo *pScanResult;
4039 eHalStatus status = 0;
4040 tScanResultHandle pResult;
4041 struct cfg80211_bss *bss_status = NULL;
4042
4043 ENTER();
4044
4045 if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress)
4046 {
4047 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:LOGP in Progress. Ignore!!!",__func__);
4048 return -EAGAIN;
4049 }
4050
4051 /*
4052 * start getting scan results and populate cgf80211 BSS database
4053 */
4054 status = sme_ScanGetResult(hHal, pAdapter->sessionId, NULL, &pResult);
4055
4056 /* no scan results */
4057 if (NULL == pResult)
4058 {
4059 hddLog(VOS_TRACE_LEVEL_INFO, "%s: No scan result\n", __func__);
4060 return status;
4061 }
4062
4063 pScanResult = sme_ScanResultGetFirst(hHal, pResult);
4064
4065 while (pScanResult)
4066 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304067 /*
4068 * cfg80211_inform_bss() is not updating ie field of bss entry, if
4069 * entry already exists in bss data base of cfg80211 for that
4070 * particular BSS ID. Using cfg80211_inform_bss_frame to update the
4071 * bss entry instead of cfg80211_inform_bss, But this call expects
4072 * mgmt packet as input. As of now there is no possibility to get
4073 * the mgmt(probe response) frame from PE, converting bss_desc to
Jeff Johnson295189b2012-06-20 16:38:30 -07004074 * ieee80211_mgmt(probe response) and passing to c
4075 * fg80211_inform_bss_frame.
4076 * */
4077
4078 bss_status = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
4079 &pScanResult->BssDescriptor);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304080
Jeff Johnson295189b2012-06-20 16:38:30 -07004081
4082 if (NULL == bss_status)
4083 {
4084 hddLog(VOS_TRACE_LEVEL_INFO,
4085 "%s: NULL returned by cfg80211_inform_bss\n", __func__);
4086 }
4087 else
4088 {
4089 cfg80211_put_bss(bss_status);
4090 }
4091
4092 pScanResult = sme_ScanResultGetNext(hHal, pResult);
4093 }
4094
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304095 sme_ScanResultPurge(hHal, pResult);
Jeff Johnson295189b2012-06-20 16:38:30 -07004096
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304097 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07004098}
4099
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004100void
4101hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel)
4102{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304103 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07004104 "%02X:%02X:%02X:%02X:%02X:%02X\n",
4105 macAddr[0], macAddr[1], macAddr[2], macAddr[3], macAddr[4],
4106 macAddr[5]);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004107} /****** end hddPrintMacAddr() ******/
4108
4109void
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07004110hddPrintPmkId(tANI_U8 *pmkId, tANI_U8 logLevel)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004111{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304112 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07004113 "%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X\n",
4114 pmkId[0], pmkId[1], pmkId[2], pmkId[3], pmkId[4],
4115 pmkId[5], pmkId[6], pmkId[7], pmkId[8], pmkId[9], pmkId[10],
4116 pmkId[11], pmkId[12], pmkId[13], pmkId[14], pmkId[15]);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004117} /****** end hddPrintPmkId() ******/
4118
4119//hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel);
4120//hddPrintMacAddr(macAddr, VOS_TRACE_LEVEL_FATAL);
4121
4122//void sirDumpBuf(tpAniSirGlobal pMac, tANI_U8 modId, tANI_U32 level, tANI_U8 *buf, tANI_U32 size);
4123//sirDumpBuf(pMac, VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, pmkid, 16);
4124
4125#define dump_bssid(bssid) \
4126 { \
Jeff Johnsone7245742012-09-05 17:12:55 -07004127 hddLog(VOS_TRACE_LEVEL_INFO, "BSSID (MAC) address:\t"); \
4128 hddPrintMacAddr(bssid, VOS_TRACE_LEVEL_INFO);\
4129 hddLog(VOS_TRACE_LEVEL_INFO, "\n"); \
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004130 }
4131
4132#define dump_pmkid(pMac, pmkid) \
4133 { \
Jeff Johnsone7245742012-09-05 17:12:55 -07004134 hddLog(VOS_TRACE_LEVEL_INFO, "PMKSA-ID:\t"); \
4135 hddPrintPmkId(pmkid, VOS_TRACE_LEVEL_INFO);\
4136 hddLog(VOS_TRACE_LEVEL_INFO, "\n"); \
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004137 }
4138
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -07004139#if defined(FEATURE_WLAN_LFR) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004140/*
4141 * FUNCTION: wlan_hdd_cfg80211_pmksa_candidate_notify
4142 * This function is used to notify the supplicant of a new PMKSA candidate.
4143 */
4144int wlan_hdd_cfg80211_pmksa_candidate_notify(
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304145 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004146 int index, bool preauth )
4147{
Jeff Johnsone7245742012-09-05 17:12:55 -07004148#ifdef FEATURE_WLAN_OKC
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004149 struct net_device *dev = pAdapter->dev;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004150 hdd_context_t *pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004151
4152 ENTER();
Jeff Johnsone7245742012-09-05 17:12:55 -07004153 hddLog(VOS_TRACE_LEVEL_INFO, "%s is going to notify supplicant of:", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004154
4155 if( NULL == pRoamInfo )
4156 {
4157 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pRoamInfo is NULL\n", __func__);
4158 return -EINVAL;
4159 }
4160
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004161 if (eANI_BOOLEAN_TRUE == hdd_is_okc_mode_enabled(pHddCtx))
4162 {
4163 dump_bssid(pRoamInfo->bssid);
4164 cfg80211_pmksa_candidate_notify(dev, index,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004165 pRoamInfo->bssid, preauth, GFP_KERNEL);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004166 }
Jeff Johnsone7245742012-09-05 17:12:55 -07004167#endif /* FEATURE_WLAN_OKC */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304168 return 0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004169}
4170#endif //FEATURE_WLAN_LFR
4171
Jeff Johnson295189b2012-06-20 16:38:30 -07004172/*
4173 * FUNCTION: hdd_cfg80211_scan_done_callback
4174 * scanning callback function, called after finishing scan
4175 *
4176 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304177static eHalStatus hdd_cfg80211_scan_done_callback(tHalHandle halHandle,
Jeff Johnson295189b2012-06-20 16:38:30 -07004178 void *pContext, tANI_U32 scanId, eCsrScanStatus status)
4179{
4180 struct net_device *dev = (struct net_device *) pContext;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304181 //struct wireless_dev *wdev = dev->ieee80211_ptr;
Jeff Johnson295189b2012-06-20 16:38:30 -07004182 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07004183 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
4184 hdd_scaninfo_t *pScanInfo = &pHddCtx->scan_info;
Jeff Johnson295189b2012-06-20 16:38:30 -07004185 struct cfg80211_scan_request *req = NULL;
4186 int ret = 0;
4187
4188 ENTER();
4189
4190 hddLog(VOS_TRACE_LEVEL_INFO,
4191 "%s called with halHandle = %p, pContext = %p,"
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304192 "scanID = %d, returned status = %d\n",
Jeff Johnson295189b2012-06-20 16:38:30 -07004193 __func__, halHandle, pContext, (int) scanId, (int) status);
4194
4195 //Block on scan req completion variable. Can't wait forever though.
4196 ret = wait_for_completion_interruptible_timeout(
4197 &pScanInfo->scan_req_completion_event,
4198 msecs_to_jiffies(WLAN_WAIT_TIME_SCAN_REQ));
4199 if (!ret)
4200 {
4201 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -07004202 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -07004203 }
4204
4205 if(pScanInfo->mScanPending != VOS_TRUE)
4206 {
4207 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -07004208 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -07004209 }
4210
4211 /* Check the scanId */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304212 if (pScanInfo->scanId != scanId)
Jeff Johnson295189b2012-06-20 16:38:30 -07004213 {
4214 hddLog(VOS_TRACE_LEVEL_INFO,
4215 "%s called with mismatched scanId pScanInfo->scanId = %d "
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304216 "scanId = %d \n", __func__, (int) pScanInfo->scanId,
Jeff Johnson295189b2012-06-20 16:38:30 -07004217 (int) scanId);
4218 }
4219
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304220 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07004221 pAdapter);
4222
4223 if (0 > ret)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304224 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004225
4226
4227 /* If any client wait scan result through WEXT
4228 * send scan done event to client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07004229 if (pHddCtx->scan_info.waitScanResult)
Jeff Johnson295189b2012-06-20 16:38:30 -07004230 {
4231 /* The other scan request waiting for current scan finish
4232 * Send event to notify current scan finished */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07004233 if(WEXT_SCAN_PENDING_DELAY == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -07004234 {
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07004235 vos_event_set(&pHddCtx->scan_info.scan_finished_event);
Jeff Johnson295189b2012-06-20 16:38:30 -07004236 }
4237 /* Send notify to WEXT client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07004238 else if(WEXT_SCAN_PENDING_PIGGYBACK == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -07004239 {
4240 struct net_device *dev = pAdapter->dev;
4241 union iwreq_data wrqu;
4242 int we_event;
4243 char *msg;
4244
4245 memset(&wrqu, '\0', sizeof(wrqu));
4246 we_event = SIOCGIWSCAN;
4247 msg = NULL;
4248 wireless_send_event(dev, we_event, &wrqu, msg);
4249 }
4250 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07004251 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07004252
4253 /* Get the Scan Req */
4254 req = pAdapter->request;
4255
4256 if (!req)
4257 {
4258 hddLog(VOS_TRACE_LEVEL_ERROR, "request is became NULL\n");
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07004259 pScanInfo->mScanPending = VOS_FALSE;
Jeff Johnsone7245742012-09-05 17:12:55 -07004260 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -07004261 }
4262
4263 /*
4264 * setting up 0, just in case.
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304265 */
Jeff Johnson295189b2012-06-20 16:38:30 -07004266 req->n_ssids = 0;
4267 req->n_channels = 0;
4268 req->ie = 0;
4269
Jeff Johnson295189b2012-06-20 16:38:30 -07004270 pAdapter->request = NULL;
Jeff Johnsone7245742012-09-05 17:12:55 -07004271 /* Scan is no longer pending */
4272 pScanInfo->mScanPending = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07004273
Madan Mohan Koyyalamudib764bf82012-10-11 16:38:51 -07004274 /*
4275 * cfg80211_scan_done informing NL80211 about completion
4276 * of scanning
4277 */
4278 cfg80211_scan_done(req, false);
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -08004279 complete(&pScanInfo->abortscan_event_var);
Jeff Johnson295189b2012-06-20 16:38:30 -07004280
Jeff Johnsone7245742012-09-05 17:12:55 -07004281allow_suspend:
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07004282 /* release the wake lock at the end of the scan*/
4283 hdd_allow_suspend();
Jeff Johnsone7245742012-09-05 17:12:55 -07004284
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -07004285 /* Acquire wakelock to handle the case where APP's tries to suspend
4286 * immediatly after the driver gets connect request(i.e after scan)
4287 * from supplicant, this result in app's is suspending and not able
4288 * to process the connect request to AP */
4289 hdd_allow_suspend_timeout(100);
4290
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07004291#ifdef FEATURE_WLAN_TDLS
4292 wlan_hdd_tdls_scan_done_callback(pAdapter);
4293#endif
4294
Jeff Johnson295189b2012-06-20 16:38:30 -07004295 EXIT();
4296 return 0;
4297}
4298
4299/*
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08004300 * FUNCTION: hdd_isScanAllowed
4301 * Go through each adapter and check if scan allowed
4302 *
4303 */
4304v_BOOL_t hdd_isScanAllowed( hdd_context_t *pHddCtx )
4305{
4306 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
4307 hdd_station_ctx_t *pHddStaCtx = NULL;
4308 hdd_adapter_t *pAdapter = NULL;
4309 VOS_STATUS status = 0;
4310 v_U8_t staId = 0;
4311 v_U8_t *staMac = NULL;
4312
4313 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
4314
4315 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
4316 {
4317 pAdapter = pAdapterNode->pAdapter;
4318
4319 if( pAdapter )
4320 {
4321 hddLog(VOS_TRACE_LEVEL_INFO,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304322 "%s: Adapter with device mode %d exists",
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08004323 __func__, pAdapter->device_mode);
4324 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
4325 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
4326 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
4327 {
4328 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4329 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
4330 (VOS_FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
4331 {
4332 staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]);
4333 hddLog(VOS_TRACE_LEVEL_ERROR,
4334 "%s: client %02x:%02x:%02x:%02x:%02x:%02x is in the "
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304335 "middle of WPS/EAPOL exchange.", __func__,
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08004336 staMac[0], staMac[1], staMac[2],
4337 staMac[3], staMac[4], staMac[5]);
4338 return VOS_FALSE;
4339 }
4340 }
4341 else if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) ||
4342 (WLAN_HDD_P2P_GO == pAdapter->device_mode))
4343 {
4344 for (staId = 0; staId < WLAN_MAX_STA_COUNT; staId++)
4345 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304346 if ((pAdapter->aStaInfo[staId].isUsed) &&
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08004347 (WLANTL_STA_CONNECTED == pAdapter->aStaInfo[staId].tlSTAState))
4348 {
4349 staMac = (v_U8_t *) &(pAdapter->aStaInfo[staId].macAddrSTA.bytes[0]);
4350
4351 hddLog(VOS_TRACE_LEVEL_ERROR,
4352 "%s: client %02x:%02x:%02x:%02x:%02x:%02x of SoftAP/P2P-GO is in the "
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304353 "middle of WPS/EAPOL exchange.", __func__,
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08004354 staMac[0], staMac[1], staMac[2],
4355 staMac[3], staMac[4], staMac[5]);
4356 return VOS_FALSE;
4357 }
4358 }
4359 }
4360 }
4361 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
4362 pAdapterNode = pNext;
4363 }
4364 hddLog(VOS_TRACE_LEVEL_INFO,
4365 "%s: Scan allowed", __func__);
4366 return VOS_TRUE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304367}
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08004368
4369/*
Jeff Johnson295189b2012-06-20 16:38:30 -07004370 * FUNCTION: wlan_hdd_cfg80211_scan
4371 * this scan respond to scan trigger and update cfg80211 scan database
4372 * later, scan dump command can be used to recieve scan results
4373 */
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -08004374int wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
4375#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
4376 struct net_device *dev,
4377#endif
4378 struct cfg80211_scan_request *request)
4379{
4380#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
4381 struct net_device *dev = request->wdev->netdev;
4382#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304383 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Jeff Johnson295189b2012-06-20 16:38:30 -07004384 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
4385 hdd_wext_state_t *pwextBuf = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
4386 hdd_config_t *cfg_param = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
4387 tCsrScanRequest scanRequest;
4388 tANI_U8 *channelList = NULL, i;
4389 v_U32_t scanId = 0;
4390 int status = 0;
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07004391 hdd_scaninfo_t *pScanInfo = &pHddCtx->scan_info;
Jeff Johnson295189b2012-06-20 16:38:30 -07004392 v_U8_t* pP2pIe = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07004393
4394 ENTER();
4395
4396 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",
4397 __func__,pAdapter->device_mode);
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08004398
Gopichand Nakkala681989c2013-03-06 22:27:48 -08004399 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08004400 (eConnectionState_Connecting ==
Gopichand Nakkala681989c2013-03-06 22:27:48 -08004401 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08004402 {
4403 hddLog(VOS_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08004404 "%s: %p(%d) Connection in progress: Scan request denied (EBUSY)", __func__, \
4405 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08004406 return -EBUSY;
4407 }
4408
Jeff Johnson295189b2012-06-20 16:38:30 -07004409#ifdef WLAN_BTAMP_FEATURE
4410 //Scan not supported when AMP traffic is on.
Gopichand Nakkala681989c2013-03-06 22:27:48 -08004411 if (VOS_TRUE == WLANBAP_AmpSessionOn())
Jeff Johnson295189b2012-06-20 16:38:30 -07004412 {
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08004413 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07004414 "%s: No scanning when AMP is on", __func__);
4415 return -EOPNOTSUPP;
4416 }
4417#endif
4418 //Scan on any other interface is not supported.
Gopichand Nakkala681989c2013-03-06 22:27:48 -08004419 if (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07004420 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -08004421 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07004422 "%s: Not scanning on device_mode = %d",
4423 __func__, pAdapter->device_mode);
4424 return -EOPNOTSUPP;
4425 }
4426
4427 if (TRUE == pScanInfo->mScanPending)
4428 {
4429 hddLog(VOS_TRACE_LEVEL_INFO, "%s: mScanPending is TRUE", __func__);
Gopichand Nakkala681989c2013-03-06 22:27:48 -08004430 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -07004431 }
4432
4433 if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress)
4434 {
4435 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
4436 "%s:LOGP in Progress. Ignore!!!", __func__);
4437 return -EAGAIN;
4438 }
4439
Mohit Khanna6c52bbf2012-09-11 15:10:12 -07004440 if ((WLAN_HDD_GET_CTX(pAdapter))->isLoadUnloadInProgress)
4441 {
4442 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
4443 "%s:Unloading/Loading in Progress. Ignore!!!", __func__);
4444 return -EAGAIN;
4445 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304446 //Don't Allow Scan and return busy if Remain On
Jeff Johnson32d95a32012-09-10 13:15:23 -07004447 //Channel and action frame is pending
4448 //Otherwise Cancel Remain On Channel and allow Scan
4449 //If no action frame pending
Gopichand Nakkala681989c2013-03-06 22:27:48 -08004450 if (0 != wlan_hdd_check_remain_on_channel(pAdapter))
Jeff Johnson32d95a32012-09-10 13:15:23 -07004451 {
4452 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Remain On Channel Pending", __func__);
4453 return -EBUSY;
4454 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08004455#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07004456 /* if tdls disagree scan right now, return immediately.
4457 tdls will schedule the scan when scan is allowed. (return SUCCESS)
4458 or will reject the scan if any TDLS is in progress. (return -EBUSY)
4459 */
4460 status = wlan_hdd_tdls_scan_callback (pAdapter,
4461 wiphy,
4462#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
4463 dev,
Gopichand Nakkalac3c42b92013-03-20 19:42:34 -07004464#endif
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07004465 request);
4466 if(status <= 0)
4467 {
4468 hddLog(VOS_TRACE_LEVEL_INFO, "%s: TDLS Pending %d", __func__, status);
4469 return status;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08004470 }
4471#endif
Jeff Johnson32d95a32012-09-10 13:15:23 -07004472
Jeff Johnson295189b2012-06-20 16:38:30 -07004473 if (mutex_lock_interruptible(&pHddCtx->tmInfo.tmOperationLock))
4474 {
4475 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_ERROR,
Jeff Johnson1250df42012-12-10 14:31:52 -08004476 "%s: Acquire lock fail", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004477 return -EAGAIN;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304478 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004479 if (TRUE == pHddCtx->tmInfo.tmAction.enterImps)
4480 {
4481 hddLog(VOS_TRACE_LEVEL_WARN,
4482 "%s: MAX TM Level Scan not allowed", __func__);
4483 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304484 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -07004485 }
4486 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
4487
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08004488 /* Check if scan is allowed at this point of time.
4489 */
4490 if (!hdd_isScanAllowed(pHddCtx))
4491 {
4492 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Scan not allowed", __func__);
4493 return -EBUSY;
4494 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304495
Jeff Johnson295189b2012-06-20 16:38:30 -07004496 vos_mem_zero( &scanRequest, sizeof(scanRequest));
4497
4498 if (NULL != request)
4499 {
4500 hddLog(VOS_TRACE_LEVEL_INFO, "scan request for ssid = %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304501 (int)request->n_ssids);
Jeff Johnson295189b2012-06-20 16:38:30 -07004502
4503 /* Even though supplicant doesn't provide any SSIDs, n_ssids is set to 1.
4504 * Becasue of this, driver is assuming that this is not wildcard scan and so
4505 * is not aging out the scan results.
4506 */
Jeff Johnson32d95a32012-09-10 13:15:23 -07004507 if (request->ssids && '\0' == request->ssids->ssid[0])
Jeff Johnson295189b2012-06-20 16:38:30 -07004508 {
4509 request->n_ssids = 0;
4510 }
4511
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07004512 if ((request->ssids) && (0 < request->n_ssids))
Jeff Johnson295189b2012-06-20 16:38:30 -07004513 {
4514 tCsrSSIDInfo *SsidInfo;
4515 int j;
4516 scanRequest.SSIDs.numOfSSIDs = request->n_ssids;
4517 /* Allocate num_ssid tCsrSSIDInfo structure */
4518 SsidInfo = scanRequest.SSIDs.SSIDList =
4519 ( tCsrSSIDInfo *)vos_mem_malloc(
4520 request->n_ssids*sizeof(tCsrSSIDInfo));
4521
4522 if(NULL == scanRequest.SSIDs.SSIDList)
4523 {
4524 hddLog(VOS_TRACE_LEVEL_ERROR,
4525 "memory alloc failed SSIDInfo buffer");
4526 return -ENOMEM;
4527 }
4528
4529 /* copy all the ssid's and their length */
4530 for(j = 0; j < request->n_ssids; j++, SsidInfo++)
4531 {
4532 /* get the ssid length */
4533 SsidInfo->SSID.length = request->ssids[j].ssid_len;
4534 vos_mem_copy(SsidInfo->SSID.ssId, &request->ssids[j].ssid[0],
4535 SsidInfo->SSID.length);
4536 SsidInfo->SSID.ssId[SsidInfo->SSID.length] = '\0';
4537 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "SSID number %d: %s",
4538 j, SsidInfo->SSID.ssId);
4539 }
4540 /* set the scan type to active */
4541 scanRequest.scanType = eSIR_ACTIVE_SCAN;
4542 }
4543 else if(WLAN_HDD_P2P_GO == pAdapter->device_mode)
4544 {
4545 /* set the scan type to active */
4546 scanRequest.scanType = eSIR_ACTIVE_SCAN;
4547 }
4548 else
4549 {
4550 /*Set the scan type to default type, in this case it is ACTIVE*/
4551 scanRequest.scanType = pScanInfo->scan_mode;
4552 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304553 scanRequest.minChnTime = cfg_param->nActiveMinChnTime;
Jeff Johnson295189b2012-06-20 16:38:30 -07004554 scanRequest.maxChnTime = cfg_param->nActiveMaxChnTime;
4555 }
4556 else
4557 {
4558 /* set the scan type to active */
4559 scanRequest.scanType = eSIR_ACTIVE_SCAN;
4560 vos_mem_set( scanRequest.bssid, sizeof( tCsrBssid ), 0xff );
4561
4562 /* set min and max channel time to zero */
4563 scanRequest.minChnTime = 0;
4564 scanRequest.maxChnTime = 0;
4565 }
4566
4567 /* set BSSType to default type */
4568 scanRequest.BSSType = eCSR_BSS_TYPE_ANY;
4569
4570 /*TODO: scan the requested channels only*/
4571
4572 /*Right now scanning all the channels */
4573 if( request )
4574 {
4575 if( request->n_channels )
4576 {
4577 channelList = vos_mem_malloc( request->n_channels );
4578 if( NULL == channelList )
4579 {
4580 status = -ENOMEM;
4581 goto free_mem;
4582 }
4583
4584 for( i = 0 ; i < request->n_channels ; i++ )
4585 channelList[i] = request->channels[i]->hw_value;
4586 }
4587
4588 scanRequest.ChannelInfo.numOfChannels = request->n_channels;
4589 scanRequest.ChannelInfo.ChannelList = channelList;
4590
4591 /* set requestType to full scan */
4592 scanRequest.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304593
4594 /* Flush the scan results(only p2p beacons) for STA scan and P2P
Madan Mohan Koyyalamudi8d50f312012-11-27 15:48:57 -08004595 * search (Flush on both full scan and social scan but not on single
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304596 * channel scan).P2P search happens on 3 social channels (1, 6, 11)
Madan Mohan Koyyalamudi8d50f312012-11-27 15:48:57 -08004597 */
4598
4599 /* Supplicant does single channel scan after 8-way handshake
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304600 * and in that case driver shoudnt flush scan results. If
4601 * driver flushes the scan results here and unfortunately if
4602 * the AP doesnt respond to our probe req then association
Madan Mohan Koyyalamudi8d50f312012-11-27 15:48:57 -08004603 * fails which is not desired
4604 */
4605
4606 if( request->n_channels != WLAN_HDD_P2P_SINGLE_CHANNEL_SCAN )
4607 {
4608 sme_ScanFlushP2PResult( WLAN_HDD_GET_HAL_CTX(pAdapter),
4609 pAdapter->sessionId );
4610 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004611
4612 if( request->ie_len )
4613 {
4614 /* save this for future association (join requires this) */
4615 memset( &pScanInfo->scanAddIE, 0, sizeof(pScanInfo->scanAddIE) );
4616 memcpy( pScanInfo->scanAddIE.addIEdata, request->ie, request->ie_len);
4617 pScanInfo->scanAddIE.length = request->ie_len;
4618
4619 if((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Jeff Johnsone7245742012-09-05 17:12:55 -07004620 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
4621 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -07004622 )
4623 {
4624 pwextBuf->roamProfile.pAddIEScan = pScanInfo->scanAddIE.addIEdata;
4625 pwextBuf->roamProfile.nAddIEScanLength = pScanInfo->scanAddIE.length;
4626 }
4627
4628 scanRequest.uIEFieldLen = pScanInfo->scanAddIE.length;
4629 scanRequest.pIEField = pScanInfo->scanAddIE.addIEdata;
4630
Jeff Johnson295189b2012-06-20 16:38:30 -07004631 pP2pIe = wlan_hdd_get_p2p_ie_ptr((v_U8_t*)request->ie,
4632 request->ie_len);
4633 if (pP2pIe != NULL)
4634 {
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07004635#ifdef WLAN_FEATURE_P2P_DEBUG
4636 if (((globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED) ||
4637 (globalP2PConnectionStatus == P2P_GO_NEG_PROCESS)) &&
4638 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
4639 {
4640 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_1;
4641 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
4642 "Go nego completed to Connection is started");
4643 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
4644 "for 8way Handshake");
4645 }
4646 else if((globalP2PConnectionStatus == P2P_CLIENT_DISCONNECTED_STATE) &&
4647 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
4648 {
4649 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_2;
4650 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
4651 "Disconnected state to Connection is started");
4652 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
4653 "for 4way Handshake");
4654 }
4655#endif
4656
Jeff Johnsone7245742012-09-05 17:12:55 -07004657 /* no_cck will be set during p2p find to disable 11b rates */
4658 if(TRUE == request->no_cck)
Jeff Johnson295189b2012-06-20 16:38:30 -07004659 {
Jeff Johnson295189b2012-06-20 16:38:30 -07004660 hddLog(VOS_TRACE_LEVEL_INFO,
4661 "%s: This is a P2P Search", __func__);
4662 scanRequest.p2pSearch = 1;
Jeff Johnsone7245742012-09-05 17:12:55 -07004663
Jeff Johnsone7245742012-09-05 17:12:55 -07004664 if( request->n_channels == WLAN_HDD_P2P_SOCIAL_CHANNELS )
4665 {
Madan Mohan Koyyalamudi1b1d9e82012-10-21 11:38:33 -07004666 /* set requestType to P2P Discovery */
4667 scanRequest.requestType = eCSR_SCAN_P2P_DISCOVERY;
Jeff Johnsone7245742012-09-05 17:12:55 -07004668 }
4669
4670 /*
4671 Skip Dfs Channel in case of P2P Search
4672 if it is set in ini file
4673 */
4674 if(cfg_param->skipDfsChnlInP2pSearch)
4675 {
4676 scanRequest.skipDfsChnlInP2pSearch = 1;
4677 }
4678 else
4679 {
4680 scanRequest.skipDfsChnlInP2pSearch = 0;
4681 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004682
Jeff Johnson295189b2012-06-20 16:38:30 -07004683 }
4684 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004685 }
4686 }
4687
4688 INIT_COMPLETION(pScanInfo->scan_req_completion_event);
4689
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07004690 /* acquire the wakelock to avoid the apps suspend during the scan. To
4691 * address the following issues.
4692 * 1) Disconnected scenario: we are not allowing the suspend as WLAN is not in
4693 * BMPS/IMPS this result in android trying to suspend aggressively and backing off
4694 * for long time, this result in apps running at full power for long time.
4695 * 2) Connected scenario: If we allow the suspend during the scan, RIVA will
4696 * be stuck in full power because of resume BMPS
4697 */
4698 hdd_prevent_suspend();
Jeff Johnsone7245742012-09-05 17:12:55 -07004699
4700 status = sme_ScanRequest( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07004701 pAdapter->sessionId, &scanRequest, &scanId,
4702 &hdd_cfg80211_scan_done_callback, dev );
Jeff Johnsone7245742012-09-05 17:12:55 -07004703
Jeff Johnson295189b2012-06-20 16:38:30 -07004704 if (eHAL_STATUS_SUCCESS != status)
4705 {
4706 hddLog(VOS_TRACE_LEVEL_ERROR,
4707 "%s: sme_ScanRequest returned error %d", __func__, status);
4708 complete(&pScanInfo->scan_req_completion_event);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -07004709 if(eHAL_STATUS_RESOURCES == status)
4710 {
Madan Mohan Koyyalamudia3fcf142012-10-18 15:01:20 -07004711 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 -07004712 status = -EBUSY;
4713 } else {
4714 status = -EIO;
4715 }
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07004716 hdd_allow_suspend();
Jeff Johnson295189b2012-06-20 16:38:30 -07004717 goto free_mem;
4718 }
4719
4720 pScanInfo->mScanPending = TRUE;
4721 pAdapter->request = request;
4722 pScanInfo->scanId = scanId;
4723
4724 complete(&pScanInfo->scan_req_completion_event);
4725
4726free_mem:
4727 if( scanRequest.SSIDs.SSIDList )
4728 {
4729 vos_mem_free(scanRequest.SSIDs.SSIDList);
4730 }
4731
4732 if( channelList )
4733 vos_mem_free( channelList );
4734
4735 EXIT();
4736
4737 return status;
4738}
4739
4740/*
4741 * FUNCTION: wlan_hdd_cfg80211_connect_start
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304742 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -07004743 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304744int wlan_hdd_cfg80211_connect_start( hdd_adapter_t *pAdapter,
Jeff Johnson32d95a32012-09-10 13:15:23 -07004745 const u8 *ssid, size_t ssid_len, const u8 *bssid, u8 operatingChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -07004746{
4747 int status = 0;
4748 hdd_wext_state_t *pWextState;
4749 v_U32_t roamId;
4750 tCsrRoamProfile *pRoamProfile;
4751 eMib_dot11DesiredBssType connectedBssType;
4752 eCsrAuthType RSNAuthType;
4753
4754 ENTER();
4755
4756 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304757
Jeff Johnson295189b2012-06-20 16:38:30 -07004758 if (SIR_MAC_MAX_SSID_LENGTH < ssid_len)
4759 {
4760 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wrong SSID len", __func__);
4761 return -EINVAL;
4762 }
4763
4764 pRoamProfile = &pWextState->roamProfile;
4765
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304766 if (pRoamProfile)
Jeff Johnson295189b2012-06-20 16:38:30 -07004767 {
Jeff Johnsone7245742012-09-05 17:12:55 -07004768 int ret = 0;
4769 hdd_station_ctx_t *pHddStaCtx;
4770 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4771 hdd_connGetConnectedBssType(pHddStaCtx,&connectedBssType );
4772
4773 if((eMib_dot11DesiredBssType_independent == connectedBssType) ||
4774 (eConnectionState_Associated == pHddStaCtx->conn_info.connState) ||
4775 (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState))
Jeff Johnson295189b2012-06-20 16:38:30 -07004776 {
4777 /* Issue disconnect to CSR */
4778 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304779 if( eHAL_STATUS_SUCCESS ==
Jeff Johnson295189b2012-06-20 16:38:30 -07004780 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
4781 pAdapter->sessionId,
4782 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
4783 {
Jeff Johnsone7245742012-09-05 17:12:55 -07004784 ret = wait_for_completion_interruptible_timeout(
4785 &pAdapter->disconnect_comp_var,
4786 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
4787 if (0 == ret)
4788 {
4789 VOS_ASSERT(0);
4790 }
4791 }
4792 }
4793 else if(eConnectionState_Disconnecting == pHddStaCtx->conn_info.connState)
4794 {
4795 ret = wait_for_completion_interruptible_timeout(
4796 &pAdapter->disconnect_comp_var,
4797 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
4798 if (0 == ret)
4799 {
4800 VOS_ASSERT(0);
Jeff Johnson295189b2012-06-20 16:38:30 -07004801 }
4802 }
4803
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304804 if (HDD_WMM_USER_MODE_NO_QOS ==
Jeff Johnson295189b2012-06-20 16:38:30 -07004805 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->WmmMode)
4806 {
4807 /*QoS not enabled in cfg file*/
4808 pRoamProfile->uapsd_mask = 0;
4809 }
4810 else
4811 {
4812 /*QoS enabled, update uapsd mask from cfg file*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304813 pRoamProfile->uapsd_mask =
Jeff Johnson295189b2012-06-20 16:38:30 -07004814 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask;
4815 }
4816
4817 pRoamProfile->SSIDs.numOfSSIDs = 1;
4818 pRoamProfile->SSIDs.SSIDList->SSID.length = ssid_len;
4819 vos_mem_zero(pRoamProfile->SSIDs.SSIDList->SSID.ssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304820 sizeof(pRoamProfile->SSIDs.SSIDList->SSID.ssId));
Jeff Johnson295189b2012-06-20 16:38:30 -07004821 vos_mem_copy((void *)(pRoamProfile->SSIDs.SSIDList->SSID.ssId),
4822 ssid, ssid_len);
4823
4824 if (bssid)
4825 {
4826 pRoamProfile->BSSIDs.numOfBSSIDs = 1;
4827 vos_mem_copy((void *)(pRoamProfile->BSSIDs.bssid), bssid,
4828 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304829 /* Save BSSID in seperate variable as well, as RoamProfile
4830 BSSID is getting zeroed out in the association process. And in
Jeff Johnson295189b2012-06-20 16:38:30 -07004831 case of join failure we should send valid BSSID to supplicant
4832 */
4833 vos_mem_copy((void *)(pWextState->req_bssId), bssid,
4834 WNI_CFG_BSSID_LEN);
4835 }
4836
4837 if ((IW_AUTH_WPA_VERSION_WPA == pWextState->wpaVersion) ||
4838 (IW_AUTH_WPA_VERSION_WPA2 == pWextState->wpaVersion))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304839 {
Jeff Johnson295189b2012-06-20 16:38:30 -07004840 /*set gen ie*/
4841 hdd_SetGENIEToCsr(pAdapter, &RSNAuthType);
4842 /*set auth*/
4843 hdd_set_csr_auth_type(pAdapter, RSNAuthType);
4844 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304845 else if ( (pWextState->roamProfile.AuthType.authType[0] ==
Jeff Johnson295189b2012-06-20 16:38:30 -07004846 eCSR_AUTH_TYPE_OPEN_SYSTEM)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304847 && ((pWextState->roamProfile.EncryptionType.encryptionType[0] ==
4848 eCSR_ENCRYPT_TYPE_WEP40_STATICKEY)
4849 || (pWextState->roamProfile.EncryptionType.encryptionType[0] ==
Jeff Johnson295189b2012-06-20 16:38:30 -07004850 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY))
4851 )
4852 {
4853 /*Android UI not having any option to configure the Authentication type to OPEN/SHARED;
4854 * The authentication type will be always eCSR_AUTH_TYPE_OPEN_SYSTEM when WEP is used
4855 * Use eCSR_AUTH_TYPE_AUTOSWITCH when WEP encryption used*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304856 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.authType =
Jeff Johnson295189b2012-06-20 16:38:30 -07004857 eCSR_AUTH_TYPE_AUTOSWITCH;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304858 pWextState->roamProfile.AuthType.authType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -07004859 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.authType;
4860 }
4861#ifdef FEATURE_WLAN_WAPI
4862 if (pAdapter->wapi_info.nWapiMode)
4863 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004864 hddLog(LOG1, "%s: Setting WAPI AUTH Type and Encryption Mode values", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004865 switch (pAdapter->wapi_info.wapiAuthMode)
4866 {
4867 case WAPI_AUTH_MODE_PSK:
4868 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004869 hddLog(LOG1, "%s: WAPI AUTH TYPE: PSK: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07004870 pAdapter->wapi_info.wapiAuthMode);
4871 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_PSK;
4872 break;
4873 }
4874 case WAPI_AUTH_MODE_CERT:
4875 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004876 hddLog(LOG1, "%s: WAPI AUTH TYPE: CERT: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07004877 pAdapter->wapi_info.wapiAuthMode);
4878 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE;
4879 break;
4880 }
4881 } // End of switch
4882 if ( pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_PSK ||
4883 pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_CERT)
4884 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004885 hddLog(LOG1, "%s: WAPI PAIRWISE/GROUP ENCRYPTION: WPI", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004886 pRoamProfile->AuthType.numEntries = 1;
4887 pRoamProfile->EncryptionType.numEntries = 1;
4888 pRoamProfile->EncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
4889 pRoamProfile->mcEncryptionType.numEntries = 1;
4890 pRoamProfile->mcEncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
4891 }
4892 }
4893#endif /* FEATURE_WLAN_WAPI */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05304894#ifdef WLAN_FEATURE_GTK_OFFLOAD
4895 /* Initializing gtkOffloadRequestParams */
4896 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
4897 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
4898 {
4899 pHddStaCtx->gtkOffloadRequestParams.requested = FALSE;
4900 memset(&pHddStaCtx->gtkOffloadRequestParams.gtkOffloadReqParams,
4901 0, sizeof (tSirGtkOffloadParams));
4902 }
4903#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07004904 pRoamProfile->csrPersona = pAdapter->device_mode;
4905
Jeff Johnson32d95a32012-09-10 13:15:23 -07004906 if( operatingChannel )
4907 {
4908 pRoamProfile->ChannelInfo.ChannelList = &operatingChannel;
4909 pRoamProfile->ChannelInfo.numOfChannels = 1;
4910 }
Chet Lanctot186b5732013-03-18 10:26:30 -07004911 else
4912 {
4913 pRoamProfile->ChannelInfo.ChannelList = NULL;
4914 pRoamProfile->ChannelInfo.numOfChannels = 0;
4915 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07004916
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08004917 /* change conn_state to connecting before sme_RoamConnect(), because sme_RoamConnect()
4918 * has a direct path to call hdd_smeRoamCallback(), which will change the conn_state
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304919 * If direct path, conn_state will be accordingly changed to NotConnected or Associated
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08004920 * by either hdd_AssociationCompletionHandler() or hdd_DisConnectHandler() in sme_RoamCallback()
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -08004921 * if sme_RomConnect is to be queued, Connecting state will remain until it is completed.
4922 */
4923 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode)
4924 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
4925 eConnectionState_Connecting);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304926
4927 status = sme_RoamConnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07004928 pAdapter->sessionId, pRoamProfile, &roamId);
4929
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08004930 if( (eHAL_STATUS_SUCCESS != status) &&
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +05304931 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) )
4932
4933 {
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08004934 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: sme_RoamConnect (session %d) failed with "
4935 "status %d. -> NotConnected", __func__, pAdapter->sessionId, status);
4936 /* change back to NotAssociated */
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +05304937 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08004938 eConnectionState_NotConnected);
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +05304939 }
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -08004940
4941 pRoamProfile->ChannelInfo.ChannelList = NULL;
4942 pRoamProfile->ChannelInfo.numOfChannels = 0;
4943
Jeff Johnson295189b2012-06-20 16:38:30 -07004944 }
4945 else
4946 {
4947 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid Roam profile", __func__);
4948 return -EINVAL;
4949 }
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08004950 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07004951 return status;
4952}
4953
4954/*
4955 * FUNCTION: wlan_hdd_set_cfg80211_auth_type
4956 * This function is used to set the authentication type (OPEN/SHARED).
4957 *
4958 */
4959static int wlan_hdd_cfg80211_set_auth_type(hdd_adapter_t *pAdapter,
4960 enum nl80211_auth_type auth_type)
4961{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304962 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07004963 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4964
4965 ENTER();
4966
4967 /*set authentication type*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304968 switch (auth_type)
Jeff Johnson295189b2012-06-20 16:38:30 -07004969 {
4970 case NL80211_AUTHTYPE_OPEN_SYSTEM:
4971 case NL80211_AUTHTYPE_AUTOMATIC:
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07004972#ifdef WLAN_FEATURE_VOWIFI_11R
4973 case NL80211_AUTHTYPE_FT:
4974#endif /* WLAN_FEATURE_VOWIFI_11R */
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 OPEN", __func__);
4977 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
4978 break;
4979
4980 case NL80211_AUTHTYPE_SHARED_KEY:
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 SHARED", __func__);
4983 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_SHARED_KEY;
4984 break;
4985#ifdef FEATURE_WLAN_CCX
4986 case NL80211_AUTHTYPE_NETWORK_EAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304987 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -07004988 "%s: set authentication type to CCKM WPA", __func__);
4989 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_CCKM_WPA;//eCSR_AUTH_TYPE_CCKM_RSN needs to be handled as well if required.
4990 break;
4991#endif
4992
4993
4994 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304995 hddLog(VOS_TRACE_LEVEL_ERROR,
4996 "%s: Unsupported authentication type %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07004997 auth_type);
4998 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_UNKNOWN;
4999 return -EINVAL;
5000 }
5001
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305002 pWextState->roamProfile.AuthType.authType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -07005003 pHddStaCtx->conn_info.authType;
5004 return 0;
5005}
5006
5007/*
5008 * FUNCTION: wlan_hdd_set_akm_suite
5009 * This function is used to set the key mgmt type(PSK/8021x).
5010 *
5011 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305012static int wlan_hdd_set_akm_suite( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07005013 u32 key_mgmt
5014 )
5015{
5016 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
5017 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305018
Jeff Johnson295189b2012-06-20 16:38:30 -07005019 /*set key mgmt type*/
5020 switch(key_mgmt)
5021 {
5022 case WLAN_AKM_SUITE_PSK:
Gopichand Nakkala356fb102013-03-06 12:34:04 +05305023#ifdef WLAN_FEATURE_VOWIFI_11R
5024 case WLAN_AKM_SUITE_FT_PSK:
5025#endif
5026 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to PSK",
Jeff Johnson295189b2012-06-20 16:38:30 -07005027 __func__);
5028 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_PSK;
5029 break;
5030
5031 case WLAN_AKM_SUITE_8021X:
Gopichand Nakkala356fb102013-03-06 12:34:04 +05305032#ifdef WLAN_FEATURE_VOWIFI_11R
5033 case WLAN_AKM_SUITE_FT_8021X:
5034#endif
5035 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to 8021x",
Jeff Johnson295189b2012-06-20 16:38:30 -07005036 __func__);
5037 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
5038 break;
5039#ifdef FEATURE_WLAN_CCX
5040#define WLAN_AKM_SUITE_CCKM 0x00409600 /* Should be in ieee802_11_defs.h */
5041#define IW_AUTH_KEY_MGMT_CCKM 8 /* Should be in linux/wireless.h */
5042 case WLAN_AKM_SUITE_CCKM:
5043 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to CCKM",
5044 __func__);
5045 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_CCKM;
5046 break;
5047#endif
5048
5049 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305050 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported key mgmt type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07005051 __func__, key_mgmt);
5052 return -EINVAL;
5053
5054 }
5055 return 0;
5056}
5057
5058/*
5059 * FUNCTION: wlan_hdd_cfg80211_set_cipher
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305060 * This function is used to set the encryption type
Jeff Johnson295189b2012-06-20 16:38:30 -07005061 * (NONE/WEP40/WEP104/TKIP/CCMP).
5062 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305063static int wlan_hdd_cfg80211_set_cipher( hdd_adapter_t *pAdapter,
5064 u32 cipher,
Jeff Johnson295189b2012-06-20 16:38:30 -07005065 bool ucast
5066 )
5067{
5068 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305069 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07005070 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
5071
5072 ENTER();
5073
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305074 if (!cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -07005075 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305076 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: received cipher %d - considering none",
Jeff Johnson295189b2012-06-20 16:38:30 -07005077 __func__, cipher);
5078 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
5079 }
5080 else
5081 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305082
Jeff Johnson295189b2012-06-20 16:38:30 -07005083 /*set encryption method*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305084 switch (cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -07005085 {
5086 case IW_AUTH_CIPHER_NONE:
5087 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
5088 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305089
Jeff Johnson295189b2012-06-20 16:38:30 -07005090 case WLAN_CIPHER_SUITE_WEP40:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305091 if ((IW_AUTH_KEY_MGMT_802_1X == pWextState->authKeyMgmt) &&
Jeff Johnson295189b2012-06-20 16:38:30 -07005092 (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType))
5093 encryptionType = eCSR_ENCRYPT_TYPE_WEP40;
5094 else
5095 encryptionType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
5096 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305097
Jeff Johnson295189b2012-06-20 16:38:30 -07005098 case WLAN_CIPHER_SUITE_WEP104:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305099 if ((IW_AUTH_KEY_MGMT_802_1X == pWextState->authKeyMgmt) &&
Jeff Johnson295189b2012-06-20 16:38:30 -07005100 (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType))
5101 encryptionType = eCSR_ENCRYPT_TYPE_WEP104;
5102 else
5103 encryptionType = eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
5104 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305105
Jeff Johnson295189b2012-06-20 16:38:30 -07005106 case WLAN_CIPHER_SUITE_TKIP:
5107 encryptionType = eCSR_ENCRYPT_TYPE_TKIP;
5108 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305109
Jeff Johnson295189b2012-06-20 16:38:30 -07005110 case WLAN_CIPHER_SUITE_CCMP:
5111 encryptionType = eCSR_ENCRYPT_TYPE_AES;
5112 break;
5113#ifdef FEATURE_WLAN_WAPI
5114 case WLAN_CIPHER_SUITE_SMS4:
5115 encryptionType = eCSR_ENCRYPT_TYPE_WPI;
5116 break;
5117#endif
5118
5119#ifdef FEATURE_WLAN_CCX
5120 case WLAN_CIPHER_SUITE_KRK:
5121 encryptionType = eCSR_ENCRYPT_TYPE_KRK;
5122 break;
5123#endif
5124 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305125 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported cipher type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07005126 __func__, cipher);
5127 return -EOPNOTSUPP;
5128 }
5129 }
5130
5131 if (ucast)
5132 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305133 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting unicast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07005134 __func__, encryptionType);
5135 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
5136 pWextState->roamProfile.EncryptionType.numEntries = 1;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305137 pWextState->roamProfile.EncryptionType.encryptionType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -07005138 encryptionType;
5139 }
5140 else
5141 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305142 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting mcast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07005143 __func__, encryptionType);
5144 pHddStaCtx->conn_info.mcEncryptionType = encryptionType;
5145 pWextState->roamProfile.mcEncryptionType.numEntries = 1;
5146 pWextState->roamProfile.mcEncryptionType.encryptionType[0] = encryptionType;
5147 }
5148
5149 return 0;
5150}
5151
5152
5153/*
5154 * FUNCTION: wlan_hdd_cfg80211_set_ie
5155 * This function is used to parse WPA/RSN IE's.
5156 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305157int wlan_hdd_cfg80211_set_ie( hdd_adapter_t *pAdapter,
5158 u8 *ie,
Jeff Johnson295189b2012-06-20 16:38:30 -07005159 size_t ie_len
5160 )
5161{
5162 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
5163 u8 *genie = ie;
5164 v_U16_t remLen = ie_len;
5165#ifdef FEATURE_WLAN_WAPI
5166 v_U32_t akmsuite[MAX_NUM_AKM_SUITES];
5167 u16 *tmp;
5168 v_U16_t akmsuiteCount;
5169 int *akmlist;
5170#endif
5171 ENTER();
5172
5173 /* clear previous assocAddIE */
5174 pWextState->assocAddIE.length = 0;
5175 pWextState->roamProfile.bWPSAssociation = VOS_FALSE;
5176
5177 while (remLen >= 2)
5178 {
5179 v_U16_t eLen = 0;
5180 v_U8_t elementId;
5181 elementId = *genie++;
5182 eLen = *genie++;
5183 remLen -= 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305184
5185 hddLog(VOS_TRACE_LEVEL_INFO, "%s: IE[0x%X], LEN[%d]\n",
Jeff Johnson295189b2012-06-20 16:38:30 -07005186 __func__, elementId, eLen);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305187
5188 switch ( elementId )
Jeff Johnson295189b2012-06-20 16:38:30 -07005189 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305190 case DOT11F_EID_WPA:
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005191 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 -07005192 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305193 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07005194 "%s: Invalid WPA IE", __func__);
5195 return -EINVAL;
5196 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305197 else if (0 == memcmp(&genie[0], "\x00\x50\xf2\x04", 4))
Jeff Johnson295189b2012-06-20 16:38:30 -07005198 {
5199 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305200 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPS IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -07005201 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305202
Jeff Johnson295189b2012-06-20 16:38:30 -07005203 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
5204 {
Jeff Johnson902c9832012-12-10 14:28:09 -08005205 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE. "
5206 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -07005207 VOS_ASSERT(0);
5208 return -ENOMEM;
5209 }
5210 // WSC IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
5211 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
5212 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305213
Jeff Johnson295189b2012-06-20 16:38:30 -07005214 pWextState->roamProfile.bWPSAssociation = VOS_TRUE;
5215 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
5216 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
5217 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305218 else if (0 == memcmp(&genie[0], "\x00\x50\xf2", 3))
5219 {
Jeff Johnson295189b2012-06-20 16:38:30 -07005220 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPA IE (len %d)",__func__, eLen + 2);
5221 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
5222 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2) /*ie_len*/);
5223 pWextState->roamProfile.pWPAReqIE = pWextState->WPARSNIE;
5224 pWextState->roamProfile.nWPAReqIELength = eLen + 2;//ie_len;
5225 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305226 else if ( (0 == memcmp(&genie[0], P2P_OUI_TYPE,
5227 P2P_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07005228 /*Consider P2P IE, only for P2P Client */
5229 && (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
5230 {
5231 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305232 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set P2P IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -07005233 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305234
Jeff Johnson295189b2012-06-20 16:38:30 -07005235 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
5236 {
Jeff Johnson902c9832012-12-10 14:28:09 -08005237 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
5238 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -07005239 VOS_ASSERT(0);
5240 return -ENOMEM;
5241 }
5242 // P2P IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
5243 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
5244 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305245
Jeff Johnson295189b2012-06-20 16:38:30 -07005246 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
5247 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
5248 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005249#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305250 else if ( (0 == memcmp(&genie[0], WFD_OUI_TYPE,
5251 WFD_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07005252 /*Consider WFD IE, only for P2P Client */
5253 && (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
5254 {
5255 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305256 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WFD IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -07005257 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305258
Jeff Johnson295189b2012-06-20 16:38:30 -07005259 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
5260 {
Jeff Johnson902c9832012-12-10 14:28:09 -08005261 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
5262 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -07005263 VOS_ASSERT(0);
5264 return -ENOMEM;
5265 }
5266 // WFD IE is saved to Additional IE ; it should be accumulated to handle
5267 // WPS IE + P2P IE + WFD IE
5268 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
5269 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305270
Jeff Johnson295189b2012-06-20 16:38:30 -07005271 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
5272 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
5273 }
5274#endif
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005275 /* Appending HS 2.0 Indication Element in Assiciation Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305276 else if ( (0 == memcmp(&genie[0], HS20_OUI_TYPE,
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07005277 HS20_OUI_TYPE_SIZE)) )
5278 {
5279 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305280 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set HS20 IE(len %d)",
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07005281 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005282
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07005283 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
5284 {
Jeff Johnson902c9832012-12-10 14:28:09 -08005285 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
5286 "Need bigger buffer space");
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07005287 VOS_ASSERT(0);
5288 return -ENOMEM;
5289 }
5290 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
5291 pWextState->assocAddIE.length += eLen + 2;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005292
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07005293 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
5294 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
5295 }
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005296
Jeff Johnson295189b2012-06-20 16:38:30 -07005297 break;
5298 case DOT11F_EID_RSN:
5299 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set RSN IE(len %d)",__func__, eLen + 2);
5300 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
5301 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2)/*ie_len*/);
5302 pWextState->roamProfile.pRSNReqIE = pWextState->WPARSNIE;
5303 pWextState->roamProfile.nRSNReqIELength = eLen + 2; //ie_len;
5304 break;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005305 /* Appending Extended Capabilities with Interworking bit set in Assoc Req */
5306 case DOT11F_EID_EXTCAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305307 {
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005308 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305309 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set Extended CAPS IE(len %d)",
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005310 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305311
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005312 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
5313 {
Jeff Johnson902c9832012-12-10 14:28:09 -08005314 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
5315 "Need bigger buffer space");
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005316 VOS_ASSERT(0);
5317 return -ENOMEM;
5318 }
5319 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
5320 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305321
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005322 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
5323 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
5324 break;
5325 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005326#ifdef FEATURE_WLAN_WAPI
5327 case WLAN_EID_WAPI:
5328 pAdapter->wapi_info.nWapiMode = 1; //Setting WAPI Mode to ON=1
5329 hddLog(VOS_TRACE_LEVEL_INFO,"WAPI MODE IS %lu \n",
5330 pAdapter->wapi_info.nWapiMode);
5331 tmp = (u16 *)ie;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305332 tmp = tmp + 2; // Skip element Id and Len, Version
Jeff Johnson295189b2012-06-20 16:38:30 -07005333 akmsuiteCount = WPA_GET_LE16(tmp);
5334 tmp = tmp + 1;
5335 akmlist = (int *)(tmp);
5336 if(akmsuiteCount <= MAX_NUM_AKM_SUITES)
5337 {
5338 memcpy(akmsuite, akmlist, (4*akmsuiteCount));
5339 }
5340 else
5341 {
5342 hddLog(VOS_TRACE_LEVEL_FATAL, "Invalid akmSuite count\n");
5343 VOS_ASSERT(0);
5344 return -EINVAL;
5345 }
5346
5347 if (WAPI_PSK_AKM_SUITE == akmsuite[0])
5348 {
5349 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO PSK",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005350 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005351 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_PSK;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305352 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005353 if (WAPI_CERT_AKM_SUITE == akmsuite[0])
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305354 {
Jeff Johnson295189b2012-06-20 16:38:30 -07005355 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO CERTIFICATE",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005356 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005357 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_CERT;
5358 }
5359 break;
5360#endif
5361 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305362 hddLog (VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07005363 "%s Set UNKNOWN IE %X", __func__, elementId);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005364 /* when Unknown IE is received we should break and continue
5365 * to the next IE in the buffer instead we were returning
5366 * so changing this to break */
5367 break;
Jeff Johnson295189b2012-06-20 16:38:30 -07005368 }
5369 genie += eLen;
5370 remLen -= eLen;
5371 }
5372 EXIT();
5373 return 0;
5374}
5375
5376/*
5377 * FUNCTION: wlan_hdd_cfg80211_set_privacy
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305378 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -07005379 * parameters during connect operation.
5380 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305381int wlan_hdd_cfg80211_set_privacy( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07005382 struct cfg80211_connect_params *req
5383 )
5384{
5385 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305386 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07005387 ENTER();
5388
5389 /*set wpa version*/
5390 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
5391
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305392 if (req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -07005393 {
5394 if ( (NL80211_WPA_VERSION_1 == req->crypto.wpa_versions)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305395 && ( (req->ie_len)
5396 && (0 == memcmp( &req->ie[2], "\x00\x50\xf2",3) ) ) )
Jeff Johnson295189b2012-06-20 16:38:30 -07005397 // Make sure that it is including a WPA IE.
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305398 /* Currently NL is putting WPA version 1 even for open,
Jeff Johnson295189b2012-06-20 16:38:30 -07005399 * since p2p ie is also put in same buffer.
5400 * */
5401 {
5402 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
5403 }
5404 else if (NL80211_WPA_VERSION_2 == req->crypto.wpa_versions)
5405 {
5406 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
5407 }
5408 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305409
5410 hddLog(VOS_TRACE_LEVEL_INFO, "%s: set wpa version to %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07005411 pWextState->wpaVersion);
5412
5413 /*set authentication type*/
5414 status = wlan_hdd_cfg80211_set_auth_type(pAdapter, req->auth_type);
5415
5416 if (0 > status)
5417 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305418 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07005419 "%s: failed to set authentication type ", __func__);
5420 return status;
5421 }
5422
5423 /*set key mgmt type*/
5424 if (req->crypto.n_akm_suites)
5425 {
5426 status = wlan_hdd_set_akm_suite(pAdapter, req->crypto.akm_suites[0]);
5427 if (0 > status)
5428 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305429 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set akm suite",
Jeff Johnson295189b2012-06-20 16:38:30 -07005430 __func__);
5431 return status;
5432 }
5433 }
5434
5435 /*set pairwise cipher type*/
5436 if (req->crypto.n_ciphers_pairwise)
5437 {
5438 status = wlan_hdd_cfg80211_set_cipher(pAdapter,
5439 req->crypto.ciphers_pairwise[0], true);
5440 if (0 > status)
5441 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305442 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07005443 "%s: failed to set unicast cipher type", __func__);
5444 return status;
5445 }
5446 }
5447 else
5448 {
5449 /*Reset previous cipher suite to none*/
5450 status = wlan_hdd_cfg80211_set_cipher(pAdapter, 0, true);
5451 if (0 > status)
5452 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305453 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07005454 "%s: failed to set unicast cipher type", __func__);
5455 return status;
5456 }
5457 }
5458
5459 /*set group cipher type*/
5460 status = wlan_hdd_cfg80211_set_cipher(pAdapter, req->crypto.cipher_group,
5461 false);
5462
5463 if (0 > status)
5464 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305465 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set mcast cipher type",
Jeff Johnson295189b2012-06-20 16:38:30 -07005466 __func__);
5467 return status;
5468 }
5469
Chet Lanctot186b5732013-03-18 10:26:30 -07005470#ifdef WLAN_FEATURE_11W
5471 pWextState->roamProfile.MFPEnabled = (req->mfp == NL80211_MFP_REQUIRED);
5472#endif
5473
Jeff Johnson295189b2012-06-20 16:38:30 -07005474 /*parse WPA/RSN IE, and set the correspoing fileds in Roam profile*/
5475 if (req->ie_len)
5476 {
5477 status = wlan_hdd_cfg80211_set_ie(pAdapter, req->ie, req->ie_len);
5478 if ( 0 > status)
5479 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305480 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse the WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -07005481 __func__);
5482 return status;
5483 }
5484 }
5485
5486 /*incase of WEP set default key information*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305487 if (req->key && req->key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -07005488 {
5489 if ( (WLAN_CIPHER_SUITE_WEP40 == req->crypto.ciphers_pairwise[0])
5490 || (WLAN_CIPHER_SUITE_WEP104 == req->crypto.ciphers_pairwise[0])
5491 )
5492 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305493 if ( IW_AUTH_KEY_MGMT_802_1X
Jeff Johnson295189b2012-06-20 16:38:30 -07005494 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X ))
5495 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305496 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Dynamic WEP not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -07005497 __func__);
5498 return -EOPNOTSUPP;
5499 }
5500 else
5501 {
5502 u8 key_len = req->key_len;
5503 u8 key_idx = req->key_idx;
5504
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305505 if ((eCSR_SECURITY_WEP_KEYSIZE_MAX_BYTES >= key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -07005506 && (CSR_MAX_NUM_KEY > key_idx)
5507 )
5508 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305509 hddLog(VOS_TRACE_LEVEL_INFO,
5510 "%s: setting default wep key, key_idx = %hu key_len %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07005511 __func__, key_idx, key_len);
5512 vos_mem_copy(
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305513 &pWextState->roamProfile.Keys.KeyMaterial[key_idx][0],
Jeff Johnson295189b2012-06-20 16:38:30 -07005514 req->key, key_len);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305515 pWextState->roamProfile.Keys.KeyLength[key_idx] =
Jeff Johnson295189b2012-06-20 16:38:30 -07005516 (u8)key_len;
5517 pWextState->roamProfile.Keys.defaultIndex = (u8)key_idx;
5518 }
5519 }
5520 }
5521 }
5522
5523 return status;
5524}
5525
5526/*
5527 * FUNCTION: wlan_hdd_cfg80211_set_privacy
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305528 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -07005529 * parameters during connect operation.
5530 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305531static int wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07005532 struct net_device *ndev,
5533 struct cfg80211_connect_params *req
5534 )
5535{
5536 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305537 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -07005538 VOS_STATUS exitbmpsStatus = VOS_STATUS_E_INVAL;
5539 hdd_context_t *pHddCtx = NULL;
5540
5541 ENTER();
5542
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305543 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -07005544 "%s: device_mode = %d\n",__func__,pAdapter->device_mode);
5545
5546 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
5547 {
5548 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5549 "%s:LOGP in Progress. Ignore!!!", __func__);
5550 return -EAGAIN;
5551 }
5552
5553#ifdef WLAN_BTAMP_FEATURE
5554 //Infra connect not supported when AMP traffic is on.
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305555 if( VOS_TRUE == WLANBAP_AmpSessionOn() )
Jeff Johnson295189b2012-06-20 16:38:30 -07005556 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305557 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07005558 "%s: No connection when AMP is on", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08005559 return -ECONNREFUSED;
Jeff Johnson295189b2012-06-20 16:38:30 -07005560 }
5561#endif
5562 /*initialise security parameters*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305563 status = wlan_hdd_cfg80211_set_privacy(pAdapter, req);
Jeff Johnson295189b2012-06-20 16:38:30 -07005564
5565 if ( 0 > status)
5566 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305567 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security params",
Jeff Johnson295189b2012-06-20 16:38:30 -07005568 __func__);
5569 return status;
5570 }
5571
5572 //If Device Mode is Station Concurrent Sessions Exit BMps
Jeff Johnsona8a1a482012-12-12 16:49:33 -08005573 //P2P Mode will be taken care in Open/close adapter
Jeff Johnson295189b2012-06-20 16:38:30 -07005574 if((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
5575 (vos_concurrent_sessions_running()))
5576 {
5577 v_CONTEXT_t pVosContext = vos_get_global_context( VOS_MODULE_ID_HDD, NULL );
5578
5579 if (NULL != pVosContext)
5580 {
5581 pHddCtx = vos_get_context( VOS_MODULE_ID_HDD, pVosContext);
5582 if(NULL != pHddCtx)
5583 {
5584 exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
5585 }
5586 }
5587 }
5588
Mohit Khanna765234a2012-09-11 15:08:35 -07005589 if ( req->channel )
5590 {
5591 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
5592 req->ssid_len, req->bssid,
5593 req->channel->hw_value);
5594 }
5595 else
5596 {
5597 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
5598 req->ssid_len, req->bssid,
5599 0);
5600 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005601
5602 if (0 > status)
5603 {
5604 //ReEnable BMPS if disabled
5605 if((VOS_STATUS_SUCCESS == exitbmpsStatus) &&
5606 (NULL != pHddCtx))
5607 {
5608 //ReEnable Bmps and Imps back
5609 hdd_enable_bmps_imps(pHddCtx);
5610 }
5611
5612 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: connect failed", __func__);
5613 return status;
5614 }
5615 (WLAN_HDD_GET_CTX(pAdapter))->isAmpAllowed = VOS_FALSE;
5616 EXIT();
5617 return status;
5618}
5619
5620
5621/*
5622 * FUNCTION: wlan_hdd_cfg80211_disconnect
5623 * This function is used to issue a disconnect request to SME
5624 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305625static int wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07005626 struct net_device *dev,
5627 u16 reason
5628 )
5629{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305630 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
5631 tCsrRoamProfile *pRoamProfile =
Jeff Johnson295189b2012-06-20 16:38:30 -07005632 &(WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter))->roamProfile;
5633 int status = 0;
5634 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08005635#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala4327a152013-03-04 23:22:42 -08005636 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08005637 tANI_U8 staIdx;
5638#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305639
Jeff Johnson295189b2012-06-20 16:38:30 -07005640 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305641
5642 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",
Jeff Johnson295189b2012-06-20 16:38:30 -07005643 __func__,pAdapter->device_mode);
5644
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305645 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Disconnect called with reason code %d",
5646 __func__, reason);
Jeff Johnson295189b2012-06-20 16:38:30 -07005647
5648 if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress)
5649 {
5650 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5651 "%s:LOGP in Progress. Ignore!!!",__func__);
5652 return -EAGAIN;
5653 }
5654 if (NULL != pRoamProfile)
5655 {
5656 /*issue disconnect request to SME, if station is in connected state*/
5657 if (pHddStaCtx->conn_info.connState == eConnectionState_Associated)
5658 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305659 eCsrRoamDisconnectReason reasonCode =
Jeff Johnson295189b2012-06-20 16:38:30 -07005660 eCSR_DISCONNECT_REASON_UNSPECIFIED;
5661 switch(reason)
5662 {
5663 case WLAN_REASON_MIC_FAILURE:
5664 reasonCode = eCSR_DISCONNECT_REASON_MIC_ERROR;
5665 break;
5666
5667 case WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY:
5668 case WLAN_REASON_DISASSOC_AP_BUSY:
5669 case WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA:
5670 reasonCode = eCSR_DISCONNECT_REASON_DISASSOC;
5671 break;
5672
5673 case WLAN_REASON_PREV_AUTH_NOT_VALID:
5674 case WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA:
5675 reasonCode = eCSR_DISCONNECT_REASON_DEAUTH;
5676 break;
5677
5678 case WLAN_REASON_DEAUTH_LEAVING:
5679 default:
5680 reasonCode = eCSR_DISCONNECT_REASON_UNSPECIFIED;
5681 break;
5682 }
5683 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
5684 (WLAN_HDD_GET_CTX(pAdapter))->isAmpAllowed = VOS_TRUE;
5685 INIT_COMPLETION(pAdapter->disconnect_comp_var);
5686
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08005687#ifdef FEATURE_WLAN_TDLS
5688 /* First clean up the tdls peers if any */
Gopichand Nakkala4327a152013-03-04 23:22:42 -08005689 for (staIdx = 0 ; staIdx < HDD_MAX_NUM_TDLS_STA; staIdx++)
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08005690 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -08005691 if ((pHddCtx->tdlsConnInfo[staIdx].sessionId == pAdapter->sessionId) &&
5692 (pHddCtx->tdlsConnInfo[staIdx].staId))
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08005693 {
Hoonki Lee11f7dda2013-02-14 16:55:44 -08005694 uint8 *mac;
Gopichand Nakkala4327a152013-03-04 23:22:42 -08005695 mac = pHddCtx->tdlsConnInfo[staIdx].peerMac.bytes;
Hoonki Lee11f7dda2013-02-14 16:55:44 -08005696 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07005697 "%s: call sme_DeleteTdlsPeerSta staId %d sessionId %d " MAC_ADDRESS_STR,
Gopichand Nakkala4327a152013-03-04 23:22:42 -08005698 __func__, pHddCtx->tdlsConnInfo[staIdx].staId, pAdapter->sessionId,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07005699 MAC_ADDR_ARRAY(mac));
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08005700 sme_DeleteTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala4327a152013-03-04 23:22:42 -08005701 pAdapter->sessionId,
5702 mac);
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08005703 }
5704 }
5705#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005706 /*issue disconnect*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305707 status = sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07005708 pAdapter->sessionId, reasonCode);
5709
5710 if ( 0 != status)
5711 {
5712 hddLog(VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305713 "%s csrRoamDisconnect failure, returned %d \n",
Jeff Johnson295189b2012-06-20 16:38:30 -07005714 __func__, (int)status );
5715 return -EINVAL;
5716 }
5717
5718 wait_for_completion_interruptible_timeout(
5719 &pAdapter->disconnect_comp_var,
5720 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
5721
5722
5723 /*stop tx queues*/
5724 netif_tx_disable(dev);
5725 netif_carrier_off(dev);
5726 }
5727 }
5728 else
5729 {
5730 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid roam profile", __func__);
5731 }
5732
5733 return status;
5734}
5735
5736/*
5737 * FUNCTION: wlan_hdd_cfg80211_set_privacy_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305738 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -07005739 * settings in IBSS mode.
5740 */
5741static int wlan_hdd_cfg80211_set_privacy_ibss(
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305742 hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07005743 struct cfg80211_ibss_params *params
5744 )
5745{
5746 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305747 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07005748 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
5749 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305750
Jeff Johnson295189b2012-06-20 16:38:30 -07005751 ENTER();
5752
5753 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
5754
5755 if (params->ie_len && ( NULL != params->ie) )
5756 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305757 if (WLAN_EID_RSN == params->ie[0])
Jeff Johnson295189b2012-06-20 16:38:30 -07005758 {
5759 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
5760 encryptionType = eCSR_ENCRYPT_TYPE_AES;
5761 }
5762 else
5763 {
5764 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
5765 encryptionType = eCSR_ENCRYPT_TYPE_TKIP;
5766 }
5767 status = wlan_hdd_cfg80211_set_ie(pAdapter, params->ie, params->ie_len);
5768
5769 if (0 > status)
5770 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305771 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -07005772 __func__);
5773 return status;
5774 }
5775 }
5776
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305777 pWextState->roamProfile.AuthType.authType[0] =
5778 pHddStaCtx->conn_info.authType =
Jeff Johnson295189b2012-06-20 16:38:30 -07005779 eCSR_AUTH_TYPE_OPEN_SYSTEM;
5780
5781 if (params->privacy)
5782 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305783 /* Security enabled IBSS, At this time there is no information available
5784 * about the security paramters, so initialise the encryption type to
Jeff Johnson295189b2012-06-20 16:38:30 -07005785 * eCSR_ENCRYPT_TYPE_WEP40_STATICKEY.
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305786 * The correct security parameters will be updated later in
Jeff Johnson295189b2012-06-20 16:38:30 -07005787 * wlan_hdd_cfg80211_add_key */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305788 /* Hal expects encryption type to be set inorder
Jeff Johnson295189b2012-06-20 16:38:30 -07005789 *enable privacy bit in beacons */
5790
5791 encryptionType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
5792 }
5793
5794 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
5795 pWextState->roamProfile.EncryptionType.numEntries = 1;
5796 pWextState->roamProfile.EncryptionType.encryptionType[0] = encryptionType;
5797
5798 return status;
5799}
5800
5801/*
5802 * FUNCTION: wlan_hdd_cfg80211_join_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305803 * This function is used to create/join an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -07005804 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305805static int wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07005806 struct net_device *dev,
5807 struct cfg80211_ibss_params *params
5808 )
5809{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305810 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Jeff Johnson295189b2012-06-20 16:38:30 -07005811 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
5812 tCsrRoamProfile *pRoamProfile;
5813 int status;
5814 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
5815
5816 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305817
5818 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -07005819 "%s: device_mode = %d\n",__func__,pAdapter->device_mode);
5820
5821 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
5822 {
5823 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5824 "%s:LOGP in Progress. Ignore!!!", __func__);
5825 return -EAGAIN;
5826 }
5827
5828 if (NULL == pWextState)
5829 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305830 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption\n",
Jeff Johnson295189b2012-06-20 16:38:30 -07005831 __func__);
5832 return -EIO;
5833 }
5834
5835 pRoamProfile = &pWextState->roamProfile;
5836
5837 if ( eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType )
5838 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305839 hddLog (VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07005840 "%s Interface type is not set to IBSS \n", __func__);
5841 return -EINVAL;
5842 }
5843
5844 /* Set Channel */
5845 if (NULL != params->channel)
5846 {
5847 u8 channelNum;
5848 if (IEEE80211_BAND_5GHZ == params->channel->band)
5849 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305850 hddLog(VOS_TRACE_LEVEL_ERROR,
5851 "%s: IBSS join is called with unsupported band %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07005852 __func__, params->channel->band);
5853 return -EOPNOTSUPP;
5854 }
5855
5856 /* Get channel number */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305857 channelNum =
Jeff Johnson295189b2012-06-20 16:38:30 -07005858 ieee80211_frequency_to_channel(params->channel->center_freq);
5859
5860 /*TODO: use macro*/
5861 if (14 >= channelNum)
5862 {
5863 v_U32_t numChans = WNI_CFG_VALID_CHANNEL_LIST_LEN;
5864 v_U8_t validChan[WNI_CFG_VALID_CHANNEL_LIST_LEN];
5865 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
5866 int indx;
5867
5868 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
5869 validChan, &numChans))
5870 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305871 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid channel list",
Jeff Johnson295189b2012-06-20 16:38:30 -07005872 __func__);
5873 return -EOPNOTSUPP;
5874 }
5875
5876 for (indx = 0; indx < numChans; indx++)
5877 {
5878 if (channelNum == validChan[indx])
5879 {
5880 break;
5881 }
5882 }
5883 if (indx >= numChans)
5884 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305885 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Not valid Channel %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07005886 __func__, channelNum);
5887 return -EINVAL;
5888 }
5889 /* Set the Operational Channel */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305890 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: set channel %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07005891 channelNum);
5892 pRoamProfile->ChannelInfo.numOfChannels = 1;
5893 pHddStaCtx->conn_info.operationChannel = channelNum;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305894 pRoamProfile->ChannelInfo.ChannelList =
Jeff Johnson295189b2012-06-20 16:38:30 -07005895 &pHddStaCtx->conn_info.operationChannel;
5896 }
5897 else
5898 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305899 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Not valid Channel %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07005900 __func__, channelNum);
5901 return -EINVAL;
5902 }
5903 }
5904
5905 /* Initialize security parameters */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305906 status = wlan_hdd_cfg80211_set_privacy_ibss(pAdapter, params);
Jeff Johnson295189b2012-06-20 16:38:30 -07005907 if (status < 0)
5908 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305909 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security parameters",
Jeff Johnson295189b2012-06-20 16:38:30 -07005910 __func__);
5911 return status;
5912 }
5913
5914 /* Issue connect start */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305915 status = wlan_hdd_cfg80211_connect_start(pAdapter, params->ssid,
Jeff Johnson32d95a32012-09-10 13:15:23 -07005916 params->ssid_len, params->bssid, 0);
Jeff Johnson295189b2012-06-20 16:38:30 -07005917
5918 if (0 > status)
5919 {
5920 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: connect failed", __func__);
5921 return status;
5922 }
5923
5924 return 0;
5925}
5926
5927/*
5928 * FUNCTION: wlan_hdd_cfg80211_leave_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305929 * This function is used to leave an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -07005930 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305931static int wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07005932 struct net_device *dev
5933 )
5934{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305935 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Jeff Johnson295189b2012-06-20 16:38:30 -07005936 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
5937 tCsrRoamProfile *pRoamProfile;
5938
5939 ENTER();
5940
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005941 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
5942 {
5943 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5944 "%s:LOGP in Progress. Ignore!!!", __func__);
5945 return -EAGAIN;
5946 }
5947
Jeff Johnson295189b2012-06-20 16:38:30 -07005948 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",__func__,pAdapter->device_mode);
5949 if (NULL == pWextState)
5950 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305951 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption\n",
Jeff Johnson295189b2012-06-20 16:38:30 -07005952 __func__);
5953 return -EIO;
5954 }
5955
5956 pRoamProfile = &pWextState->roamProfile;
5957
5958 /* Issue disconnect only if interface type is set to IBSS */
5959 if (eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType)
5960 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305961 hddLog (VOS_TRACE_LEVEL_ERROR, "%s: BSS Type is not set to IBSS",
Jeff Johnson295189b2012-06-20 16:38:30 -07005962 __func__);
5963 return -EINVAL;
5964 }
5965
5966 /* Issue Disconnect request */
5967 INIT_COMPLETION(pAdapter->disconnect_comp_var);
5968 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
5969 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
5970
5971 return 0;
5972}
5973
5974/*
5975 * FUNCTION: wlan_hdd_cfg80211_set_wiphy_params
5976 * This function is used to set the phy parameters
5977 * (RTS Threshold/FRAG Threshold/Retry Count etc ...)
5978 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305979static int wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07005980 u32 changed)
5981{
5982 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5983 tHalHandle hHal = pHddCtx->hHal;
5984
5985 ENTER();
5986
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005987 if ( pHddCtx->isLogpInProgress )
5988 {
5989 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5990 "%s:LOGP in Progress. Ignore!!!", __func__);
5991 return -EAGAIN;
5992 }
5993
Jeff Johnson295189b2012-06-20 16:38:30 -07005994 if (changed & WIPHY_PARAM_RTS_THRESHOLD)
5995 {
5996 u16 rts_threshold = (wiphy->rts_threshold == -1) ?
5997 WNI_CFG_RTS_THRESHOLD_STAMAX :
5998 wiphy->rts_threshold;
5999
6000 if ((WNI_CFG_RTS_THRESHOLD_STAMIN > rts_threshold) ||
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306001 (WNI_CFG_RTS_THRESHOLD_STAMAX < rts_threshold))
Jeff Johnson295189b2012-06-20 16:38:30 -07006002 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306003 hddLog(VOS_TRACE_LEVEL_ERROR,
6004 "%s: Invalid RTS Threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07006005 __func__, rts_threshold);
6006 return -EINVAL;
6007 }
6008
6009 if (0 != ccmCfgSetInt(hHal, WNI_CFG_RTS_THRESHOLD,
6010 rts_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306011 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -07006012 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306013 hddLog(VOS_TRACE_LEVEL_ERROR,
6014 "%s: ccmCfgSetInt failed for rts_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07006015 __func__, rts_threshold);
6016 return -EIO;
6017 }
6018
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306019 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set rts threshold %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07006020 rts_threshold);
6021 }
6022
6023 if (changed & WIPHY_PARAM_FRAG_THRESHOLD)
6024 {
6025 u16 frag_threshold = (wiphy->frag_threshold == -1) ?
6026 WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX :
6027 wiphy->frag_threshold;
6028
6029 if ((WNI_CFG_FRAGMENTATION_THRESHOLD_STAMIN > frag_threshold)||
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306030 (WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX < frag_threshold) )
Jeff Johnson295189b2012-06-20 16:38:30 -07006031 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306032 hddLog(VOS_TRACE_LEVEL_ERROR,
6033 "%s: Invalid frag_threshold value %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07006034 frag_threshold);
6035 return -EINVAL;
6036 }
6037
6038 if (0 != ccmCfgSetInt(hHal, WNI_CFG_FRAGMENTATION_THRESHOLD,
6039 frag_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306040 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -07006041 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306042 hddLog(VOS_TRACE_LEVEL_ERROR,
6043 "%s: ccmCfgSetInt failed for frag_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07006044 __func__, frag_threshold);
6045 return -EIO;
6046 }
6047
6048 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set frag threshold %hu", __func__,
6049 frag_threshold);
6050 }
6051
6052 if ((changed & WIPHY_PARAM_RETRY_SHORT)
6053 || (changed & WIPHY_PARAM_RETRY_LONG))
6054 {
6055 u8 retry_value = (changed & WIPHY_PARAM_RETRY_SHORT) ?
6056 wiphy->retry_short :
6057 wiphy->retry_long;
6058
6059 if ((WNI_CFG_LONG_RETRY_LIMIT_STAMIN > retry_value) ||
6060 (WNI_CFG_LONG_RETRY_LIMIT_STAMAX < retry_value))
6061 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306062 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07006063 __func__, retry_value);
6064 return -EINVAL;
6065 }
6066
6067 if (changed & WIPHY_PARAM_RETRY_SHORT)
6068 {
6069 if (0 != ccmCfgSetInt(hHal, WNI_CFG_LONG_RETRY_LIMIT,
6070 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306071 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -07006072 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306073 hddLog(VOS_TRACE_LEVEL_ERROR,
6074 "%s: ccmCfgSetInt failed for long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07006075 __func__, retry_value);
6076 return -EIO;
6077 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306078 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07006079 __func__, retry_value);
6080 }
6081 else if (changed & WIPHY_PARAM_RETRY_SHORT)
6082 {
6083 if (0 != ccmCfgSetInt(hHal, WNI_CFG_SHORT_RETRY_LIMIT,
6084 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306085 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -07006086 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306087 hddLog(VOS_TRACE_LEVEL_ERROR,
6088 "%s: ccmCfgSetInt failed for short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07006089 __func__, retry_value);
6090 return -EIO;
6091 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306092 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07006093 __func__, retry_value);
6094 }
6095 }
6096
6097 return 0;
6098}
6099
6100/*
6101 * FUNCTION: wlan_hdd_cfg80211_set_txpower
6102 * This function is used to set the txpower
6103 */
6104static int wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
6105#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306106 enum tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -07006107#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306108 enum nl80211_tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -07006109#endif
6110 int dbm)
6111{
6112 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
6113 tHalHandle hHal = pHddCtx->hHal;
6114 tSirMacAddr bssid = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
6115 tSirMacAddr selfMac = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
6116
6117 ENTER();
6118
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306119 if (0 != ccmCfgSetInt(hHal, WNI_CFG_CURRENT_TX_POWER_LEVEL,
6120 dbm, ccmCfgSetCallback,
6121 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -07006122 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306123 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07006124 "%s: ccmCfgSetInt failed for tx power %hu", __func__, dbm);
6125 return -EIO;
6126 }
6127
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006128 if ( pHddCtx->isLogpInProgress )
6129 {
6130 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6131 "%s:LOGP in Progress. Ignore!!!", __func__);
6132 return -EAGAIN;
6133 }
6134
Jeff Johnson295189b2012-06-20 16:38:30 -07006135 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set tx power level %d dbm", __func__,
6136 dbm);
6137
6138 switch(type)
6139 {
6140 case NL80211_TX_POWER_AUTOMATIC: /*automatically determine transmit power*/
6141 /* Fall through */
6142 case NL80211_TX_POWER_LIMITED: /*limit TX power by the mBm parameter*/
6143 if( sme_SetMaxTxPower(hHal, bssid, selfMac, dbm) != eHAL_STATUS_SUCCESS )
6144 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306145 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Setting maximum tx power failed",
6146 __func__);
6147 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -07006148 }
6149 break;
6150 case NL80211_TX_POWER_FIXED: /*fix TX power to the mBm parameter*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306151 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: NL80211_TX_POWER_FIXED not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -07006152 __func__);
6153 return -EOPNOTSUPP;
6154 break;
6155 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306156 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid power setting type %d",
6157 __func__, type);
Jeff Johnson295189b2012-06-20 16:38:30 -07006158 return -EIO;
6159 }
6160
6161 return 0;
6162}
6163
6164/*
6165 * FUNCTION: wlan_hdd_cfg80211_get_txpower
6166 * This function is used to read the txpower
6167 */
6168static int wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy, int *dbm)
6169{
6170
6171 hdd_adapter_t *pAdapter;
6172 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
6173
Jeff Johnsone7245742012-09-05 17:12:55 -07006174 ENTER();
6175
Jeff Johnson295189b2012-06-20 16:38:30 -07006176 if (NULL == pHddCtx)
6177 {
6178 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD context is Null",__func__);
6179 *dbm = 0;
6180 return -ENOENT;
6181 }
6182
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006183 if ( pHddCtx->isLogpInProgress )
6184 {
6185 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6186 "%s:LOGP in Progress. Ignore!!!", __func__);
6187 return -EAGAIN;
6188 }
6189
Jeff Johnson295189b2012-06-20 16:38:30 -07006190 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
6191 if (NULL == pAdapter)
6192 {
6193 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Not in station context " ,__func__);
6194 return -ENOENT;
6195 }
6196
6197 wlan_hdd_get_classAstats(pAdapter);
6198 *dbm = pAdapter->hdd_stats.ClassA_stat.max_pwr;
6199
Jeff Johnsone7245742012-09-05 17:12:55 -07006200 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07006201 return 0;
6202}
6203
6204static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
6205 u8* mac, struct station_info *sinfo)
6206{
6207 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
6208 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6209 int ssidlen = pHddStaCtx->conn_info.SSID.SSID.length;
6210 tANI_U8 rate_flags;
6211
6212 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
6213 hdd_config_t *pCfg = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -07006214
6215 tANI_U8 OperationalRates[CSR_DOT11_SUPPORTED_RATES_MAX];
6216 tANI_U32 ORLeng = CSR_DOT11_SUPPORTED_RATES_MAX;
6217 tANI_U8 ExtendedRates[CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX];
6218 tANI_U32 ERLeng = CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX;
6219 tANI_U8 MCSRates[SIZE_OF_BASIC_MCS_SET];
6220 tANI_U32 MCSLeng = SIZE_OF_BASIC_MCS_SET;
6221 tANI_U16 maxRate = 0;
6222 tANI_U16 myRate;
6223 tANI_U16 currentRate = 0;
6224 tANI_U8 maxSpeedMCS = 0;
6225 tANI_U8 maxMCSIdx = 0;
6226 tANI_U8 rateFlag = 1;
6227 tANI_U8 i, j, rssidx;
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07006228 tANI_U16 temp;
Jeff Johnson295189b2012-06-20 16:38:30 -07006229
Leo Chang6f8870f2013-03-26 18:11:36 -07006230#ifdef WLAN_FEATURE_11AC
6231 tANI_U32 vht_mcs_map;
6232 eDataRate11ACMaxMcs vhtMaxMcs;
6233#endif /* WLAN_FEATURE_11AC */
6234
Jeff Johnsone7245742012-09-05 17:12:55 -07006235 ENTER();
6236
Jeff Johnson295189b2012-06-20 16:38:30 -07006237 if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) ||
6238 (0 == ssidlen))
6239 {
6240 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Not associated or"
6241 " Invalid ssidlen, %d", __func__, ssidlen);
6242 /*To keep GUI happy*/
6243 return 0;
6244 }
6245
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006246 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
6247 {
6248 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6249 "%s:LOGP in Progress. Ignore!!!", __func__);
6250 return -EAGAIN;
6251 }
6252
Jeff Johnson295189b2012-06-20 16:38:30 -07006253 wlan_hdd_get_rssi(pAdapter, &sinfo->signal);
6254 sinfo->filled |= STATION_INFO_SIGNAL;
6255
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -07006256 wlan_hdd_get_station_stats(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07006257 rate_flags = pAdapter->hdd_stats.ClassA_stat.tx_rate_flags;
6258
6259 //convert to the UI units of 100kbps
6260 myRate = pAdapter->hdd_stats.ClassA_stat.tx_rate * 5;
6261
6262#ifdef LINKSPEED_DEBUG_ENABLED
Leo Chang6f8870f2013-03-26 18:11:36 -07006263 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 -07006264 sinfo->signal,
6265 pCfg->reportMaxLinkSpeed,
6266 myRate,
6267 (int) pCfg->linkSpeedRssiHigh,
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07006268 (int) pCfg->linkSpeedRssiMid,
6269 (int) pCfg->linkSpeedRssiLow,
Leo Chang6f8870f2013-03-26 18:11:36 -07006270 (int) rate_flags,
6271 (int) pAdapter->hdd_stats.ClassA_stat.mcs_index);
Jeff Johnson295189b2012-06-20 16:38:30 -07006272#endif //LINKSPEED_DEBUG_ENABLED
6273
6274 if (eHDD_LINK_SPEED_REPORT_ACTUAL != pCfg->reportMaxLinkSpeed)
6275 {
6276 // we do not want to necessarily report the current speed
6277 if (eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed)
6278 {
6279 // report the max possible speed
6280 rssidx = 0;
6281 }
6282 else if (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed)
6283 {
6284 // report the max possible speed with RSSI scaling
6285 if (sinfo->signal >= pCfg->linkSpeedRssiHigh)
6286 {
6287 // report the max possible speed
6288 rssidx = 0;
6289 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07006290 else if (sinfo->signal >= pCfg->linkSpeedRssiMid)
Jeff Johnson295189b2012-06-20 16:38:30 -07006291 {
6292 // report middle speed
6293 rssidx = 1;
6294 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07006295 else if (sinfo->signal >= pCfg->linkSpeedRssiLow)
6296 {
6297 // report middle speed
6298 rssidx = 2;
6299 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006300 else
6301 {
6302 // report actual speed
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07006303 rssidx = 3;
Jeff Johnson295189b2012-06-20 16:38:30 -07006304 }
6305 }
6306 else
6307 {
6308 // unknown, treat as eHDD_LINK_SPEED_REPORT_MAX
6309 hddLog(VOS_TRACE_LEVEL_ERROR,
6310 "%s: Invalid value for reportMaxLinkSpeed: %u",
6311 __func__, pCfg->reportMaxLinkSpeed);
6312 rssidx = 0;
6313 }
6314
6315 maxRate = 0;
6316
6317 /* Get Basic Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +05306318 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_OPERATIONAL_RATE_SET,
6319 OperationalRates, &ORLeng))
6320 {
6321 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
6322 /*To keep GUI happy*/
6323 return 0;
6324 }
6325
Jeff Johnson295189b2012-06-20 16:38:30 -07006326 for (i = 0; i < ORLeng; i++)
6327 {
Jeff Johnsone7245742012-09-05 17:12:55 -07006328 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -07006329 {
6330 /* Validate Rate Set */
6331 if (supported_data_rate[j].beacon_rate_index == (OperationalRates[i] & 0x7F))
6332 {
6333 currentRate = supported_data_rate[j].supported_rate[rssidx];
6334 break;
6335 }
6336 }
6337 /* Update MAX rate */
6338 maxRate = (currentRate > maxRate)?currentRate:maxRate;
6339 }
6340
6341 /* Get Extended Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +05306342 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET,
6343 ExtendedRates, &ERLeng))
6344 {
6345 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
6346 /*To keep GUI happy*/
6347 return 0;
6348 }
6349
Jeff Johnson295189b2012-06-20 16:38:30 -07006350 for (i = 0; i < ERLeng; i++)
6351 {
Jeff Johnsone7245742012-09-05 17:12:55 -07006352 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -07006353 {
6354 if (supported_data_rate[j].beacon_rate_index == (ExtendedRates[i] & 0x7F))
6355 {
6356 currentRate = supported_data_rate[j].supported_rate[rssidx];
6357 break;
6358 }
6359 }
6360 /* Update MAX rate */
6361 maxRate = (currentRate > maxRate)?currentRate:maxRate;
6362 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006363 /* Get MCS Rate Set -- but only if we are connected at MCS
6364 rates or if we are always reporting max speed or if we have
6365 good rssi */
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07006366 if ((0 == rssidx) && !(rate_flags & eHAL_TX_RATE_LEGACY))
Jeff Johnson295189b2012-06-20 16:38:30 -07006367 {
Gopichand Nakkala05ab1322013-02-15 11:28:38 +05306368 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_CURRENT_MCS_SET,
6369 MCSRates, &MCSLeng))
6370 {
6371 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
6372 /*To keep GUI happy*/
6373 return 0;
6374 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006375 rateFlag = 0;
Leo Chang6f8870f2013-03-26 18:11:36 -07006376#ifdef WLAN_FEATURE_11AC
6377 /* VHT80 rate has seperate rate table */
Gopichand Nakkala4c705372013-04-24 13:20:33 +05306378 if (rate_flags & (eHAL_TX_RATE_VHT20|eHAL_TX_RATE_VHT40|eHAL_TX_RATE_VHT80))
Jeff Johnson295189b2012-06-20 16:38:30 -07006379 {
Leo Chang6f8870f2013-03-26 18:11:36 -07006380 ccmCfgGetInt(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_VHT_TX_MCS_MAP, &vht_mcs_map);
Gopichand Nakkala4c705372013-04-24 13:20:33 +05306381 vhtMaxMcs = (eDataRate11ACMaxMcs)(vht_mcs_map & DATA_RATE_11AC_MCS_MASK );
Leo Chang6f8870f2013-03-26 18:11:36 -07006382 if (rate_flags & eHAL_TX_RATE_SGI)
Jeff Johnson295189b2012-06-20 16:38:30 -07006383 {
Leo Chang6f8870f2013-03-26 18:11:36 -07006384 rateFlag |= 1;
Jeff Johnson295189b2012-06-20 16:38:30 -07006385 }
Leo Chang6f8870f2013-03-26 18:11:36 -07006386 if (DATA_RATE_11AC_MAX_MCS_7 == vhtMaxMcs)
Jeff Johnson295189b2012-06-20 16:38:30 -07006387 {
Leo Chang6f8870f2013-03-26 18:11:36 -07006388 maxMCSIdx = 7;
6389 }
6390 else if (DATA_RATE_11AC_MAX_MCS_8 == vhtMaxMcs)
6391 {
6392 maxMCSIdx = 8;
6393 }
6394 else if (DATA_RATE_11AC_MAX_MCS_9 == vhtMaxMcs)
6395 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +05306396 //VHT20 is supporting 0~8
6397 if (rate_flags & eHAL_TX_RATE_VHT20)
6398 maxMCSIdx = 8;
6399 else
6400 maxMCSIdx = 9;
Leo Chang6f8870f2013-03-26 18:11:36 -07006401 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +05306402
6403 if (rate_flags & eHAL_TX_RATE_VHT80)
6404 {
6405 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT80_rate[rateFlag];
6406 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT80_rate[rateFlag];
6407 }
6408 else if (rate_flags & eHAL_TX_RATE_VHT40)
6409 {
6410 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT40_rate[rateFlag];
6411 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT40_rate[rateFlag];
6412 }
6413 else if (rate_flags & eHAL_TX_RATE_VHT20)
6414 {
6415 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT20_rate[rateFlag];
6416 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT20_rate[rateFlag];
6417 }
6418
Leo Chang6f8870f2013-03-26 18:11:36 -07006419 maxSpeedMCS = 1;
6420 if (currentRate > maxRate)
6421 {
6422 maxRate = currentRate;
6423 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +05306424
Leo Chang6f8870f2013-03-26 18:11:36 -07006425 }
6426 else
6427#endif /* WLAN_FEATURE_11AC */
6428 {
6429 if (rate_flags & eHAL_TX_RATE_HT40)
6430 {
6431 rateFlag |= 1;
6432 }
6433 if (rate_flags & eHAL_TX_RATE_SGI)
6434 {
6435 rateFlag |= 2;
6436 }
6437
6438 for (i = 0; i < MCSLeng; i++)
6439 {
6440 temp = sizeof(supported_mcs_rate) / sizeof(supported_mcs_rate[0]);
6441 for (j = 0; j < temp; j++)
6442 {
6443 if (supported_mcs_rate[j].beacon_rate_index == MCSRates[i])
6444 {
6445 currentRate = supported_mcs_rate[j].supported_rate[rateFlag];
6446 break;
6447 }
6448 }
6449 if ((j < temp) && (currentRate > maxRate))
6450 {
6451 maxRate = currentRate;
6452 maxSpeedMCS = 1;
6453 maxMCSIdx = supported_mcs_rate[j].beacon_rate_index;
6454 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006455 }
6456 }
6457 }
6458
Gopichand Nakkala4c705372013-04-24 13:20:33 +05306459 else if (!(rate_flags & eHAL_TX_RATE_LEGACY))
6460 {
6461 maxRate = myRate;
6462 maxSpeedMCS = 1;
6463 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
6464 }
6465
Jeff Johnson295189b2012-06-20 16:38:30 -07006466 // make sure we report a value at least as big as our current rate
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07006467 if (((maxRate < myRate) && (0 == rssidx)) ||
6468 (0 == maxRate))
Jeff Johnson295189b2012-06-20 16:38:30 -07006469 {
6470 maxRate = myRate;
6471 if (rate_flags & eHAL_TX_RATE_LEGACY)
6472 {
6473 maxSpeedMCS = 0;
6474 }
6475 else
6476 {
6477 maxSpeedMCS = 1;
6478 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
6479 }
6480 }
6481
Gopichand Nakkala4c705372013-04-24 13:20:33 +05306482 if (rate_flags & eHAL_TX_RATE_LEGACY)
Jeff Johnson295189b2012-06-20 16:38:30 -07006483 {
6484 sinfo->txrate.legacy = maxRate;
6485#ifdef LINKSPEED_DEBUG_ENABLED
6486 pr_info("Reporting legacy rate %d\n", sinfo->txrate.legacy);
6487#endif //LINKSPEED_DEBUG_ENABLED
6488 }
6489 else
6490 {
6491 sinfo->txrate.mcs = maxMCSIdx;
Leo Chang6f8870f2013-03-26 18:11:36 -07006492#ifdef WLAN_FEATURE_11AC
6493 sinfo->txrate.nss = 1;
6494 if (rate_flags & eHAL_TX_RATE_VHT80)
6495 {
6496 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
Gopichand Nakkala4c705372013-04-24 13:20:33 +05306497 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
Leo Chang6f8870f2013-03-26 18:11:36 -07006498 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +05306499 else if (rate_flags & eHAL_TX_RATE_VHT40)
Leo Chang6f8870f2013-03-26 18:11:36 -07006500 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +05306501 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
6502 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
6503 }
6504 else if (rate_flags & eHAL_TX_RATE_VHT20)
6505 {
6506 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
6507 }
6508#endif /* WLAN_FEATURE_11AC */
6509 if (rate_flags & (eHAL_TX_RATE_HT20 | eHAL_TX_RATE_HT40))
6510 {
6511 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
6512 if (rate_flags & eHAL_TX_RATE_HT40)
6513 {
6514 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
6515 }
Leo Chang6f8870f2013-03-26 18:11:36 -07006516 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006517 if (rate_flags & eHAL_TX_RATE_SGI)
6518 {
6519 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
6520 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +05306521
Jeff Johnson295189b2012-06-20 16:38:30 -07006522#ifdef LINKSPEED_DEBUG_ENABLED
6523 pr_info("Reporting MCS rate %d flags %x\n",
6524 sinfo->txrate.mcs,
6525 sinfo->txrate.flags );
6526#endif //LINKSPEED_DEBUG_ENABLED
6527 }
6528 }
6529 else
6530 {
6531 // report current rate instead of max rate
6532
6533 if (rate_flags & eHAL_TX_RATE_LEGACY)
6534 {
6535 //provide to the UI in units of 100kbps
6536 sinfo->txrate.legacy = myRate;
6537#ifdef LINKSPEED_DEBUG_ENABLED
6538 pr_info("Reporting actual legacy rate %d\n", sinfo->txrate.legacy);
6539#endif //LINKSPEED_DEBUG_ENABLED
6540 }
6541 else
6542 {
6543 //must be MCS
6544 sinfo->txrate.mcs = pAdapter->hdd_stats.ClassA_stat.mcs_index;
Leo Chang6f8870f2013-03-26 18:11:36 -07006545#ifdef WLAN_FEATURE_11AC
6546 sinfo->txrate.nss = 1;
6547 if (rate_flags & eHAL_TX_RATE_VHT80)
6548 {
6549 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
6550 }
6551 else
6552#endif /* WLAN_FEATURE_11AC */
6553 {
6554 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
6555 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006556 if (rate_flags & eHAL_TX_RATE_SGI)
6557 {
6558 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
6559 }
6560 if (rate_flags & eHAL_TX_RATE_HT40)
6561 {
6562 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
6563 }
Leo Chang6f8870f2013-03-26 18:11:36 -07006564#ifdef WLAN_FEATURE_11AC
6565 else if (rate_flags & eHAL_TX_RATE_VHT80)
6566 {
6567 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
6568 }
6569#endif /* WLAN_FEATURE_11AC */
Jeff Johnson295189b2012-06-20 16:38:30 -07006570#ifdef LINKSPEED_DEBUG_ENABLED
6571 pr_info("Reporting actual MCS rate %d flags %x\n",
6572 sinfo->txrate.mcs,
6573 sinfo->txrate.flags );
6574#endif //LINKSPEED_DEBUG_ENABLED
6575 }
6576 }
6577 sinfo->filled |= STATION_INFO_TX_BITRATE;
6578
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -07006579 sinfo->tx_packets =
6580 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[0] +
6581 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[1] +
6582 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[2] +
6583 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[3];
6584
6585 sinfo->tx_retries =
6586 pAdapter->hdd_stats.summary_stat.retry_cnt[0] +
6587 pAdapter->hdd_stats.summary_stat.retry_cnt[1] +
6588 pAdapter->hdd_stats.summary_stat.retry_cnt[2] +
6589 pAdapter->hdd_stats.summary_stat.retry_cnt[3];
6590
6591 sinfo->tx_failed =
6592 pAdapter->hdd_stats.summary_stat.fail_cnt[0] +
6593 pAdapter->hdd_stats.summary_stat.fail_cnt[1] +
6594 pAdapter->hdd_stats.summary_stat.fail_cnt[2] +
6595 pAdapter->hdd_stats.summary_stat.fail_cnt[3];
6596
6597 sinfo->filled |=
6598 STATION_INFO_TX_PACKETS |
6599 STATION_INFO_TX_RETRIES |
6600 STATION_INFO_TX_FAILED;
6601
6602 EXIT();
6603 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07006604}
6605
6606static int wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
6607 struct net_device *dev, bool mode, v_SINT_t timeout)
6608{
6609 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +05306610 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07006611 VOS_STATUS vos_status;
6612
Jeff Johnsone7245742012-09-05 17:12:55 -07006613 ENTER();
6614
Jeff Johnson295189b2012-06-20 16:38:30 -07006615 if (NULL == pAdapter)
6616 {
6617 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL\n", __func__);
6618 return -ENODEV;
6619 }
6620
Gopichand Nakkala20c4c042013-04-19 22:08:55 +05306621 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
6622 if (NULL == pHddCtx)
6623 {
6624 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: HDD context is NULL\n", __func__);
6625 return -ENODEV;
6626 }
6627
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306628 if ( pHddCtx->isLogpInProgress )
6629 {
6630 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6631 "%s:LOGP in Progress. Ignore!!!", __func__);
6632 return -EAGAIN;
6633 }
6634
Gopichand Nakkala20c4c042013-04-19 22:08:55 +05306635 if ((DRIVER_POWER_MODE_AUTO == !mode) &&
6636 (TRUE == pHddCtx->hdd_wlan_suspended) &&
6637 (pHddCtx->cfg_ini->fhostArpOffload) &&
6638 (eConnectionState_Associated ==
6639 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
6640 {
6641 vos_status = hdd_conf_hostarpoffload(pAdapter, TRUE);
6642 if (!VOS_IS_STATUS_SUCCESS(vos_status))
6643 {
6644 hddLog(VOS_TRACE_LEVEL_INFO,
6645 "%s:Failed to enable ARPOFFLOAD Feature %d\n",
6646 __func__, vos_status);
6647 }
6648 }
6649
Jeff Johnson295189b2012-06-20 16:38:30 -07006650 /**The get power cmd from the supplicant gets updated by the nl only
6651 *on successful execution of the function call
6652 *we are oppositely mapped w.r.t mode in the driver
6653 **/
6654 vos_status = wlan_hdd_enter_bmps(pAdapter, !mode);
6655
Jeff Johnsone7245742012-09-05 17:12:55 -07006656 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07006657 if (VOS_STATUS_E_FAILURE == vos_status)
6658 {
6659 return -EINVAL;
6660 }
6661 return 0;
6662}
6663
6664
6665#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
6666static int wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
6667 struct net_device *netdev,
6668 u8 key_index)
6669{
Jeff Johnsone7245742012-09-05 17:12:55 -07006670 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07006671 return 0;
6672}
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306673#endif //LINUX_VERSION_CODE
Jeff Johnson295189b2012-06-20 16:38:30 -07006674
6675#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
6676static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
6677 struct net_device *dev,
6678 struct ieee80211_txq_params *params)
6679{
Jeff Johnsone7245742012-09-05 17:12:55 -07006680 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07006681 return 0;
6682}
6683#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
6684static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
6685 struct ieee80211_txq_params *params)
6686{
Jeff Johnsone7245742012-09-05 17:12:55 -07006687 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07006688 return 0;
6689}
6690#endif //LINUX_VERSION_CODE
6691
6692static int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
6693 struct net_device *dev, u8 *mac)
6694{
6695 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08006696 VOS_STATUS vos_status;
6697 v_U8_t staId;
Jeff Johnson295189b2012-06-20 16:38:30 -07006698
Jeff Johnsone7245742012-09-05 17:12:55 -07006699 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07006700 if ( NULL == pAdapter || NULL == pAdapter->pHddCtx)
6701 {
6702 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Invalid Adapter or HDD Context " ,__func__);
6703 return -EINVAL;
6704 }
6705
6706 if (((hdd_context_t*)pAdapter->pHddCtx)->isLoadUnloadInProgress)
6707 {
6708 hddLog( LOGE,
6709 "%s: Wlan Load/Unload is in progress", __func__);
6710 return -EBUSY;
6711 }
6712
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006713 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
6714 {
6715 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6716 "%s:LOGP in Progress. Ignore!!!", __func__);
6717 return -EAGAIN;
6718 }
6719
Jeff Johnson295189b2012-06-20 16:38:30 -07006720 if ( (WLAN_HDD_SOFTAP == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -07006721 || (WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -07006722 )
6723 {
6724 if( NULL == mac )
6725 {
6726 v_U16_t i;
6727 for(i = 0; i < WLAN_MAX_STA_COUNT; i++)
6728 {
6729 if(pAdapter->aStaInfo[i].isUsed)
6730 {
6731 u8 *macAddr = pAdapter->aStaInfo[i].macAddrSTA.bytes;
6732 hddLog(VOS_TRACE_LEVEL_INFO,
6733 "%s: Delete STA with MAC::"
6734 "%02x:%02x:%02x:%02x:%02x:%02x",
6735 __func__,
6736 macAddr[0], macAddr[1], macAddr[2],
6737 macAddr[3], macAddr[4], macAddr[5]);
6738 hdd_softap_sta_deauth(pAdapter, macAddr);
6739 }
6740 }
6741 }
6742 else
6743 {
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08006744
6745 vos_status = hdd_softap_GetStaId(pAdapter,(v_MACADDR_t *)mac, &staId);
6746 if (!VOS_IS_STATUS_SUCCESS(vos_status))
6747 {
6748 hddLog(VOS_TRACE_LEVEL_INFO,
6749 "%s: Skip this DEL STA as this is not used::"
6750 "%02x:%02x:%02x:%02x:%02x:%02x",
6751 __func__,
6752 mac[0], mac[1], mac[2],
6753 mac[3], mac[4], mac[5]);
6754 return -ENOENT;
6755 }
6756
6757 if( pAdapter->aStaInfo[staId].isDeauthInProgress == TRUE)
6758 {
6759 hddLog(VOS_TRACE_LEVEL_INFO,
6760 "%s: Skip this DEL STA as deauth is in progress::"
6761 "%02x:%02x:%02x:%02x:%02x:%02x",
6762 __func__,
6763 mac[0], mac[1], mac[2],
6764 mac[3], mac[4], mac[5]);
6765 return -ENOENT;
6766 }
6767
6768 pAdapter->aStaInfo[staId].isDeauthInProgress = TRUE;
6769
Jeff Johnson295189b2012-06-20 16:38:30 -07006770 hddLog(VOS_TRACE_LEVEL_INFO,
6771 "%s: Delete STA with MAC::"
6772 "%02x:%02x:%02x:%02x:%02x:%02x",
6773 __func__,
6774 mac[0], mac[1], mac[2],
6775 mac[3], mac[4], mac[5]);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08006776
6777 vos_status = hdd_softap_sta_deauth(pAdapter, mac);
6778 if (!VOS_IS_STATUS_SUCCESS(vos_status))
6779 {
6780 pAdapter->aStaInfo[staId].isDeauthInProgress = FALSE;
6781 hddLog(VOS_TRACE_LEVEL_INFO,
6782 "%s: STA removal failed for ::"
6783 "%02x:%02x:%02x:%02x:%02x:%02x",
6784 __func__,
6785 mac[0], mac[1], mac[2],
6786 mac[3], mac[4], mac[5]);
6787 return -ENOENT;
6788 }
6789
Jeff Johnson295189b2012-06-20 16:38:30 -07006790 }
6791 }
6792
6793 EXIT();
6794
6795 return 0;
6796}
6797
Hoonki Lee11f7dda2013-02-14 16:55:44 -08006798static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
6799 struct net_device *dev, u8 *mac, struct station_parameters *params)
6800{
Gopichand Nakkalab977a972013-02-18 19:15:09 -08006801 int status = -EPERM;
Hoonki Lee11f7dda2013-02-14 16:55:44 -08006802#ifdef FEATURE_WLAN_TDLS
6803 u32 mask, set;
Hoonki Lee11f7dda2013-02-14 16:55:44 -08006804 ENTER();
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006805 mask = params->sta_flags_mask;
6806
6807 set = params->sta_flags_set;
6808
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07006809#ifdef WLAN_FEATURE_TDLS_DEBUG
6810 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6811 "%s: mask 0x%x set 0x%x " MAC_ADDRESS_STR,
6812 __func__, mask, set, MAC_ADDR_ARRAY(mac));
6813#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006814
6815 if (mask & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
6816 if (set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006817 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 0, NULL);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006818 }
6819 }
6820#endif
Gopichand Nakkalab977a972013-02-18 19:15:09 -08006821 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -07006822}
6823
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006824
6825#ifdef FEATURE_WLAN_LFR
6826static int wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
Jeff Johnsond13512a2012-07-17 11:42:19 -07006827 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006828{
6829#define MAX_PMKSAIDS_IN_CACHE 8
6830 static tPmkidCacheInfo PMKIDCache[MAX_PMKSAIDS_IN_CACHE]; // HDD Local cache
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306831 static tANI_U32 i; // HDD Local Cache index
6832 tANI_U32 j=0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006833 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6834 tHalHandle halHandle;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306835 eHalStatus result;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006836 tANI_U8 BSSIDMatched = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306837
Jeff Johnsone7245742012-09-05 17:12:55 -07006838 ENTER();
6839
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306840 // Validate pAdapter
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006841 if ( NULL == pAdapter || NULL == pAdapter->pHddCtx)
6842 {
6843 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Invalid Adapter or HDD Context " ,__func__);
6844 return -EINVAL;
6845 }
6846
6847 if (((hdd_context_t*)pAdapter->pHddCtx)->isLoadUnloadInProgress)
6848 {
6849 hddLog( LOGE,
6850 "%s: Wlan Load/Unload is in progress", __func__);
6851 return -EBUSY;
6852 }
6853
6854 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
6855 {
6856 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6857 "%s:LOGP in Progress. Ignore!!!", __func__);
6858 return -EAGAIN;
6859 }
6860
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306861 // Retrieve halHandle
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006862 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
6863
6864 for (j = 0; j < i; j++)
6865 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306866 if(vos_mem_compare(PMKIDCache[j].BSSID,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006867 pmksa->bssid, WNI_CFG_BSSID_LEN))
6868 {
6869 /* BSSID matched previous entry. Overwrite it. */
6870 BSSIDMatched = 1;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306871 vos_mem_copy(PMKIDCache[j].BSSID,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006872 pmksa->bssid, WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306873 vos_mem_copy(PMKIDCache[j].PMKID,
6874 pmksa->pmkid,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006875 CSR_RSN_PMKID_SIZE);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306876 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Reusing cache entry %d.",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006877 __func__, j );
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006878 dump_bssid(pmksa->bssid);
6879 dump_pmkid(halHandle, pmksa->pmkid);
6880 break;
6881 }
6882 }
6883
Madan Mohan Koyyalamudic4b317d2012-10-18 19:43:08 -07006884 /* Check we compared all entries,if then take the first slot now */
6885 if(j == MAX_PMKSAIDS_IN_CACHE) i=0;
6886
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006887 if (!BSSIDMatched)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306888 {
6889 // Now, we DON'T have a BSSID match, so take a new entry in the cache.
6890 vos_mem_copy(PMKIDCache[i].BSSID,
6891 pmksa->bssid, ETHER_ADDR_LEN);
6892 vos_mem_copy(PMKIDCache[i].PMKID,
6893 pmksa->pmkid,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006894 CSR_RSN_PMKID_SIZE);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306895 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Adding a new cache entry %d.",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006896 __func__, i );
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006897 dump_bssid(pmksa->bssid);
6898 dump_pmkid(halHandle, pmksa->pmkid);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306899 // Increment the HDD Local Cache index
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006900 // The "i=0" doesn't work for the call to sme_RoamSetPMKIDCache() - LFR FIXME
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306901 if (i<=(MAX_PMKSAIDS_IN_CACHE-1)) i++; else i=0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006902 }
6903
6904
6905 // Calling csrRoamSetPMKIDCache to configure the PMKIDs into the cache
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306906 //hddLog(LOG1, FL("%s: Calling csrRoamSetPMKIDCache with %d cache entries."),
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006907 // __func__, i );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306908 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Calling csrRoamSetPMKIDCache with %d cache entries.",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006909 __func__, i );
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006910 // Finally set the PMKSA ID Cache in CSR
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306911 result = sme_RoamSetPMKIDCache(halHandle,pAdapter->sessionId,
6912 PMKIDCache,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006913 i );
6914 return 0;
6915}
6916
6917
6918static int wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
Jeff Johnsond13512a2012-07-17 11:42:19 -07006919 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006920{
Jeff Johnsone7245742012-09-05 17:12:55 -07006921 ENTER();
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006922 // TODO: Implement this later.
6923 return 0;
6924}
6925
6926static int wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
6927{
Jeff Johnsone7245742012-09-05 17:12:55 -07006928 ENTER();
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006929 // TODO: Implement this later.
6930 return 0;
6931}
6932#endif
6933
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07006934#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306935static int wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07006936 struct net_device *dev, struct cfg80211_update_ft_ies_params *ftie)
6937{
6938 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6939 hdd_station_ctx_t *pHddStaCtx;
6940
6941 if (NULL == pAdapter)
6942 {
6943 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL\n", __func__);
6944 return -ENODEV;
6945 }
6946
6947 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6948
6949 // Added for debug on reception of Re-assoc Req.
6950 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
6951 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306952 hddLog(LOGE, FL("Called with Ie of length = %d when not associated\n"),
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07006953 ftie->ie_len);
6954 hddLog(LOGE, FL("Should be Re-assoc Req IEs\n"));
6955 }
6956
6957#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306958 hddLog(LOGE, FL("%s called with Ie of length = %d\n"), __func__,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07006959 ftie->ie_len);
6960#endif
6961
6962 // Pass the received FT IEs to SME
Gopichand Nakkala356fb102013-03-06 12:34:04 +05306963 sme_SetFTIEs( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
6964 (const u8 *)ftie->ie,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07006965 ftie->ie_len);
6966 return 0;
6967}
6968#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006969
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006970#ifdef FEATURE_WLAN_TDLS
6971static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
6972 u8 *peer, u8 action_code, u8 dialog_token,
6973 u16 status_code, const u8 *buf, size_t len)
6974{
6975
6976 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6977 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006978 u8 peerMac[6];
6979 VOS_STATUS status;
Gopichand Nakkala05922802013-03-14 12:23:19 -07006980 int max_sta_failed = 0;
Hoonki Leea34dd892013-02-05 22:56:02 -08006981 int responder;
Hoonki Leed37cbb32013-04-20 00:31:14 -07006982 long rc;
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006983
Hoonki Lee11f7dda2013-02-14 16:55:44 -08006984 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006985 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306986 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006987 "Invalid arguments");
6988 return -EINVAL;
6989 }
6990
Sameer Thalappil75ea31a2013-02-21 19:38:16 -08006991 if (pHddCtx->isLogpInProgress)
6992 {
6993 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6994 "%s:LOGP in Progress. Ignore!!!", __func__);
Gopichand Nakkala05922802013-03-14 12:23:19 -07006995 wlan_hdd_tdls_set_link_status(pAdapter, peer, eTDLS_LINK_IDLE);
Sameer Thalappil75ea31a2013-02-21 19:38:16 -08006996 return -EBUSY;
6997 }
6998
Hoonki Lee27511902013-03-14 18:19:06 -07006999 if (eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode)
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007000 {
Hoonki Lee27511902013-03-14 18:19:06 -07007001 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
7002 "%s: TDLS mode is disabled OR not enabled in FW."
7003 MAC_ADDRESS_STR " action %d declined.",
7004 __func__, MAC_ADDR_ARRAY(peer), action_code);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007005 return -ENOTSUPP;
7006 }
Lee Hoonkic1262f22013-01-24 21:59:00 -08007007
Hoonki Lee27511902013-03-14 18:19:06 -07007008 /* other than teardown frame, other mgmt frames are not sent if disabled */
7009 if (SIR_MAC_TDLS_TEARDOWN != action_code)
7010 {
7011 /* if tdls_mode is disabled to respond to peer's request */
7012 if (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode)
7013 {
7014 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
7015 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07007016 " TDLS mode is disabled. action %d declined.",
7017 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee27511902013-03-14 18:19:06 -07007018
7019 return -ENOTSUPP;
7020 }
7021 }
7022
Gopichand Nakkalab977a972013-02-18 19:15:09 -08007023 if (WLAN_IS_TDLS_SETUP_ACTION(action_code))
7024 {
Hoonki Leefb8df672013-04-10 18:20:34 -07007025 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, peer, TRUE, TRUE))
Gopichand Nakkalab977a972013-02-18 19:15:09 -08007026 {
7027 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007028 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07007029 " TDLS setup is ongoing. action %d declined.",
7030 __func__, MAC_ADDR_ARRAY(peer), action_code);
7031 return -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -08007032 }
7033 }
7034
Hoonki Lee11f7dda2013-02-14 16:55:44 -08007035 if (SIR_MAC_TDLS_SETUP_REQ == action_code ||
7036 SIR_MAC_TDLS_SETUP_RSP == action_code )
Lee Hoonkic1262f22013-01-24 21:59:00 -08007037 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -08007038 if (HDD_MAX_NUM_TDLS_STA <= wlan_hdd_tdlsConnectedPeers(pAdapter))
Lee Hoonkic1262f22013-01-24 21:59:00 -08007039 {
7040 /* supplicant still sends tdls_mgmt(SETUP_REQ) even after
7041 we return error code at 'add_station()'. Hence we have this
7042 check again in addtion to add_station().
7043 Anyway, there is no hard to double-check. */
Hoonki Lee11f7dda2013-02-14 16:55:44 -08007044 if (SIR_MAC_TDLS_SETUP_REQ == action_code)
Lee Hoonkic1262f22013-01-24 21:59:00 -08007045 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007046 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7047 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07007048 " TDLS Max peer already connected. action %d declined.",
7049 __func__, MAC_ADDR_ARRAY(peer), action_code);
Gopichand Nakkala05922802013-03-14 12:23:19 -07007050 goto error;
Lee Hoonkic1262f22013-01-24 21:59:00 -08007051 }
7052 else
7053 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -08007054 /* maximum reached. tweak to send error code to peer and return
7055 error code to supplicant */
Lee Hoonkic1262f22013-01-24 21:59:00 -08007056 status_code = eSIR_MAC_UNSPEC_FAILURE_STATUS;
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007057 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7058 "%s: " MAC_ADDRESS_STR
7059 " TDLS Max peer already connected send response status %d",
7060 __func__, MAC_ADDR_ARRAY(peer), status_code);
Gopichand Nakkala05922802013-03-14 12:23:19 -07007061 max_sta_failed = -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -08007062 /* fall through to send setup resp with failure status
7063 code */
Lee Hoonkic1262f22013-01-24 21:59:00 -08007064 }
7065 }
Hoonki Lee11f7dda2013-02-14 16:55:44 -08007066 else
7067 {
7068 hddTdlsPeer_t *pTdlsPeer;
Gopichand Nakkala4327a152013-03-04 23:22:42 -08007069 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007070 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Hoonki Lee11f7dda2013-02-14 16:55:44 -08007071 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007072 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07007073 "%s:" MAC_ADDRESS_STR " already connected. action %d declined.",
7074 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee11f7dda2013-02-14 16:55:44 -08007075 return -EPERM;
7076 }
7077 }
Lee Hoonkic1262f22013-01-24 21:59:00 -08007078 }
Hoonki Lee11f7dda2013-02-14 16:55:44 -08007079 vos_mem_copy(peerMac, peer, 6);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007080
Hoonki Lee1090c6a2013-01-16 17:40:54 -08007081#ifdef WLAN_FEATURE_TDLS_DEBUG
7082 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007083 "%s: " MAC_ADDRESS_STR " action %d, dialog_token %d status %d, len = %d",
7084 "tdls_mgmt", MAC_ADDR_ARRAY(peer),
7085 action_code, dialog_token, status_code, len);
Hoonki Lee1090c6a2013-01-16 17:40:54 -08007086#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007087
Hoonki Leea34dd892013-02-05 22:56:02 -08007088 /*Except teardown responder will not be used so just make 0*/
7089 responder = 0;
Hoonki Lee11f7dda2013-02-14 16:55:44 -08007090 if (SIR_MAC_TDLS_TEARDOWN == action_code)
Hoonki Leea34dd892013-02-05 22:56:02 -08007091 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -07007092
7093 hddTdlsPeer_t *pTdlsPeer;
7094 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peerMac);
7095
7096 if(pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
7097 responder = pTdlsPeer->is_responder;
7098 else
Hoonki Leea34dd892013-02-05 22:56:02 -08007099 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -07007100 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7101 "%s: " MAC_ADDRESS_STR " peer doesn't exist or not connected %d dialog_token %d status %d, len = %d",
7102 __func__, MAC_ADDR_ARRAY(peer), (NULL == pTdlsPeer) ? -1 : pTdlsPeer->link_status,
7103 dialog_token, status_code, len);
7104 return -EPERM;
Hoonki Leea34dd892013-02-05 22:56:02 -08007105 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007106 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007107
Hoonki Lee14621352013-04-16 17:51:19 -07007108 if ((SIR_MAC_TDLS_SETUP_RSP == action_code) ||
7109 (SIR_MAC_TDLS_DIS_RSP == action_code))
7110 {
7111 if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter)))
7112 {
7113 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
7114 "%s: Sending Disc/Setup Rsp Frame.Disable BMPS", __func__);
7115 hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
7116 }
7117 wlan_hdd_tdls_set_cap(pAdapter, peerMac, eTDLS_CAP_SUPPORTED);
7118 }
7119
Gopichand Nakkalab977a972013-02-18 19:15:09 -08007120 INIT_COMPLETION(pAdapter->tdls_mgmt_comp);
7121
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007122 status = sme_SendTdlsMgmtFrame(WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
Hoonki Leea34dd892013-02-05 22:56:02 -08007123 peerMac, action_code, dialog_token, status_code, (tANI_U8 *)buf, len, responder);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007124
Gopichand Nakkalab977a972013-02-18 19:15:09 -08007125 if (VOS_STATUS_SUCCESS != status)
7126 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007127 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7128 "%s: sme_SendTdlsMgmtFrame failed!", __func__);
Hoonki Lee14621352013-04-16 17:51:19 -07007129 wlan_hdd_tdls_check_bmps(pAdapter);
7130 goto error;
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007131 }
7132
Hoonki Leed37cbb32013-04-20 00:31:14 -07007133 rc = wait_for_completion_interruptible_timeout(&pAdapter->tdls_mgmt_comp,
7134 msecs_to_jiffies(WAIT_TIME_TDLS_MGMT));
7135
7136 if ((rc <= 0) || (TRUE != pAdapter->mgmtTxCompletionStatus))
Gopichand Nakkalab977a972013-02-18 19:15:09 -08007137 {
Hoonki Leed37cbb32013-04-20 00:31:14 -07007138 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7139 "%s: Mgmt Tx Completion failed status %ld TxCompletion %lu",
7140 __func__, rc, pAdapter->mgmtTxCompletionStatus);
7141 wlan_hdd_tdls_check_bmps(pAdapter);
7142 goto error;
Gopichand Nakkalab977a972013-02-18 19:15:09 -08007143 }
7144
Gopichand Nakkala05922802013-03-14 12:23:19 -07007145 if (max_sta_failed)
Hoonki Lee14621352013-04-16 17:51:19 -07007146 {
7147 wlan_hdd_tdls_check_bmps(pAdapter);
Gopichand Nakkala05922802013-03-14 12:23:19 -07007148 return max_sta_failed;
Hoonki Lee14621352013-04-16 17:51:19 -07007149 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -08007150
Hoonki Leea34dd892013-02-05 22:56:02 -08007151 if (SIR_MAC_TDLS_SETUP_RSP == action_code)
7152 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -08007153 wlan_hdd_tdls_set_responder(pAdapter, peerMac, TRUE);
Hoonki Leea34dd892013-02-05 22:56:02 -08007154 }
7155 else if (SIR_MAC_TDLS_SETUP_CNF == action_code)
7156 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -08007157 wlan_hdd_tdls_set_responder(pAdapter, peerMac, FALSE);
Hoonki Leea34dd892013-02-05 22:56:02 -08007158 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007159
7160 return 0;
Gopichand Nakkala05922802013-03-14 12:23:19 -07007161error:
7162 /* max_sta_failed ; we didn't set to CONNECTING for this case,
7163 because we already know that this transaction will be failed,
7164 but we weren't sure if supplicant call DISABLE_LINK or not. So,
7165 to be safe, do not change the state mahine.
7166 */
7167 if(max_sta_failed == 0 &&
7168 (WLAN_IS_TDLS_SETUP_ACTION(action_code)))
7169 wlan_hdd_tdls_set_link_status(pAdapter, peerMac, eTDLS_LINK_IDLE);
7170 return -EPERM;
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007171}
7172
7173static int wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
7174 u8 *peer, enum nl80211_tdls_operation oper)
7175{
7176 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
7177 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Hoonki Lee1090c6a2013-01-16 17:40:54 -08007178#ifdef WLAN_FEATURE_TDLS_DEBUG
7179 const char *tdls_oper_str[]= {
7180 "NL80211_TDLS_DISCOVERY_REQ",
7181 "NL80211_TDLS_SETUP",
7182 "NL80211_TDLS_TEARDOWN",
7183 "NL80211_TDLS_ENABLE_LINK",
7184 "NL80211_TDLS_DISABLE_LINK",
7185 "NL80211_TDLS_UNKONW_OPER"};
7186#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007187
Chilam Ngc4244af2013-04-01 15:37:32 -07007188 if ( NULL == pHddCtx || NULL == pHddCtx->cfg_ini || NULL == peer )
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007189 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -08007190 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chilam Ngc4244af2013-04-01 15:37:32 -07007191 "%s: Invalid arguments", __func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007192 return -EINVAL;
7193 }
Hoonki Lee1090c6a2013-01-16 17:40:54 -08007194
Sameer Thalappil75ea31a2013-02-21 19:38:16 -08007195 if (pHddCtx->isLogpInProgress)
7196 {
7197 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7198 "%s:LOGP in Progress. Ignore!!!", __func__);
7199 return -EBUSY;
7200 }
7201
Hoonki Lee1090c6a2013-01-16 17:40:54 -08007202#ifdef WLAN_FEATURE_TDLS_DEBUG
7203 if((int)oper > 4)
7204 oper = 5;
7205
7206 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007207 "%s: " MAC_ADDRESS_STR " %d (%s) ", "tdls_oper",
7208 MAC_ADDR_ARRAY(peer), (int)oper,
7209 tdls_oper_str[(int)oper]);
Hoonki Lee1090c6a2013-01-16 17:40:54 -08007210#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007211
7212 if( FALSE == pHddCtx->cfg_ini->fEnableTDLSSupport ||
Hoonki Lee1090c6a2013-01-16 17:40:54 -08007213 FALSE == sme_IsFeatureSupportedByFW(TDLS))
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007214 {
Hoonki Lee1090c6a2013-01-16 17:40:54 -08007215 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chilam Ngc4244af2013-04-01 15:37:32 -07007216 "TDLS Disabled in INI OR not enabled in FW. "
7217 "Cannot process TDLS commands");
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007218 return -ENOTSUPP;
7219 }
7220
7221 switch (oper) {
7222 case NL80211_TDLS_ENABLE_LINK:
7223 {
Hoonki Lee387663d2013-02-05 18:08:43 -08007224 hddTdlsPeer_t *pTdlsPeer;
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007225 VOS_STATUS status;
7226
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007227 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007228
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007229 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
7230 "%s: TDLS_LINK_ENABLE " MAC_ADDRESS_STR,
7231 __func__, MAC_ADDR_ARRAY(peer));
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007232
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007233 if ( NULL == pTdlsPeer ) {
7234 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wlan_hdd_tdls_find_peer "
7235 MAC_ADDRESS_STR " failed",
7236 __func__, MAC_ADDR_ARRAY(peer));
7237 return -EINVAL;
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007238 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007239
Gopichand Nakkala2f4a2822013-04-17 11:22:01 -07007240 if (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
7241 {
7242 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Staion Index %u "
7243 MAC_ADDRESS_STR " failed",
7244 __func__, pTdlsPeer->staId, MAC_ADDR_ARRAY(peer));
7245 return -EINVAL;
7246 }
7247
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007248 if (eTDLS_LINK_CONNECTING == pTdlsPeer->link_status)
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007249 {
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -07007250 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer, eTDLS_LINK_CONNECTED);
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007251 /* start TDLS client registration with TL */
7252 status = hdd_roamRegisterTDLSSTA( pAdapter, peer, pTdlsPeer->staId, pTdlsPeer->signature);
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -07007253 if (VOS_STATUS_SUCCESS == status)
7254 {
Hoonki Lee14621352013-04-16 17:51:19 -07007255 if (pTdlsPeer->is_responder == 0)
7256 {
7257 v_U8_t staId = (v_U8_t)pTdlsPeer->staId;
7258
7259 wlan_hdd_tdls_timer_restart(pAdapter,
7260 &pTdlsPeer->initiatorWaitTimeoutTimer,
7261 WAIT_TIME_TDLS_INITIATOR);
7262 /* suspend initiator TX until it receives direct packet from the
7263 reponder or WAIT_TIME_TDLS_INITIATOR timer expires */
7264 WLANTL_SuspendDataTx( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
7265 &staId, NULL);
7266 }
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -07007267 wlan_hdd_tdls_increment_peer_count(pAdapter);
7268 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007269 wlan_hdd_tdls_check_bmps(pAdapter);
7270 }
7271
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007272 }
7273 break;
7274 case NL80211_TDLS_DISABLE_LINK:
Lee Hoonkic1262f22013-01-24 21:59:00 -08007275 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -08007276 hddTdlsPeer_t *curr_peer = wlan_hdd_tdls_find_peer(pAdapter, peer);
Gopichand Nakkalab977a972013-02-18 19:15:09 -08007277
Gopichand Nakkala2f4a2822013-04-17 11:22:01 -07007278 if((NULL != curr_peer) && TDLS_STA_INDEX_VALID(curr_peer->staId))
Lee Hoonkic1262f22013-01-24 21:59:00 -08007279 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007280 long status;
7281
7282 INIT_COMPLETION(pAdapter->tdls_del_station_comp);
7283
Lee Hoonkic1262f22013-01-24 21:59:00 -08007284 sme_DeleteTdlsPeerSta( WLAN_HDD_GET_HAL_CTX(pAdapter),
7285 pAdapter->sessionId, peer );
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007286
7287 status = wait_for_completion_interruptible_timeout(&pAdapter->tdls_del_station_comp,
7288 msecs_to_jiffies(WAIT_TIME_TDLS_DEL_STA));
7289 if (status <= 0)
7290 {
7291 wlan_hdd_tdls_set_peer_link_status(curr_peer, eTDLS_LINK_IDLE);
7292 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7293 "%s: Del station failed status %ld",
7294 __func__, status);
7295 return -EPERM;
7296 }
Gopichand Nakkala8b00c632013-03-08 19:47:52 -08007297 wlan_hdd_tdls_set_peer_link_status(curr_peer, eTDLS_LINK_IDLE);
Lee Hoonkic1262f22013-01-24 21:59:00 -08007298 }
7299 else
7300 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007301 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7302 "%s: TDLS Peer Station doesn't exist.", __func__);
Lee Hoonkic1262f22013-01-24 21:59:00 -08007303 }
Lee Hoonkic1262f22013-01-24 21:59:00 -08007304 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007305 break;
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007306 case NL80211_TDLS_TEARDOWN:
7307 case NL80211_TDLS_SETUP:
7308 case NL80211_TDLS_DISCOVERY_REQ:
7309 /* We don't support in-driver setup/teardown/discovery */
7310 return -ENOTSUPP;
7311 default:
7312 return -ENOTSUPP;
7313 }
7314 return 0;
7315}
Chilam NG571c65a2013-01-19 12:27:36 +05307316
7317int wlan_hdd_cfg80211_send_tdls_discover_req(struct wiphy *wiphy,
7318 struct net_device *dev, u8 *peer)
7319{
7320 hddLog(VOS_TRACE_LEVEL_INFO, "tdls send discover req: %x %x %x %x %x %x",
7321 peer[0], peer[1], peer[2], peer[3], peer[4], peer[5]);
7322
7323 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
7324 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, NULL, 0);
7325}
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007326#endif
7327
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05307328#ifdef WLAN_FEATURE_GTK_OFFLOAD
7329/*
7330 * FUNCTION: wlan_hdd_cfg80211_update_replayCounterCallback
7331 * Callback rountine called upon receiving response for
7332 * get offload info
7333 */
7334void wlan_hdd_cfg80211_update_replayCounterCallback(void *callbackContext,
7335 tpSirGtkOffloadGetInfoRspParams pGtkOffloadGetInfoRsp)
7336{
7337
7338 hdd_adapter_t *pAdapter = (hdd_adapter_t *)callbackContext;
7339
7340 ENTER();
7341
7342 if (NULL == pAdapter)
7343 {
7344 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
7345 "%s: HDD adapter is Null", __func__);
7346 return ;
7347 }
7348
7349 if (NULL == pGtkOffloadGetInfoRsp)
7350 {
7351 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7352 "%s: pGtkOffloadGetInfoRsp is Null", __func__);
7353 return ;
7354 }
7355
7356 if (VOS_STATUS_SUCCESS != pGtkOffloadGetInfoRsp->ulStatus)
7357 {
7358 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7359 "%s: wlan Failed to get replay counter value",
7360 __func__);
7361 return ;
7362 }
7363
7364 /* Update replay counter to NL */
7365 cfg80211_gtk_rekey_notify(pAdapter->dev, pGtkOffloadGetInfoRsp->bssId,
7366 (tANI_U8 *)&pGtkOffloadGetInfoRsp->ullKeyReplayCounter, GFP_KERNEL);
7367}
7368
7369/*
7370 * FUNCTION: wlan_hdd_cfg80211_set_rekey_data
7371 * This function is used to offload GTK rekeying job to the firmware.
7372 */
7373int wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
7374 struct cfg80211_gtk_rekey_data *data)
7375{
7376 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
7377 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
7378 hdd_station_ctx_t *pHddStaCtx;
7379 tHalHandle hHal;
7380 tpSirGtkOffloadParams pGtkOffloadReqParams;
7381 eHalStatus status = eHAL_STATUS_FAILURE;
7382
7383 ENTER();
7384
7385 if (NULL == pAdapter)
7386 {
7387 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
7388 "%s: HDD adapter is Null", __func__);
7389 return -ENODEV;
7390 }
7391
7392 if (NULL == pHddCtx)
7393 {
7394 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7395 "%s: HDD context is Null!!!", __func__);
7396 return -ENODEV;
7397 }
7398
7399 if (pHddCtx->isLogpInProgress)
7400 {
7401 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
7402 "%s: LOGP in Progress. Ignore!!!", __func__);
7403 return -EAGAIN;
7404 }
7405
7406 if (pHddCtx->isLoadUnloadInProgress)
7407 {
7408 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
7409 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
7410 return -EAGAIN;
7411 }
7412
7413 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7414 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
7415 if (NULL == hHal)
7416 {
7417 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7418 "%s: HAL context is Null!!!", __func__);
7419 return -EAGAIN;
7420 }
7421
7422 pGtkOffloadReqParams =
7423 &pHddStaCtx->gtkOffloadRequestParams.gtkOffloadReqParams;
7424
7425 pGtkOffloadReqParams->ulFlags = GTK_OFFLOAD_ENABLE;
7426 memcpy(pGtkOffloadReqParams->aKCK, data->kck, NL80211_KCK_LEN);
7427 memcpy(pGtkOffloadReqParams->aKEK, data->kek, NL80211_KEK_LEN);
7428 memcpy(pGtkOffloadReqParams->bssId, &pHddStaCtx->conn_info.bssId,
7429 WNI_CFG_BSSID_LEN);
7430 memcpy(&pGtkOffloadReqParams->ullKeyReplayCounter, &data->replay_ctr,
7431 sizeof (tANI_U64));
7432
7433 if (TRUE == pHddCtx->hdd_wlan_suspended)
7434 {
7435 /* if wlan is suspended, enable GTK offload directly from here */
7436 status = sme_SetGTKOffload(hHal, pGtkOffloadReqParams,
7437 pAdapter->sessionId);
7438
7439 if (eHAL_STATUS_SUCCESS != status)
7440 {
7441 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7442 "%s: sme_SetGTKOffload failed, returned %d",
7443 __func__, status);
7444 return status;
7445 }
7446 pHddStaCtx->gtkOffloadRequestParams.requested = FALSE;
7447 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
7448 "%s: sme_SetGTKOffload successfull", __func__);
7449 }
7450 else
7451 {
7452 pHddStaCtx->gtkOffloadRequestParams.requested = TRUE;
7453 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
7454 "%s: wlan not suspended GTKOffload request is stored",
7455 __func__);
7456 return eHAL_STATUS_SUCCESS;
7457 }
7458 return status;
7459}
7460#endif /*WLAN_FEATURE_GTK_OFFLOAD*/
7461
Jeff Johnson295189b2012-06-20 16:38:30 -07007462/* cfg80211_ops */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307463static struct cfg80211_ops wlan_hdd_cfg80211_ops =
Jeff Johnson295189b2012-06-20 16:38:30 -07007464{
7465 .add_virtual_intf = wlan_hdd_add_virtual_intf,
7466 .del_virtual_intf = wlan_hdd_del_virtual_intf,
7467 .change_virtual_intf = wlan_hdd_cfg80211_change_iface,
7468 .change_station = wlan_hdd_change_station,
7469#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
7470 .add_beacon = wlan_hdd_cfg80211_add_beacon,
7471 .del_beacon = wlan_hdd_cfg80211_del_beacon,
7472 .set_beacon = wlan_hdd_cfg80211_set_beacon,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007473#else
7474 .start_ap = wlan_hdd_cfg80211_start_ap,
7475 .change_beacon = wlan_hdd_cfg80211_change_beacon,
7476 .stop_ap = wlan_hdd_cfg80211_stop_ap,
Jeff Johnson295189b2012-06-20 16:38:30 -07007477#endif
7478 .change_bss = wlan_hdd_cfg80211_change_bss,
7479 .add_key = wlan_hdd_cfg80211_add_key,
7480 .get_key = wlan_hdd_cfg80211_get_key,
7481 .del_key = wlan_hdd_cfg80211_del_key,
7482 .set_default_key = wlan_hdd_cfg80211_set_default_key,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -08007483#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07007484 .set_channel = wlan_hdd_cfg80211_set_channel,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -08007485#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007486 .scan = wlan_hdd_cfg80211_scan,
7487 .connect = wlan_hdd_cfg80211_connect,
7488 .disconnect = wlan_hdd_cfg80211_disconnect,
7489 .join_ibss = wlan_hdd_cfg80211_join_ibss,
7490 .leave_ibss = wlan_hdd_cfg80211_leave_ibss,
7491 .set_wiphy_params = wlan_hdd_cfg80211_set_wiphy_params,
7492 .set_tx_power = wlan_hdd_cfg80211_set_txpower,
7493 .get_tx_power = wlan_hdd_cfg80211_get_txpower,
Jeff Johnson295189b2012-06-20 16:38:30 -07007494 .remain_on_channel = wlan_hdd_cfg80211_remain_on_channel,
7495 .cancel_remain_on_channel = wlan_hdd_cfg80211_cancel_remain_on_channel,
7496 .mgmt_tx = wlan_hdd_action,
7497#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
7498 .mgmt_tx_cancel_wait = wlan_hdd_cfg80211_mgmt_tx_cancel_wait,
7499 .set_default_mgmt_key = wlan_hdd_set_default_mgmt_key,
7500 .set_txq_params = wlan_hdd_set_txq_params,
7501#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007502 .get_station = wlan_hdd_cfg80211_get_station,
7503 .set_power_mgmt = wlan_hdd_cfg80211_set_power_mgmt,
7504 .del_station = wlan_hdd_cfg80211_del_station,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007505 .add_station = wlan_hdd_cfg80211_add_station,
7506#ifdef FEATURE_WLAN_LFR
7507 .set_pmksa = wlan_hdd_cfg80211_set_pmksa,
7508 .del_pmksa = wlan_hdd_cfg80211_del_pmksa,
7509 .flush_pmksa = wlan_hdd_cfg80211_flush_pmksa,
7510#endif
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07007511#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
7512 .update_ft_ies = wlan_hdd_cfg80211_update_ft_ies,
7513#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007514#ifdef FEATURE_WLAN_TDLS
7515 .tdls_mgmt = wlan_hdd_cfg80211_tdls_mgmt,
7516 .tdls_oper = wlan_hdd_cfg80211_tdls_oper,
7517#endif
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05307518#ifdef WLAN_FEATURE_GTK_OFFLOAD
7519 .set_rekey_data = wlan_hdd_cfg80211_set_rekey_data,
7520#endif /* WLAN_FEATURE_GTK_OFFLOAD */
Jeff Johnson295189b2012-06-20 16:38:30 -07007521};
7522