blob: bd7d516c36693476a2b2cccc9c7f63e4e393e32b [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);
Shailender Karmuchia734f332013-04-19 14:02:48 -07002553 pAdapter->device_mode = WLAN_HDD_IBSS;
Jeff Johnson295189b2012-06-20 16:38:30 -07002554 wdev->iftype = type;
2555 break;
2556
2557 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -07002558 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07002559 {
2560 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
2561 "%s: setting interface Type to %s", __func__,
2562 (type == NL80211_IFTYPE_AP) ? "SoftAP" : "P2pGo");
2563
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08002564 //Cancel any remain on channel for GO mode
2565 if (NL80211_IFTYPE_P2P_GO == type)
2566 {
2567 wlan_hdd_cancel_existing_remain_on_channel(pAdapter);
2568 }
Mohit Khanna0f232092012-09-11 14:46:08 -07002569 if (NL80211_IFTYPE_AP == type)
2570 {
2571 /* As Loading WLAN Driver one interface being created for p2p device
2572 * address. This will take one HW STA and the max number of clients
2573 * that can connect to softAP will be reduced by one. so while changing
2574 * the interface type to NL80211_IFTYPE_AP (SoftAP) remove p2p0
2575 * interface as it is not required in SoftAP mode.
2576 */
2577
2578 // Get P2P Adapter
2579 pP2pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_DEVICE);
2580
2581 if (pP2pAdapter)
2582 {
2583 hdd_stop_adapter(pHddCtx, pP2pAdapter);
2584 hdd_deinit_adapter(pHddCtx, pP2pAdapter);
2585 hdd_close_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
2586 }
2587 }
2588
Jeff Johnson295189b2012-06-20 16:38:30 -07002589 //De-init the adapter.
2590 hdd_stop_adapter( pHddCtx, pAdapter );
2591 hdd_deinit_adapter( pHddCtx, pAdapter );
2592 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
Jeff Johnson295189b2012-06-20 16:38:30 -07002593 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
2594 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Jeff Johnson32d95a32012-09-10 13:15:23 -07002595
2596 //Disable BMPS and IMPS if enabled
2597 //before starting Go
2598 if(WLAN_HDD_P2P_GO == pAdapter->device_mode)
2599 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302600 if(VOS_STATUS_E_FAILURE ==
Jeff Johnson32d95a32012-09-10 13:15:23 -07002601 hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_P2P_GO))
2602 {
2603 //Fail to Exit BMPS
2604 VOS_ASSERT(0);
2605 }
2606 }
2607
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -07002608 if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) &&
2609 (pConfig->apRandomBssidEnabled))
2610 {
2611 /* To meet Android requirements create a randomized
2612 MAC address of the form 02:1A:11:Fx:xx:xx */
2613 get_random_bytes(&ndev->dev_addr[3], 3);
2614 ndev->dev_addr[0] = 0x02;
2615 ndev->dev_addr[1] = 0x1A;
2616 ndev->dev_addr[2] = 0x11;
2617 ndev->dev_addr[3] |= 0xF0;
2618 memcpy(pAdapter->macAddressCurrent.bytes, ndev->dev_addr,
2619 VOS_MAC_ADDR_SIZE);
2620 pr_info("wlan: Generated HotSpot BSSID "
2621 "%02x:%02x:%02x:%02x:%02x:%02x\n",
2622 ndev->dev_addr[0],
2623 ndev->dev_addr[1],
2624 ndev->dev_addr[2],
2625 ndev->dev_addr[3],
2626 ndev->dev_addr[4],
2627 ndev->dev_addr[5]);
2628 }
2629
Jeff Johnson295189b2012-06-20 16:38:30 -07002630 hdd_set_ap_ops( pAdapter->dev );
2631
2632 status = hdd_init_ap_mode(pAdapter);
2633 if(status != VOS_STATUS_SUCCESS)
2634 {
2635 hddLog(VOS_TRACE_LEVEL_FATAL,
2636 "%s: Error initializing the ap mode", __func__);
2637 return -EINVAL;
2638 }
2639 hdd_set_conparam(1);
2640
Jeff Johnson295189b2012-06-20 16:38:30 -07002641 /*interface type changed update in wiphy structure*/
2642 if(wdev)
2643 {
2644 wdev->iftype = type;
2645 pHddCtx->change_iface = type;
2646 }
2647 else
2648 {
2649 hddLog(VOS_TRACE_LEVEL_ERROR,
2650 "%s: ERROR !!!! Wireless dev is NULL", __func__);
2651 return -EINVAL;
2652 }
2653 goto done;
2654 }
2655
2656 default:
2657 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
2658 __func__);
2659 return -EOPNOTSUPP;
2660 }
2661 }
2662 else if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07002663 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07002664 )
2665 {
2666 switch(type)
2667 {
2668 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -07002669 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -07002670 case NL80211_IFTYPE_ADHOC:
Jeff Johnson32d95a32012-09-10 13:15:23 -07002671 hdd_stop_adapter( pHddCtx, pAdapter );
2672 hdd_deinit_adapter( pHddCtx, pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07002673 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08002674 //Check for sub-string p2p to confirm its a p2p interface
2675 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala864d3552012-12-31 16:08:51 -08002676 {
2677 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
2678 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
2679 }
2680 else
2681 {
2682 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -07002683 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -08002684 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002685 hdd_set_conparam(0);
2686 pHddCtx->change_iface = type;
Jeff Johnson295189b2012-06-20 16:38:30 -07002687 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
2688 hdd_set_station_ops( pAdapter->dev );
2689 status = hdd_init_station_mode( pAdapter );
2690 if( VOS_STATUS_SUCCESS != status )
2691 return -EOPNOTSUPP;
Jeff Johnsone7245742012-09-05 17:12:55 -07002692 /* In case of JB, for P2P-GO, only change interface will be called,
2693 * This is the right place to enable back bmps_imps()
2694 */
2695 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07002696 goto done;
2697 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -07002698 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07002699 wdev->iftype = type;
Jeff Johnson295189b2012-06-20 16:38:30 -07002700 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
2701 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Jeff Johnson295189b2012-06-20 16:38:30 -07002702 goto done;
2703 default:
2704 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
2705 __func__);
2706 return -EOPNOTSUPP;
2707
2708 }
2709
2710 }
2711 else
2712 {
2713 return -EOPNOTSUPP;
2714 }
2715
2716
2717 if(pRoamProfile)
2718 {
2719 if ( LastBSSType != pRoamProfile->BSSType )
2720 {
2721 /*interface type changed update in wiphy structure*/
2722 wdev->iftype = type;
2723
2724 /*the BSS mode changed, We need to issue disconnect
2725 if connected or in IBSS disconnect state*/
2726 if ( hdd_connGetConnectedBssType(
2727 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), &connectedBssType ) ||
2728 ( eCSR_BSS_TYPE_START_IBSS == LastBSSType ) )
2729 {
2730 /*need to issue a disconnect to CSR.*/
2731 INIT_COMPLETION(pAdapter->disconnect_comp_var);
2732 if( eHAL_STATUS_SUCCESS ==
2733 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
2734 pAdapter->sessionId,
2735 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
2736 {
2737 wait_for_completion_interruptible_timeout(
2738 &pAdapter->disconnect_comp_var,
2739 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
2740 }
2741 }
2742 }
2743 }
2744
2745done:
2746 /*set bitmask based on updated value*/
2747 wlan_hdd_set_concurrency_mode(pHddCtx, pAdapter->device_mode);
2748#ifdef WLAN_BTAMP_FEATURE
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302749 if((NL80211_IFTYPE_STATION == type) && (pHddCtx->concurrency_mode <= 1) &&
Jeff Johnson295189b2012-06-20 16:38:30 -07002750 (pHddCtx->no_of_sessions[WLAN_HDD_INFRA_STATION] <=1))
2751 {
2752 //we are ok to do AMP
2753 pHddCtx->isAmpAllowed = VOS_TRUE;
2754 }
2755#endif //WLAN_BTAMP_FEATURE
2756 EXIT();
2757 return 0;
2758}
2759
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002760#ifdef FEATURE_WLAN_TDLS
2761static int wlan_hdd_tdls_add_station(struct wiphy *wiphy,
2762 struct net_device *dev, u8 *mac, bool update, tCsrStaParams *StaParams)
2763{
2764 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2765 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
2766 VOS_STATUS status;
2767
2768 ENTER();
2769
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05302770 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002771 {
2772 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2773 "Invalid arguments");
2774 return -EINVAL;
2775 }
Hoonki Lee27511902013-03-14 18:19:06 -07002776
2777 if ((eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode) ||
2778 (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode))
2779 {
2780 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2781 "%s: TDLS mode is disabled OR not enabled in FW."
2782 MAC_ADDRESS_STR " Request declined.",
2783 __func__, MAC_ADDR_ARRAY(mac));
2784 return -ENOTSUPP;
2785 }
2786
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002787 if (pHddCtx->isLogpInProgress)
2788 {
2789 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2790 "%s:LOGP in Progress. Ignore!!!", __func__);
Gopichand Nakkala05922802013-03-14 12:23:19 -07002791 wlan_hdd_tdls_set_link_status(pAdapter, mac, eTDLS_LINK_IDLE);
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002792 return -EBUSY;
2793 }
2794
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07002795 /* when self is on-going, we dont' want to change link_status */
2796 if ((0 == update) && wlan_hdd_tdls_is_peer_progress(pAdapter, mac))
2797 {
2798 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2799 "%s: " MAC_ADDRESS_STR
2800 " TDLS setup is ongoing. Request declined.",
2801 __func__, MAC_ADDR_ARRAY(mac));
2802 return -EPERM;
2803 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07002804 /* when self is not on-ongoing, we don't want to allow change_station */
2805 if ((1 == update) && !wlan_hdd_tdls_is_peer_progress(pAdapter, mac))
2806 {
2807 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2808 "%s: " MAC_ADDRESS_STR
2809 " TDLS is not connecting. change station declined.",
2810 __func__, MAC_ADDR_ARRAY(mac));
2811 return -EPERM;
2812 }
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07002813
2814 /* when others are on-going, we want to change link_status to idle */
Hoonki Leefb8df672013-04-10 18:20:34 -07002815 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, mac, TRUE, TRUE))
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002816 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07002817 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2818 "%s: " MAC_ADDRESS_STR
2819 " TDLS setup is ongoing. Request declined.",
2820 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala05922802013-03-14 12:23:19 -07002821 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002822 }
2823
2824 /* first to check if we reached to maximum supported TDLS peer.
2825 TODO: for now, return -EPERM looks working fine,
2826 but need to check if any other errno fit into this category.*/
2827 if (HDD_MAX_NUM_TDLS_STA <= wlan_hdd_tdlsConnectedPeers(pAdapter))
2828 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07002829 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2830 "%s: " MAC_ADDRESS_STR
2831 " TDLS Max peer already connected. Request declined.",
2832 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala05922802013-03-14 12:23:19 -07002833 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002834 }
2835 else
2836 {
2837 hddTdlsPeer_t *pTdlsPeer;
2838 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, mac);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07002839 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002840 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07002841 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2842 "%s: " MAC_ADDRESS_STR " already connected. Request declined.",
2843 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002844 return -EPERM;
2845 }
2846 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07002847 if (0 == update)
2848 wlan_hdd_tdls_set_link_status(pAdapter, mac, eTDLS_LINK_CONNECTING);
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002849
Jeff Johnsond75fe012013-04-06 10:53:06 -07002850 /* debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05302851 if (NULL != StaParams)
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07002852 {
2853 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2854 "%s: TDLS Peer Parameters.", __func__);
Hoonki Lee66b75f32013-04-16 18:30:07 -07002855 if(StaParams->htcap_present)
2856 {
2857 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2858 "ht_capa->cap_info: %0x", StaParams->HTCap.capInfo);
2859 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2860 "ht_capa->extended_capabilities: %0x",
2861 StaParams->HTCap.extendedHtCapInfo);
2862 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07002863 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2864 "params->capability: %0x",StaParams->capability);
2865 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2866 "params->ext_capab_len: %0x",StaParams->extn_capability);
Hoonki Lee66b75f32013-04-16 18:30:07 -07002867 if(StaParams->vhtcap_present)
2868 {
2869 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2870 "rxMcsMap %x rxHighest %x txMcsMap %x txHighest %x",
2871 StaParams->VHTCap.suppMcs.rxMcsMap, StaParams->VHTCap.suppMcs.rxHighest,
2872 StaParams->VHTCap.suppMcs.txMcsMap, StaParams->VHTCap.suppMcs.txHighest);
2873 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07002874 {
2875 int i = 0;
2876 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL, "Supported rates:");
2877 for (i = 0; i < sizeof(StaParams->supported_rates); i++)
2878 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2879 "[%d]: %x ", i, StaParams->supported_rates[i]);
2880 }
Jeff Johnsond75fe012013-04-06 10:53:06 -07002881 } /* end debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05302882 else if ((1 == update) && (NULL == StaParams))
2883 {
2884 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2885 "%s : update is true, but staParams is NULL. Error!", __func__);
2886 return -EPERM;
2887 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002888
2889 INIT_COMPLETION(pAdapter->tdls_add_station_comp);
2890
2891 if (!update)
2892 {
2893 status = sme_AddTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
2894 pAdapter->sessionId, mac);
2895 }
2896 else
2897 {
2898 status = sme_ChangeTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
2899 pAdapter->sessionId, mac, StaParams);
2900 }
2901
2902 status = wait_for_completion_interruptible_timeout(&pAdapter->tdls_add_station_comp,
2903 msecs_to_jiffies(WAIT_TIME_TDLS_ADD_STA));
2904
2905 if (!status)
2906 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07002907 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002908 "%s: timeout waiting for tdls add station indication",
2909 __func__);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07002910 return -EPERM;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002911 }
2912 if ( eHAL_STATUS_SUCCESS != pAdapter->tdlsAddStaStatus)
2913 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07002914 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002915 "%s: Add Station is unsucessful", __func__);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07002916 return -EPERM;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002917 }
2918
2919 return 0;
Gopichand Nakkala05922802013-03-14 12:23:19 -07002920
2921error:
2922 wlan_hdd_tdls_set_link_status(pAdapter, mac, eTDLS_LINK_IDLE);
2923 return -EPERM;
2924
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002925}
2926#endif
2927
Jeff Johnson295189b2012-06-20 16:38:30 -07002928static int wlan_hdd_change_station(struct wiphy *wiphy,
2929 struct net_device *dev,
2930 u8 *mac,
2931 struct station_parameters *params)
2932{
2933 VOS_STATUS status = VOS_STATUS_SUCCESS;
2934 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
2935 v_MACADDR_t STAMacAddress;
Gopichand Nakkalab0856222013-03-12 22:39:05 -07002936#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002937 tCsrStaParams StaParams = {0};
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002938 tANI_U8 isBufSta = 0;
Gopichand Nakkalab0856222013-03-12 22:39:05 -07002939#endif
Jeff Johnsone7245742012-09-05 17:12:55 -07002940 ENTER();
2941
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002942 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
2943 {
2944 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2945 "%s:LOGP in Progress. Ignore!!!", __func__);
2946 return -EAGAIN;
2947 }
2948
Jeff Johnson295189b2012-06-20 16:38:30 -07002949 vos_mem_copy(STAMacAddress.bytes, mac, sizeof(v_MACADDR_t));
2950
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002951 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
2952 || (pAdapter->device_mode == WLAN_HDD_P2P_GO))
Jeff Johnson295189b2012-06-20 16:38:30 -07002953 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002954 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED))
Jeff Johnson295189b2012-06-20 16:38:30 -07002955 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302956 status = hdd_softap_change_STA_state( pAdapter, &STAMacAddress,
Jeff Johnson295189b2012-06-20 16:38:30 -07002957 WLANTL_STA_AUTHENTICATED);
2958
2959 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002960 "%s: Station MAC address does not matching", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002961 return -EINVAL;
2962 }
2963 }
Gopichand Nakkalab0856222013-03-12 22:39:05 -07002964#ifdef FEATURE_WLAN_TDLS
Hoonki Leea6d49be2013-04-05 09:43:25 -07002965 else if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
2966 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)) {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07002967 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
2968 StaParams.capability = params->capability;
2969 StaParams.uapsd_queues = params->uapsd_queues;
2970 StaParams.max_sp = params->max_sp;
2971
2972 if (0 != params->ext_capab_len)
2973 vos_mem_copy(StaParams.extn_capability, params->ext_capab,
2974 sizeof(StaParams.extn_capability));
2975
2976 if (NULL != params->ht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -07002977 {
2978 StaParams.htcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07002979 vos_mem_copy(&StaParams.HTCap, params->ht_capa, sizeof(tSirHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -07002980 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07002981
2982 StaParams.supported_rates_len = params->supported_rates_len;
2983
2984 /* Note : The Maximum sizeof supported_rates sent by the Supplicant is 32.
2985 * The supported_rates array , for all the structures propogating till Add Sta
2986 * to the firmware has to be modified , if the supplicant (ieee80211) is
2987 * modified to send more rates.
2988 */
2989
2990 /* To avoid Data Currption , set to max length to SIR_MAC_MAX_SUPP_RATES
2991 */
2992 if (StaParams.supported_rates_len > SIR_MAC_MAX_SUPP_RATES)
2993 StaParams.supported_rates_len = SIR_MAC_MAX_SUPP_RATES;
2994
2995 if (0 != StaParams.supported_rates_len) {
2996 int i = 0;
2997 vos_mem_copy(StaParams.supported_rates, params->supported_rates,
2998 StaParams.supported_rates_len);
2999 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
3000 "Supported Rates with Length %d", StaParams.supported_rates_len);
3001 for (i=0; i < StaParams.supported_rates_len; i++)
3002 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
3003 "[%d]: %0x", i, StaParams.supported_rates[i]);
3004 }
3005
3006 if (NULL != params->vht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -07003007 {
3008 StaParams.vhtcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003009 vos_mem_copy(&StaParams.VHTCap, params->vht_capa, sizeof(tSirVHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -07003010 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003011
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003012 if (0 != params->ext_capab_len ) {
3013 /*Define A Macro : TODO Sunil*/
3014 if ((1<<4) & StaParams.extn_capability[3]) {
3015 isBufSta = 1;
3016 }
3017 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003018 //status = wlan_hdd_tdls_set_peer_caps( mac, params->uapsd_queues,
3019 // params->max_sp, isBufSta);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003020 //if (VOS_STATUS_SUCCESS != status) {
3021 // VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3022 // "%s: wlan_hdd_tdls_set_peer_caps failed!", __func__);
3023 // return -EINVAL;
3024 //}
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003025 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 1, &StaParams);
3026
3027 if (VOS_STATUS_SUCCESS != status) {
3028 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3029 "%s: sme_ChangeTdlsPeerSta failed!", __func__);
3030 return -EINVAL;
3031 }
3032 }
3033 }
Gopichand Nakkalab0856222013-03-12 22:39:05 -07003034#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303035
Jeff Johnsone7245742012-09-05 17:12:55 -07003036 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07003037 return status;
3038}
3039
3040/*
3041 * FUNCTION: wlan_hdd_cfg80211_get_ibss_peer_staidx
3042 * This function is used to get peer station index in IBSS mode
3043 */
3044static u8 wlan_hdd_cfg80211_get_ibss_peer_staidx(hdd_adapter_t* pAdapter)
3045{
3046 u8 idx = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303047 u8 temp[VOS_MAC_ADDR_SIZE] = {0};
Jeff Johnson295189b2012-06-20 16:38:30 -07003048 ENTER();
3049 memset(temp, 0, VOS_MAC_ADDR_SIZE);
3050 for ( idx = 0; idx < HDD_MAX_NUM_IBSS_STA; idx++ )
3051 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303052 if ( (0 !=
3053 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.staId[idx])
Jeff Johnson295189b2012-06-20 16:38:30 -07003054 && memcmp((u8*)&(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.peerMacAddress[idx],
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303055 temp, VOS_MAC_ADDR_SIZE)
Jeff Johnson295189b2012-06-20 16:38:30 -07003056 )
3057 {
3058 return idx;
3059 }
3060 }
3061 return idx;
3062}
3063
3064
3065/*
3066 * FUNCTION: wlan_hdd_cfg80211_add_key
3067 * This function is used to initialize the key information
3068 */
3069#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003070static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07003071 struct net_device *ndev,
3072 u8 key_index, bool pairwise,
3073 const u8 *mac_addr,
3074 struct key_params *params
3075 )
3076#else
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003077static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07003078 struct net_device *ndev,
3079 u8 key_index, const u8 *mac_addr,
3080 struct key_params *params
3081 )
3082#endif
3083{
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003084 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -07003085 tCsrRoamSetKey setKey;
3086 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
3087 int status = 0;
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003088 v_U32_t roamId= 0xFF;
3089 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07003090 hdd_hostapd_state_t *pHostapdState;
3091 VOS_STATUS vos_status;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07003092 eHalStatus halStatus;
Jeff Johnson295189b2012-06-20 16:38:30 -07003093
3094 ENTER();
3095
Jeff Johnson04dd8a82012-06-29 20:41:40 -07003096 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
3097 {
3098 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3099 "%s:LOGP in Progress. Ignore!!!", __func__);
3100 return -EAGAIN;
3101 }
3102
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003103 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
3104 __func__, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07003105
3106 if (CSR_MAX_NUM_KEY <= key_index)
3107 {
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003108 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07003109 key_index);
3110
3111 return -EINVAL;
3112 }
3113
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003114 if (CSR_MAX_KEY_LEN < params->key_len)
3115 {
3116 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key length %d", __func__,
3117 params->key_len);
3118
3119 return -EINVAL;
3120 }
3121
3122 hddLog(VOS_TRACE_LEVEL_INFO,
3123 "%s: called with key index = %d & key length %d",
3124 __func__, key_index, params->key_len);
Jeff Johnson295189b2012-06-20 16:38:30 -07003125
3126 /*extract key idx, key len and key*/
3127 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
3128 setKey.keyId = key_index;
3129 setKey.keyLength = params->key_len;
3130 vos_mem_copy(&setKey.Key[0],params->key, params->key_len);
3131
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003132 switch (params->cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -07003133 {
3134 case WLAN_CIPHER_SUITE_WEP40:
3135 setKey.encType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
3136 break;
3137
3138 case WLAN_CIPHER_SUITE_WEP104:
3139 setKey.encType = eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
3140 break;
3141
3142 case WLAN_CIPHER_SUITE_TKIP:
3143 {
3144 u8 *pKey = &setKey.Key[0];
3145 setKey.encType = eCSR_ENCRYPT_TYPE_TKIP;
3146
3147 vos_mem_zero(pKey, CSR_MAX_KEY_LEN);
3148
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003149 /*Supplicant sends the 32bytes key in this order
Jeff Johnson295189b2012-06-20 16:38:30 -07003150
3151 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003152 | Tk1 |TX-MIC | RX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -07003153 |--------------|----------|----------|
3154 <---16bytes---><--8bytes--><--8bytes-->
3155
3156 */
3157 /*Sme expects the 32 bytes key to be in the below order
3158
3159 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003160 | Tk1 |RX-MIC | TX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -07003161 |--------------|----------|----------|
3162 <---16bytes---><--8bytes--><--8bytes-->
3163 */
3164 /* Copy the Temporal Key 1 (TK1) */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003165 vos_mem_copy(pKey, params->key, 16);
Jeff Johnson295189b2012-06-20 16:38:30 -07003166
3167 /*Copy the rx mic first*/
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003168 vos_mem_copy(&pKey[16], &params->key[24], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -07003169
3170 /*Copy the tx mic */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003171 vos_mem_copy(&pKey[24], &params->key[16], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -07003172
3173
3174 break;
3175 }
3176
3177 case WLAN_CIPHER_SUITE_CCMP:
3178 setKey.encType = eCSR_ENCRYPT_TYPE_AES;
3179 break;
3180
3181#ifdef FEATURE_WLAN_WAPI
3182 case WLAN_CIPHER_SUITE_SMS4:
3183 {
3184 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
3185 wlan_hdd_cfg80211_set_key_wapi(pAdapter, key_index, mac_addr,
3186 params->key, params->key_len);
3187 return 0;
3188 }
3189#endif
Chet Lanctot186b5732013-03-18 10:26:30 -07003190
Jeff Johnson295189b2012-06-20 16:38:30 -07003191#ifdef FEATURE_WLAN_CCX
3192 case WLAN_CIPHER_SUITE_KRK:
3193 setKey.encType = eCSR_ENCRYPT_TYPE_KRK;
3194 break;
3195#endif
Chet Lanctot186b5732013-03-18 10:26:30 -07003196
3197#ifdef WLAN_FEATURE_11W
3198 case WLAN_CIPHER_SUITE_AES_CMAC:
3199 setKey.encType = eCSR_ENCRYPT_TYPE_AES_CMAC;
Chet Lanctot3b5158a2013-03-31 16:45:21 -07003200 break;
Chet Lanctot186b5732013-03-18 10:26:30 -07003201#endif
3202
Jeff Johnson295189b2012-06-20 16:38:30 -07003203 default:
3204 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unsupported cipher type %lu",
3205 __func__, params->cipher);
3206 return -EOPNOTSUPP;
3207 }
3208
3209 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: encryption type %d",
3210 __func__, setKey.encType);
3211
3212
3213
3214 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07003215 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07003216 )
3217 {
3218
3219
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003220 if (
Jeff Johnson295189b2012-06-20 16:38:30 -07003221#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
3222 (!pairwise)
3223#else
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003224 (!mac_addr || is_broadcast_ether_addr(mac_addr))
Jeff Johnson295189b2012-06-20 16:38:30 -07003225#endif
3226 )
3227 {
3228 /* set group key*/
3229 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnson1250df42012-12-10 14:31:52 -08003230 "%s- %d: setting Broadcast key",
Jeff Johnson295189b2012-06-20 16:38:30 -07003231 __func__, __LINE__);
3232 setKey.keyDirection = eSIR_RX_ONLY;
3233 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
3234 }
3235 else
3236 {
3237 /* set pairwise key*/
3238 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3239 "%s- %d: setting pairwise key",
3240 __func__, __LINE__);
3241 setKey.keyDirection = eSIR_TX_RX;
3242 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
3243 }
3244
3245 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003246 if( pHostapdState->bssState == BSS_START )
3247 {
Jeff Johnson295189b2012-06-20 16:38:30 -07003248 status = WLANSAP_SetKeySta( pVosContext, &setKey);
3249
3250 if ( status != eHAL_STATUS_SUCCESS )
3251 {
3252 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3253 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
3254 __LINE__, status );
3255 }
3256 }
3257
3258 /* Saving WEP keys */
3259 else if( eCSR_ENCRYPT_TYPE_WEP40_STATICKEY == setKey.encType ||
3260 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY == setKey.encType )
3261 {
3262 //Save the wep key in ap context. Issue setkey after the BSS is started.
3263 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
3264 vos_mem_copy(&pAPCtx->wepKey[key_index], &setKey, sizeof(tCsrRoamSetKey));
3265 }
3266 else
3267 {
3268 //Save the key in ap context. Issue setkey after the BSS is started.
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003269 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07003270 vos_mem_copy(&pAPCtx->groupKey, &setKey, sizeof(tCsrRoamSetKey));
3271 }
3272 }
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003273 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION) ||
3274 (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT) )
Jeff Johnson295189b2012-06-20 16:38:30 -07003275 {
3276 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
3277 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3278
3279 pWextState->roamProfile.Keys.KeyLength[key_index] = (u8)params->key_len;
3280
Venkata Prathyusha Kuntupalliee2ce712013-01-17 14:09:24 -08003281 pWextState->roamProfile.Keys.defaultIndex = key_index;
3282
3283
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003284 vos_mem_copy(&pWextState->roamProfile.Keys.KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -07003285 params->key, params->key_len);
3286
3287 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
3288
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303289 if (!( ( IW_AUTH_KEY_MGMT_802_1X
3290 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X))
Jeff Johnson295189b2012-06-20 16:38:30 -07003291 && (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType)
3292 )
3293 &&
3294 ( (WLAN_CIPHER_SUITE_WEP40 == params->cipher)
3295 || (WLAN_CIPHER_SUITE_WEP104 == params->cipher)
3296 )
3297 )
3298 {
3299 /* in case of static WEP, macaddr/bssid is not coming from nl80211
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303300 * interface, copy bssid for pairwise key and group macaddr for
Jeff Johnson295189b2012-06-20 16:38:30 -07003301 * group key initialization*/
3302
3303 tCsrRoamProfile *pRoamProfile = &pWextState->roamProfile;
3304
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303305 pWextState->roamProfile.negotiatedUCEncryptionType =
3306 pHddStaCtx->conn_info.ucEncryptionType =
Jeff Johnson295189b2012-06-20 16:38:30 -07003307 ((WLAN_CIPHER_SUITE_WEP40 == params->cipher) ?
3308 eCSR_ENCRYPT_TYPE_WEP40_STATICKEY :
3309 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY);
3310
3311
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303312 hddLog(VOS_TRACE_LEVEL_INFO_MED,
3313 "%s: Negotiated encryption type %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07003314 pWextState->roamProfile.negotiatedUCEncryptionType);
3315
3316 sme_SetCfgPrivacy((tpAniSirGlobal)WLAN_HDD_GET_HAL_CTX(pAdapter),
3317 &pWextState->roamProfile, true);
3318 setKey.keyLength = 0;
3319 setKey.keyDirection = eSIR_TX_RX;
3320
3321#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303322 if (pairwise)
Jeff Johnson295189b2012-06-20 16:38:30 -07003323 {
3324#endif
3325 if (mac_addr)
3326 {
3327 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
3328 }
3329 else
3330 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303331 /* macaddr is NULL, set the peerMac to bssId in case of BSS,
Jeff Johnson295189b2012-06-20 16:38:30 -07003332 * and peerMacAddress in case of IBSS*/
3333 if (eCSR_BSS_TYPE_START_IBSS == pRoamProfile->BSSType)
3334 {
3335 u8 staidx = wlan_hdd_cfg80211_get_ibss_peer_staidx(pAdapter);
3336 if (HDD_MAX_NUM_IBSS_STA != staidx)
3337 {
3338 vos_mem_copy(setKey.peerMac,
3339 &pHddStaCtx->conn_info.peerMacAddress[staidx],
3340 WNI_CFG_BSSID_LEN);
3341
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303342 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003343 else
3344 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303345 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No peerMac found",
Jeff Johnson295189b2012-06-20 16:38:30 -07003346 __func__);
3347 return -EOPNOTSUPP;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303348 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003349 }
3350 else
3351 {
3352 vos_mem_copy(setKey.peerMac,
3353 &pHddStaCtx->conn_info.bssId[0],
3354 WNI_CFG_BSSID_LEN);
3355 }
3356 }
3357#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
3358 }
3359 else
3360 {
3361 /* set group key*/
3362 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3363 "%s- %d: setting Group key",
3364 __func__, __LINE__);
3365 setKey.keyDirection = eSIR_RX_ONLY;
3366 vos_mem_copy(setKey.peerMac, groupmacaddr, WNI_CFG_BSSID_LEN);
3367 }
3368#endif
3369 }
3370 else if (
3371#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
3372 (!pairwise)
3373#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303374 (!mac_addr || is_broadcast_ether_addr(mac_addr))
Jeff Johnson295189b2012-06-20 16:38:30 -07003375#endif
3376 )
3377 {
3378 /* set group key*/
3379 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3380 "%s- %d: setting Group key",
3381 __func__, __LINE__);
3382 setKey.keyDirection = eSIR_RX_ONLY;
3383 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
3384 }
3385 else
3386 {
3387 /* set pairwise key*/
3388 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3389 "%s- %d: setting pairwise key",
3390 __func__, __LINE__);
3391 setKey.keyDirection = eSIR_TX_RX;
3392 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
3393 }
3394
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303395 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -07003396 "%s: set key for peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303397 __func__, setKey.peerMac[0], setKey.peerMac[1],
3398 setKey.peerMac[2], setKey.peerMac[3],
3399 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -07003400 setKey.keyDirection);
3401
3402 vos_status = wlan_hdd_check_ula_done(pAdapter);
3403
3404 if ( vos_status != VOS_STATUS_SUCCESS )
3405 {
3406 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3407 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
3408 __LINE__, vos_status );
3409
3410 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
3411
3412 return -EINVAL;
3413
3414 }
3415
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07003416#ifdef WLAN_FEATURE_VOWIFI_11R
3417 /* The supplicant may attempt to set the PTK once pre-authentication is done.
3418 Save the key in the UMAC and include it in the ADD BSS request */
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07003419 halStatus = sme_FTUpdateKey( WLAN_HDD_GET_HAL_CTX(pAdapter), &setKey);
Gopichand Nakkalad7d13652013-02-15 01:48:00 +05303420 if( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_WAIT )
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07003421 {
Gopichand Nakkalad7d13652013-02-15 01:48:00 +05303422 return -EINVAL;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07003423 }
3424#endif /* WLAN_FEATURE_VOWIFI_11R */
Jeff Johnson295189b2012-06-20 16:38:30 -07003425
3426 /* issue set key request to SME*/
3427 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
3428 pAdapter->sessionId, &setKey, &roamId );
3429
3430 if ( 0 != status )
3431 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303432 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07003433 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
3434 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
3435 return -EINVAL;
3436 }
3437
3438
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303439 /* in case of IBSS as there was no information available about WEP keys during
3440 * IBSS join, group key intialized with NULL key, so re-initialize group key
Jeff Johnson295189b2012-06-20 16:38:30 -07003441 * with correct value*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303442 if ( (eCSR_BSS_TYPE_START_IBSS == pWextState->roamProfile.BSSType) &&
3443 !( ( IW_AUTH_KEY_MGMT_802_1X
3444 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X))
Jeff Johnson295189b2012-06-20 16:38:30 -07003445 && (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType)
3446 )
3447 &&
3448 ( (WLAN_CIPHER_SUITE_WEP40 == params->cipher)
3449 || (WLAN_CIPHER_SUITE_WEP104 == params->cipher)
3450 )
3451 )
3452 {
3453 setKey.keyDirection = eSIR_RX_ONLY;
3454 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
3455
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303456 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -07003457 "%s: set key peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303458 __func__, setKey.peerMac[0], setKey.peerMac[1],
3459 setKey.peerMac[2], setKey.peerMac[3],
3460 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -07003461 setKey.keyDirection);
3462
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303463 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07003464 pAdapter->sessionId, &setKey, &roamId );
3465
3466 if ( 0 != status )
3467 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303468 hddLog(VOS_TRACE_LEVEL_ERROR,
3469 "%s: sme_RoamSetKey failed for group key (IBSS), returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07003470 __func__, status);
3471 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
3472 return -EINVAL;
3473 }
3474 }
3475 }
3476
3477 return 0;
3478}
3479
3480/*
3481 * FUNCTION: wlan_hdd_cfg80211_get_key
3482 * This function is used to get the key information
3483 */
3484#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303485static int wlan_hdd_cfg80211_get_key(
3486 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07003487 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303488 u8 key_index, bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -07003489 const u8 *mac_addr, void *cookie,
3490 void (*callback)(void *cookie, struct key_params*)
3491 )
3492#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303493static int wlan_hdd_cfg80211_get_key(
3494 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07003495 struct net_device *ndev,
3496 u8 key_index, const u8 *mac_addr, void *cookie,
3497 void (*callback)(void *cookie, struct key_params*)
3498 )
3499#endif
3500{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303501 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -07003502 hdd_wext_state_t *pWextState= WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
3503 tCsrRoamProfile *pRoamProfile = &(pWextState->roamProfile);
3504 struct key_params params;
3505
3506 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303507
Jeff Johnson295189b2012-06-20 16:38:30 -07003508 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",
3509 __func__,pAdapter->device_mode);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303510
Jeff Johnson295189b2012-06-20 16:38:30 -07003511 memset(&params, 0, sizeof(params));
3512
3513 if (CSR_MAX_NUM_KEY <= key_index)
3514 {
3515 return -EINVAL;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303516 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003517
3518 switch(pRoamProfile->EncryptionType.encryptionType[0])
3519 {
3520 case eCSR_ENCRYPT_TYPE_NONE:
3521 params.cipher = IW_AUTH_CIPHER_NONE;
3522 break;
3523
3524 case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY:
3525 case eCSR_ENCRYPT_TYPE_WEP40:
3526 params.cipher = WLAN_CIPHER_SUITE_WEP40;
3527 break;
3528
3529 case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY:
3530 case eCSR_ENCRYPT_TYPE_WEP104:
3531 params.cipher = WLAN_CIPHER_SUITE_WEP104;
3532 break;
3533
3534 case eCSR_ENCRYPT_TYPE_TKIP:
3535 params.cipher = WLAN_CIPHER_SUITE_TKIP;
3536 break;
3537
3538 case eCSR_ENCRYPT_TYPE_AES:
3539 params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
3540 break;
3541
3542 default:
3543 params.cipher = IW_AUTH_CIPHER_NONE;
3544 break;
3545 }
3546
3547 params.key_len = pRoamProfile->Keys.KeyLength[key_index];
3548 params.seq_len = 0;
3549 params.seq = NULL;
3550 params.key = &pRoamProfile->Keys.KeyMaterial[key_index][0];
3551 callback(cookie, &params);
3552 return 0;
3553}
3554
3555/*
3556 * FUNCTION: wlan_hdd_cfg80211_del_key
3557 * This function is used to delete the key information
3558 */
3559#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303560static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07003561 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303562 u8 key_index,
3563 bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -07003564 const u8 *mac_addr
3565 )
3566#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303567static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07003568 struct net_device *ndev,
3569 u8 key_index,
3570 const u8 *mac_addr
3571 )
3572#endif
3573{
3574 int status = 0;
3575
3576 //This code needs to be revisited. There is sme_removeKey API, we should
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303577 //plan to use that. After the change to use correct index in setkey,
Jeff Johnson295189b2012-06-20 16:38:30 -07003578 //it is observed that this is invalidating peer
3579 //key index whenever re-key is done. This is affecting data link.
3580 //It should be ok to ignore del_key.
3581#if 0
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303582 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
3583 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07003584 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
3585 tCsrRoamSetKey setKey;
3586 v_U32_t roamId= 0xFF;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303587
Jeff Johnson295189b2012-06-20 16:38:30 -07003588 ENTER();
3589
3590 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device_mode = %d\n",
3591 __func__,pAdapter->device_mode);
3592
3593 if (CSR_MAX_NUM_KEY <= key_index)
3594 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303595 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07003596 key_index);
3597
3598 return -EINVAL;
3599 }
3600
3601 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
3602 setKey.keyId = key_index;
3603
3604 if (mac_addr)
3605 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
3606 else
3607 vos_mem_copy(setKey.peerMac, groupmacaddr, WNI_CFG_BSSID_LEN);
3608
3609 setKey.encType = eCSR_ENCRYPT_TYPE_NONE;
3610
3611 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07003612 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303613 )
3614 {
3615
3616 hdd_hostapd_state_t *pHostapdState =
Jeff Johnson295189b2012-06-20 16:38:30 -07003617 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
3618 if( pHostapdState->bssState == BSS_START)
3619 {
3620 status = WLANSAP_SetKeySta( pVosContext, &setKey);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303621
Jeff Johnson295189b2012-06-20 16:38:30 -07003622 if ( status != eHAL_STATUS_SUCCESS )
3623 {
3624 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3625 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
3626 __LINE__, status );
3627 }
3628 }
3629 }
3630 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303631 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnson295189b2012-06-20 16:38:30 -07003632 )
3633 {
3634 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3635
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303636 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
3637
3638 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -07003639 "%s: delete key for peerMac %2x:%2x:%2x:%2x:%2x:%2x",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303640 __func__, setKey.peerMac[0], setKey.peerMac[1],
3641 setKey.peerMac[2], setKey.peerMac[3],
Jeff Johnson295189b2012-06-20 16:38:30 -07003642 setKey.peerMac[4], setKey.peerMac[5]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303643 if(pAdapter->sessionCtx.station.conn_info.connState ==
3644 eConnectionState_Associated)
Jeff Johnson295189b2012-06-20 16:38:30 -07003645 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303646 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07003647 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303648
Jeff Johnson295189b2012-06-20 16:38:30 -07003649 if ( 0 != status )
3650 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303651 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07003652 "%s: sme_RoamSetKey failure, returned %d",
3653 __func__, status);
3654 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
3655 return -EINVAL;
3656 }
3657 }
3658 }
3659#endif
Jeff Johnsone7245742012-09-05 17:12:55 -07003660 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07003661 return status;
3662}
3663
3664/*
3665 * FUNCTION: wlan_hdd_cfg80211_set_default_key
3666 * This function is used to set the default tx key index
3667 */
3668#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
3669static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
3670 struct net_device *ndev,
3671 u8 key_index,
3672 bool unicast, bool multicast)
3673#else
3674static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
3675 struct net_device *ndev,
3676 u8 key_index)
3677#endif
3678{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303679 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -07003680 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
3681 int status = 0;
3682 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3683
3684 ENTER();
3685
3686 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d key_index = %d \n",
3687 __func__,pAdapter->device_mode, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303688
Jeff Johnson295189b2012-06-20 16:38:30 -07003689 if (CSR_MAX_NUM_KEY <= key_index)
3690 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303691 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07003692 key_index);
3693
3694 return -EINVAL;
3695 }
3696
Jeff Johnson04dd8a82012-06-29 20:41:40 -07003697 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
3698 {
3699 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3700 "%s:LOGP in Progress. Ignore!!!", __func__);
3701 return -EAGAIN;
3702 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303703
Jeff Johnson295189b2012-06-20 16:38:30 -07003704 if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -07003705 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303706 )
Jeff Johnson295189b2012-06-20 16:38:30 -07003707 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303708 if ( (key_index != pWextState->roamProfile.Keys.defaultIndex) &&
3709 (eCSR_ENCRYPT_TYPE_TKIP !=
Jeff Johnson295189b2012-06-20 16:38:30 -07003710 pWextState->roamProfile.EncryptionType.encryptionType[0]) &&
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303711 (eCSR_ENCRYPT_TYPE_AES !=
Jeff Johnson295189b2012-06-20 16:38:30 -07003712 pWextState->roamProfile.EncryptionType.encryptionType[0])
3713 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303714 {
3715 /* if default key index is not same as previous one,
Jeff Johnson295189b2012-06-20 16:38:30 -07003716 * then update the default key index */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303717
Jeff Johnson295189b2012-06-20 16:38:30 -07003718 tCsrRoamSetKey setKey;
3719 v_U32_t roamId= 0xFF;
3720 tCsrKeys *Keys = &pWextState->roamProfile.Keys;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303721
3722 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: default tx key index %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07003723 __func__, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303724
Jeff Johnson295189b2012-06-20 16:38:30 -07003725 Keys->defaultIndex = (u8)key_index;
3726 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
3727 setKey.keyId = key_index;
3728 setKey.keyLength = Keys->KeyLength[key_index];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303729
3730 vos_mem_copy(&setKey.Key[0],
3731 &Keys->KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -07003732 Keys->KeyLength[key_index]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303733
Jeff Johnson295189b2012-06-20 16:38:30 -07003734 setKey.keyDirection = eSIR_TX_ONLY;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303735
3736 vos_mem_copy(setKey.peerMac,
Jeff Johnson295189b2012-06-20 16:38:30 -07003737 &pHddStaCtx->conn_info.bssId[0],
3738 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303739
3740 setKey.encType =
Jeff Johnson295189b2012-06-20 16:38:30 -07003741 pWextState->roamProfile.EncryptionType.encryptionType[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303742
Jeff Johnson295189b2012-06-20 16:38:30 -07003743 /* issue set key request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303744 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07003745 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303746
Jeff Johnson295189b2012-06-20 16:38:30 -07003747 if ( 0 != status )
3748 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303749 hddLog(VOS_TRACE_LEVEL_ERROR,
3750 "%s: sme_RoamSetKey failed, returned %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07003751 status);
3752 return -EINVAL;
3753 }
3754 }
3755 }
3756
3757 /* In SoftAp mode setting key direction for default mode */
3758 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
3759 {
3760 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
3761 pWextState->roamProfile.EncryptionType.encryptionType[0]) &&
3762 (eCSR_ENCRYPT_TYPE_AES !=
3763 pWextState->roamProfile.EncryptionType.encryptionType[0])
3764 )
3765 {
3766 /* Saving key direction for default key index to TX default */
3767 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
3768 pAPCtx->wepKey[key_index].keyDirection = eSIR_TX_DEFAULT;
3769 }
3770 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303771
Jeff Johnson295189b2012-06-20 16:38:30 -07003772 return status;
3773}
3774
Jeff Johnson295189b2012-06-20 16:38:30 -07003775/*
3776 * FUNCTION: wlan_hdd_cfg80211_inform_bss
3777 * This function is used to inform the BSS details to nl80211 interface.
3778 */
3779static struct cfg80211_bss* wlan_hdd_cfg80211_inform_bss(
3780 hdd_adapter_t *pAdapter, tCsrRoamConnectedProfile *roamProfile)
3781{
3782 struct net_device *dev = pAdapter->dev;
3783 struct wireless_dev *wdev = dev->ieee80211_ptr;
3784 struct wiphy *wiphy = wdev->wiphy;
3785 tSirBssDescription *pBssDesc = roamProfile->pBssDesc;
3786 int chan_no;
3787 int ie_length;
3788 const char *ie;
3789 unsigned int freq;
3790 struct ieee80211_channel *chan;
3791 int rssi = 0;
3792 struct cfg80211_bss *bss = NULL;
3793
3794 ENTER();
3795
3796 if( NULL == pBssDesc )
3797 {
3798 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pBssDesc is NULL\n", __func__);
3799 return bss;
3800 }
3801
3802 chan_no = pBssDesc->channelId;
3803 ie_length = GET_IE_LEN_IN_BSS_DESC( pBssDesc->length );
3804 ie = ((ie_length != 0) ? (const char *)&pBssDesc->ieFields: NULL);
3805
3806 if( NULL == ie )
3807 {
3808 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: IE of BSS descriptor is NULL\n", __func__);
3809 return bss;
3810 }
3811
3812#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
3813 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
3814 {
3815 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
3816 }
3817 else
3818 {
3819 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
3820 }
3821#else
3822 freq = ieee80211_channel_to_frequency(chan_no);
3823#endif
3824
3825 chan = __ieee80211_get_channel(wiphy, freq);
3826
3827 bss = cfg80211_get_bss(wiphy, chan, pBssDesc->bssId,
3828 &roamProfile->SSID.ssId[0], roamProfile->SSID.length,
3829 WLAN_CAPABILITY_ESS, WLAN_CAPABILITY_ESS);
3830 if (bss == NULL)
3831 {
3832 rssi = (VOS_MIN ((pBssDesc->rssi + pBssDesc->sinr), 0))*100;
3833
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303834 return (cfg80211_inform_bss(wiphy, chan, pBssDesc->bssId,
3835 le64_to_cpu(*(__le64 *)pBssDesc->timeStamp),
Jeff Johnson295189b2012-06-20 16:38:30 -07003836 pBssDesc->capabilityInfo,
3837 pBssDesc->beaconInterval, ie, ie_length,
3838 rssi, GFP_KERNEL ));
3839}
3840 else
3841 {
3842 return bss;
3843 }
3844}
3845
3846
3847
3848/*
3849 * FUNCTION: wlan_hdd_cfg80211_inform_bss_frame
3850 * This function is used to inform the BSS details to nl80211 interface.
3851 */
3852struct cfg80211_bss*
3853wlan_hdd_cfg80211_inform_bss_frame( hdd_adapter_t *pAdapter,
3854 tSirBssDescription *bss_desc
3855 )
3856{
3857 /*
3858 cfg80211_inform_bss() is not updating ie field of bss entry, if entry
3859 already exists in bss data base of cfg80211 for that particular BSS ID.
3860 Using cfg80211_inform_bss_frame to update the bss entry instead of
3861 cfg80211_inform_bss, But this call expects mgmt packet as input. As of
3862 now there is no possibility to get the mgmt(probe response) frame from PE,
3863 converting bss_desc to ieee80211_mgmt(probe response) and passing to
3864 cfg80211_inform_bss_frame.
3865 */
3866 struct net_device *dev = pAdapter->dev;
3867 struct wireless_dev *wdev = dev->ieee80211_ptr;
3868 struct wiphy *wiphy = wdev->wiphy;
3869 int chan_no = bss_desc->channelId;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08003870#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
3871 qcom_ie_age *qie_age = NULL;
3872 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length ) + sizeof(qcom_ie_age);
3873#else
Jeff Johnson295189b2012-06-20 16:38:30 -07003874 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length );
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08003875#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07003876 const char *ie =
3877 ((ie_length != 0) ? (const char *)&bss_desc->ieFields: NULL);
3878 unsigned int freq;
3879 struct ieee80211_channel *chan;
3880 struct ieee80211_mgmt *mgmt =
3881 kzalloc((sizeof (struct ieee80211_mgmt) + ie_length), GFP_KERNEL);
3882 struct cfg80211_bss *bss_status = NULL;
3883 size_t frame_len = sizeof (struct ieee80211_mgmt) + ie_length;
3884 int rssi = 0;
Jeff Johnsone7245742012-09-05 17:12:55 -07003885#ifdef WLAN_OPEN_SOURCE
3886 struct timespec ts;
3887#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07003888
3889 ENTER();
3890
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -07003891 if (!mgmt)
3892 return NULL;
3893
Jeff Johnson295189b2012-06-20 16:38:30 -07003894 memcpy(mgmt->bssid, bss_desc->bssId, ETH_ALEN);
Jeff Johnsone7245742012-09-05 17:12:55 -07003895
3896#ifdef WLAN_OPEN_SOURCE
3897 /* Android does not want the timestamp from the frame.
3898 Instead it wants a monotonic increasing value */
3899 get_monotonic_boottime(&ts);
3900 mgmt->u.probe_resp.timestamp =
3901 ((u64)ts.tv_sec * 1000000) + (ts.tv_nsec / 1000);
3902#else
3903 /* keep old behavior for non-open source (for now) */
Jeff Johnson295189b2012-06-20 16:38:30 -07003904 memcpy(&mgmt->u.probe_resp.timestamp, bss_desc->timeStamp,
3905 sizeof (bss_desc->timeStamp));
Jeff Johnsone7245742012-09-05 17:12:55 -07003906
3907#endif
3908
Jeff Johnson295189b2012-06-20 16:38:30 -07003909 mgmt->u.probe_resp.beacon_int = bss_desc->beaconInterval;
3910 mgmt->u.probe_resp.capab_info = bss_desc->capabilityInfo;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08003911
3912#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
3913 /* GPS Requirement: need age ie per entry. Using vendor specific. */
3914 /* Assuming this is the last IE, copy at the end */
3915 ie_length -=sizeof(qcom_ie_age);
3916 qie_age = (qcom_ie_age *)(mgmt->u.probe_resp.variable + ie_length);
3917 qie_age->element_id = QCOM_VENDOR_IE_ID;
3918 qie_age->len = QCOM_VENDOR_IE_AGE_LEN;
3919 qie_age->oui_1 = QCOM_OUI1;
3920 qie_age->oui_2 = QCOM_OUI2;
3921 qie_age->oui_3 = QCOM_OUI3;
3922 qie_age->type = QCOM_VENDOR_IE_AGE_TYPE;
3923 qie_age->age = vos_timer_get_system_ticks() - bss_desc->nReceivedTime;
3924#endif
3925
Jeff Johnson295189b2012-06-20 16:38:30 -07003926 memcpy(mgmt->u.probe_resp.variable, ie, ie_length);
3927
3928 mgmt->frame_control |=
3929 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_RESP);
3930
3931#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303932 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ) &&
Jeff Johnson295189b2012-06-20 16:38:30 -07003933 (wiphy->bands[IEEE80211_BAND_2GHZ] != NULL))
3934 {
3935 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
3936 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303937 else if ((chan_no > ARRAY_SIZE(hdd_channels_2_4_GHZ)) &&
Jeff Johnson295189b2012-06-20 16:38:30 -07003938 (wiphy->bands[IEEE80211_BAND_5GHZ] != NULL))
3939
3940 {
3941 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
3942 }
3943 else
3944 {
3945 kfree(mgmt);
3946 return NULL;
3947 }
3948#else
3949 freq = ieee80211_channel_to_frequency(chan_no);
3950#endif
3951 chan = __ieee80211_get_channel(wiphy, freq);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -08003952 /*when the band is changed on the fly using the GUI, three things are done
3953 * 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)
3954 * as part of the scan abort, message willbe queued to PE and we proceed with flushing and changinh the band.
3955 * pe will stop the scanning further and report back the results what ever it had till now by calling the call back function.
3956 * if the time between update band and scandone call back is sufficent enough the band change reflects in SME, SME validates the channels
3957 * and discards the channels correponding to previous band and calls back with zero bss results.
3958 * 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
3959 * all the channels correponding to previous band.this is due to race condition.but those channels are invalid to the new band and so
3960 * this function __ieee80211_get_channel will return NULL.Each time we report scan result with this pointer null warning kernel trace is printed.
3961 * if the scan results contain large number of APs continuosly kernel warning trace is printed and it will lead to apps watch dog bark.
3962 * So drop the bss and continue to next bss.
3963 */
3964 if(chan == NULL)
3965 {
3966 hddLog(VOS_TRACE_LEVEL_INFO, "%s chan pointer is NULL", __func__);
Chilam Ngc4244af2013-04-01 15:37:32 -07003967 kfree(mgmt);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -08003968 return NULL;
3969 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003970 /*To keep the rssi icon of the connected AP in the scan window
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303971 *and the rssi icon of the wireless networks in sync
Jeff Johnson295189b2012-06-20 16:38:30 -07003972 * */
3973 if (( eConnectionState_Associated ==
3974 pAdapter->sessionCtx.station.conn_info.connState ) &&
3975 ( VOS_TRUE == vos_mem_compare(bss_desc->bssId,
3976 pAdapter->sessionCtx.station.conn_info.bssId,
3977 WNI_CFG_BSSID_LEN)))
3978 {
3979 /* supplicant takes the signal strength in terms of mBm(100*dBm) */
3980 rssi = (pAdapter->rssi * 100);
3981 }
3982 else
3983 {
3984 rssi = (VOS_MIN ((bss_desc->rssi + bss_desc->sinr), 0))*100;
3985 }
3986
3987 bss_status = cfg80211_inform_bss_frame(wiphy, chan, mgmt,
3988 frame_len, rssi, GFP_KERNEL);
3989 kfree(mgmt);
3990 return bss_status;
3991}
3992
3993/*
3994 * FUNCTION: wlan_hdd_cfg80211_update_bss_db
3995 * This function is used to update the BSS data base of CFG8011
3996 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303997struct cfg80211_bss* wlan_hdd_cfg80211_update_bss_db( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07003998 tCsrRoamInfo *pRoamInfo
3999 )
4000{
4001 tCsrRoamConnectedProfile roamProfile;
4002 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
4003 struct cfg80211_bss *bss = NULL;
4004
4005 ENTER();
4006
4007 memset(&roamProfile, 0, sizeof(tCsrRoamConnectedProfile));
4008 sme_RoamGetConnectProfile(hHal, pAdapter->sessionId, &roamProfile);
4009
4010 if (NULL != roamProfile.pBssDesc)
4011 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304012 bss = wlan_hdd_cfg80211_inform_bss(pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07004013 &roamProfile);
4014
4015 if (NULL == bss)
4016 {
4017 hddLog(VOS_TRACE_LEVEL_INFO, "%s: cfg80211_inform_bss return NULL",
4018 __func__);
4019 }
4020
4021 sme_RoamFreeConnectProfile(hHal, &roamProfile);
4022 }
4023 else
4024 {
4025 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: roamProfile.pBssDesc is NULL",
4026 __func__);
4027 }
4028 return bss;
4029}
4030
4031/*
4032 * FUNCTION: wlan_hdd_cfg80211_update_bss
4033 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304034static int wlan_hdd_cfg80211_update_bss( struct wiphy *wiphy,
4035 hdd_adapter_t *pAdapter
Jeff Johnson295189b2012-06-20 16:38:30 -07004036 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304037{
Jeff Johnson295189b2012-06-20 16:38:30 -07004038 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
4039 tCsrScanResultInfo *pScanResult;
4040 eHalStatus status = 0;
4041 tScanResultHandle pResult;
4042 struct cfg80211_bss *bss_status = NULL;
4043
4044 ENTER();
4045
4046 if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress)
4047 {
4048 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:LOGP in Progress. Ignore!!!",__func__);
4049 return -EAGAIN;
4050 }
4051
4052 /*
4053 * start getting scan results and populate cgf80211 BSS database
4054 */
4055 status = sme_ScanGetResult(hHal, pAdapter->sessionId, NULL, &pResult);
4056
4057 /* no scan results */
4058 if (NULL == pResult)
4059 {
4060 hddLog(VOS_TRACE_LEVEL_INFO, "%s: No scan result\n", __func__);
4061 return status;
4062 }
4063
4064 pScanResult = sme_ScanResultGetFirst(hHal, pResult);
4065
4066 while (pScanResult)
4067 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304068 /*
4069 * cfg80211_inform_bss() is not updating ie field of bss entry, if
4070 * entry already exists in bss data base of cfg80211 for that
4071 * particular BSS ID. Using cfg80211_inform_bss_frame to update the
4072 * bss entry instead of cfg80211_inform_bss, But this call expects
4073 * mgmt packet as input. As of now there is no possibility to get
4074 * the mgmt(probe response) frame from PE, converting bss_desc to
Jeff Johnson295189b2012-06-20 16:38:30 -07004075 * ieee80211_mgmt(probe response) and passing to c
4076 * fg80211_inform_bss_frame.
4077 * */
4078
4079 bss_status = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
4080 &pScanResult->BssDescriptor);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304081
Jeff Johnson295189b2012-06-20 16:38:30 -07004082
4083 if (NULL == bss_status)
4084 {
4085 hddLog(VOS_TRACE_LEVEL_INFO,
4086 "%s: NULL returned by cfg80211_inform_bss\n", __func__);
4087 }
4088 else
4089 {
4090 cfg80211_put_bss(bss_status);
4091 }
4092
4093 pScanResult = sme_ScanResultGetNext(hHal, pResult);
4094 }
4095
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304096 sme_ScanResultPurge(hHal, pResult);
Jeff Johnson295189b2012-06-20 16:38:30 -07004097
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304098 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07004099}
4100
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004101void
4102hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel)
4103{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304104 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07004105 "%02X:%02X:%02X:%02X:%02X:%02X\n",
4106 macAddr[0], macAddr[1], macAddr[2], macAddr[3], macAddr[4],
4107 macAddr[5]);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004108} /****** end hddPrintMacAddr() ******/
4109
4110void
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07004111hddPrintPmkId(tANI_U8 *pmkId, tANI_U8 logLevel)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004112{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304113 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07004114 "%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X\n",
4115 pmkId[0], pmkId[1], pmkId[2], pmkId[3], pmkId[4],
4116 pmkId[5], pmkId[6], pmkId[7], pmkId[8], pmkId[9], pmkId[10],
4117 pmkId[11], pmkId[12], pmkId[13], pmkId[14], pmkId[15]);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004118} /****** end hddPrintPmkId() ******/
4119
4120//hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel);
4121//hddPrintMacAddr(macAddr, VOS_TRACE_LEVEL_FATAL);
4122
4123//void sirDumpBuf(tpAniSirGlobal pMac, tANI_U8 modId, tANI_U32 level, tANI_U8 *buf, tANI_U32 size);
4124//sirDumpBuf(pMac, VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, pmkid, 16);
4125
4126#define dump_bssid(bssid) \
4127 { \
Jeff Johnsone7245742012-09-05 17:12:55 -07004128 hddLog(VOS_TRACE_LEVEL_INFO, "BSSID (MAC) address:\t"); \
4129 hddPrintMacAddr(bssid, VOS_TRACE_LEVEL_INFO);\
4130 hddLog(VOS_TRACE_LEVEL_INFO, "\n"); \
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004131 }
4132
4133#define dump_pmkid(pMac, pmkid) \
4134 { \
Jeff Johnsone7245742012-09-05 17:12:55 -07004135 hddLog(VOS_TRACE_LEVEL_INFO, "PMKSA-ID:\t"); \
4136 hddPrintPmkId(pmkid, VOS_TRACE_LEVEL_INFO);\
4137 hddLog(VOS_TRACE_LEVEL_INFO, "\n"); \
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004138 }
4139
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -07004140#if defined(FEATURE_WLAN_LFR) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004141/*
4142 * FUNCTION: wlan_hdd_cfg80211_pmksa_candidate_notify
4143 * This function is used to notify the supplicant of a new PMKSA candidate.
4144 */
4145int wlan_hdd_cfg80211_pmksa_candidate_notify(
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304146 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004147 int index, bool preauth )
4148{
Jeff Johnsone7245742012-09-05 17:12:55 -07004149#ifdef FEATURE_WLAN_OKC
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004150 struct net_device *dev = pAdapter->dev;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004151 hdd_context_t *pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004152
4153 ENTER();
Jeff Johnsone7245742012-09-05 17:12:55 -07004154 hddLog(VOS_TRACE_LEVEL_INFO, "%s is going to notify supplicant of:", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004155
4156 if( NULL == pRoamInfo )
4157 {
4158 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pRoamInfo is NULL\n", __func__);
4159 return -EINVAL;
4160 }
4161
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004162 if (eANI_BOOLEAN_TRUE == hdd_is_okc_mode_enabled(pHddCtx))
4163 {
4164 dump_bssid(pRoamInfo->bssid);
4165 cfg80211_pmksa_candidate_notify(dev, index,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004166 pRoamInfo->bssid, preauth, GFP_KERNEL);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004167 }
Jeff Johnsone7245742012-09-05 17:12:55 -07004168#endif /* FEATURE_WLAN_OKC */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304169 return 0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004170}
4171#endif //FEATURE_WLAN_LFR
4172
Jeff Johnson295189b2012-06-20 16:38:30 -07004173/*
4174 * FUNCTION: hdd_cfg80211_scan_done_callback
4175 * scanning callback function, called after finishing scan
4176 *
4177 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304178static eHalStatus hdd_cfg80211_scan_done_callback(tHalHandle halHandle,
Jeff Johnson295189b2012-06-20 16:38:30 -07004179 void *pContext, tANI_U32 scanId, eCsrScanStatus status)
4180{
4181 struct net_device *dev = (struct net_device *) pContext;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304182 //struct wireless_dev *wdev = dev->ieee80211_ptr;
Jeff Johnson295189b2012-06-20 16:38:30 -07004183 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07004184 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
4185 hdd_scaninfo_t *pScanInfo = &pHddCtx->scan_info;
Jeff Johnson295189b2012-06-20 16:38:30 -07004186 struct cfg80211_scan_request *req = NULL;
4187 int ret = 0;
4188
4189 ENTER();
4190
4191 hddLog(VOS_TRACE_LEVEL_INFO,
4192 "%s called with halHandle = %p, pContext = %p,"
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304193 "scanID = %d, returned status = %d\n",
Jeff Johnson295189b2012-06-20 16:38:30 -07004194 __func__, halHandle, pContext, (int) scanId, (int) status);
4195
4196 //Block on scan req completion variable. Can't wait forever though.
4197 ret = wait_for_completion_interruptible_timeout(
4198 &pScanInfo->scan_req_completion_event,
4199 msecs_to_jiffies(WLAN_WAIT_TIME_SCAN_REQ));
4200 if (!ret)
4201 {
4202 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -07004203 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -07004204 }
4205
4206 if(pScanInfo->mScanPending != VOS_TRUE)
4207 {
4208 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -07004209 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -07004210 }
4211
4212 /* Check the scanId */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304213 if (pScanInfo->scanId != scanId)
Jeff Johnson295189b2012-06-20 16:38:30 -07004214 {
4215 hddLog(VOS_TRACE_LEVEL_INFO,
4216 "%s called with mismatched scanId pScanInfo->scanId = %d "
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304217 "scanId = %d \n", __func__, (int) pScanInfo->scanId,
Jeff Johnson295189b2012-06-20 16:38:30 -07004218 (int) scanId);
4219 }
4220
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304221 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07004222 pAdapter);
4223
4224 if (0 > ret)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304225 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004226
4227
4228 /* If any client wait scan result through WEXT
4229 * send scan done event to client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07004230 if (pHddCtx->scan_info.waitScanResult)
Jeff Johnson295189b2012-06-20 16:38:30 -07004231 {
4232 /* The other scan request waiting for current scan finish
4233 * Send event to notify current scan finished */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07004234 if(WEXT_SCAN_PENDING_DELAY == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -07004235 {
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07004236 vos_event_set(&pHddCtx->scan_info.scan_finished_event);
Jeff Johnson295189b2012-06-20 16:38:30 -07004237 }
4238 /* Send notify to WEXT client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07004239 else if(WEXT_SCAN_PENDING_PIGGYBACK == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -07004240 {
4241 struct net_device *dev = pAdapter->dev;
4242 union iwreq_data wrqu;
4243 int we_event;
4244 char *msg;
4245
4246 memset(&wrqu, '\0', sizeof(wrqu));
4247 we_event = SIOCGIWSCAN;
4248 msg = NULL;
4249 wireless_send_event(dev, we_event, &wrqu, msg);
4250 }
4251 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07004252 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07004253
4254 /* Get the Scan Req */
4255 req = pAdapter->request;
4256
4257 if (!req)
4258 {
4259 hddLog(VOS_TRACE_LEVEL_ERROR, "request is became NULL\n");
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07004260 pScanInfo->mScanPending = VOS_FALSE;
Jeff Johnsone7245742012-09-05 17:12:55 -07004261 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -07004262 }
4263
4264 /*
4265 * setting up 0, just in case.
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304266 */
Jeff Johnson295189b2012-06-20 16:38:30 -07004267 req->n_ssids = 0;
4268 req->n_channels = 0;
4269 req->ie = 0;
4270
Jeff Johnson295189b2012-06-20 16:38:30 -07004271 pAdapter->request = NULL;
Jeff Johnsone7245742012-09-05 17:12:55 -07004272 /* Scan is no longer pending */
4273 pScanInfo->mScanPending = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07004274
Madan Mohan Koyyalamudib764bf82012-10-11 16:38:51 -07004275 /*
4276 * cfg80211_scan_done informing NL80211 about completion
4277 * of scanning
4278 */
4279 cfg80211_scan_done(req, false);
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -08004280 complete(&pScanInfo->abortscan_event_var);
Jeff Johnson295189b2012-06-20 16:38:30 -07004281
Jeff Johnsone7245742012-09-05 17:12:55 -07004282allow_suspend:
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07004283 /* release the wake lock at the end of the scan*/
4284 hdd_allow_suspend();
Jeff Johnsone7245742012-09-05 17:12:55 -07004285
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -07004286 /* Acquire wakelock to handle the case where APP's tries to suspend
4287 * immediatly after the driver gets connect request(i.e after scan)
4288 * from supplicant, this result in app's is suspending and not able
4289 * to process the connect request to AP */
4290 hdd_allow_suspend_timeout(100);
4291
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07004292#ifdef FEATURE_WLAN_TDLS
4293 wlan_hdd_tdls_scan_done_callback(pAdapter);
4294#endif
4295
Jeff Johnson295189b2012-06-20 16:38:30 -07004296 EXIT();
4297 return 0;
4298}
4299
4300/*
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08004301 * FUNCTION: hdd_isScanAllowed
4302 * Go through each adapter and check if scan allowed
4303 *
4304 */
4305v_BOOL_t hdd_isScanAllowed( hdd_context_t *pHddCtx )
4306{
4307 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
4308 hdd_station_ctx_t *pHddStaCtx = NULL;
4309 hdd_adapter_t *pAdapter = NULL;
4310 VOS_STATUS status = 0;
4311 v_U8_t staId = 0;
4312 v_U8_t *staMac = NULL;
4313
4314 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
4315
4316 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
4317 {
4318 pAdapter = pAdapterNode->pAdapter;
4319
4320 if( pAdapter )
4321 {
4322 hddLog(VOS_TRACE_LEVEL_INFO,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304323 "%s: Adapter with device mode %d exists",
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08004324 __func__, pAdapter->device_mode);
4325 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
4326 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
4327 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
4328 {
4329 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4330 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
4331 (VOS_FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
4332 {
4333 staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]);
4334 hddLog(VOS_TRACE_LEVEL_ERROR,
4335 "%s: client %02x:%02x:%02x:%02x:%02x:%02x is in the "
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304336 "middle of WPS/EAPOL exchange.", __func__,
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08004337 staMac[0], staMac[1], staMac[2],
4338 staMac[3], staMac[4], staMac[5]);
4339 return VOS_FALSE;
4340 }
4341 }
4342 else if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) ||
4343 (WLAN_HDD_P2P_GO == pAdapter->device_mode))
4344 {
4345 for (staId = 0; staId < WLAN_MAX_STA_COUNT; staId++)
4346 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304347 if ((pAdapter->aStaInfo[staId].isUsed) &&
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08004348 (WLANTL_STA_CONNECTED == pAdapter->aStaInfo[staId].tlSTAState))
4349 {
4350 staMac = (v_U8_t *) &(pAdapter->aStaInfo[staId].macAddrSTA.bytes[0]);
4351
4352 hddLog(VOS_TRACE_LEVEL_ERROR,
4353 "%s: client %02x:%02x:%02x:%02x:%02x:%02x of SoftAP/P2P-GO is in the "
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304354 "middle of WPS/EAPOL exchange.", __func__,
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08004355 staMac[0], staMac[1], staMac[2],
4356 staMac[3], staMac[4], staMac[5]);
4357 return VOS_FALSE;
4358 }
4359 }
4360 }
4361 }
4362 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
4363 pAdapterNode = pNext;
4364 }
4365 hddLog(VOS_TRACE_LEVEL_INFO,
4366 "%s: Scan allowed", __func__);
4367 return VOS_TRUE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304368}
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08004369
4370/*
Jeff Johnson295189b2012-06-20 16:38:30 -07004371 * FUNCTION: wlan_hdd_cfg80211_scan
4372 * this scan respond to scan trigger and update cfg80211 scan database
4373 * later, scan dump command can be used to recieve scan results
4374 */
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -08004375int wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
4376#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
4377 struct net_device *dev,
4378#endif
4379 struct cfg80211_scan_request *request)
4380{
4381#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
4382 struct net_device *dev = request->wdev->netdev;
4383#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304384 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Jeff Johnson295189b2012-06-20 16:38:30 -07004385 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
4386 hdd_wext_state_t *pwextBuf = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
4387 hdd_config_t *cfg_param = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
4388 tCsrScanRequest scanRequest;
4389 tANI_U8 *channelList = NULL, i;
4390 v_U32_t scanId = 0;
4391 int status = 0;
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07004392 hdd_scaninfo_t *pScanInfo = &pHddCtx->scan_info;
Jeff Johnson295189b2012-06-20 16:38:30 -07004393 v_U8_t* pP2pIe = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07004394
4395 ENTER();
4396
4397 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",
4398 __func__,pAdapter->device_mode);
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08004399
Gopichand Nakkala681989c2013-03-06 22:27:48 -08004400 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08004401 (eConnectionState_Connecting ==
Gopichand Nakkala681989c2013-03-06 22:27:48 -08004402 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08004403 {
4404 hddLog(VOS_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08004405 "%s: %p(%d) Connection in progress: Scan request denied (EBUSY)", __func__, \
4406 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08004407 return -EBUSY;
4408 }
4409
Jeff Johnson295189b2012-06-20 16:38:30 -07004410#ifdef WLAN_BTAMP_FEATURE
4411 //Scan not supported when AMP traffic is on.
Gopichand Nakkala681989c2013-03-06 22:27:48 -08004412 if (VOS_TRUE == WLANBAP_AmpSessionOn())
Jeff Johnson295189b2012-06-20 16:38:30 -07004413 {
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08004414 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07004415 "%s: No scanning when AMP is on", __func__);
4416 return -EOPNOTSUPP;
4417 }
4418#endif
4419 //Scan on any other interface is not supported.
Gopichand Nakkala681989c2013-03-06 22:27:48 -08004420 if (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07004421 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -08004422 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07004423 "%s: Not scanning on device_mode = %d",
4424 __func__, pAdapter->device_mode);
4425 return -EOPNOTSUPP;
4426 }
4427
4428 if (TRUE == pScanInfo->mScanPending)
4429 {
4430 hddLog(VOS_TRACE_LEVEL_INFO, "%s: mScanPending is TRUE", __func__);
Gopichand Nakkala681989c2013-03-06 22:27:48 -08004431 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -07004432 }
4433
4434 if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress)
4435 {
4436 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
4437 "%s:LOGP in Progress. Ignore!!!", __func__);
4438 return -EAGAIN;
4439 }
4440
Mohit Khanna6c52bbf2012-09-11 15:10:12 -07004441 if ((WLAN_HDD_GET_CTX(pAdapter))->isLoadUnloadInProgress)
4442 {
4443 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
4444 "%s:Unloading/Loading in Progress. Ignore!!!", __func__);
4445 return -EAGAIN;
4446 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304447 //Don't Allow Scan and return busy if Remain On
Jeff Johnson32d95a32012-09-10 13:15:23 -07004448 //Channel and action frame is pending
4449 //Otherwise Cancel Remain On Channel and allow Scan
4450 //If no action frame pending
Gopichand Nakkala681989c2013-03-06 22:27:48 -08004451 if (0 != wlan_hdd_check_remain_on_channel(pAdapter))
Jeff Johnson32d95a32012-09-10 13:15:23 -07004452 {
4453 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Remain On Channel Pending", __func__);
4454 return -EBUSY;
4455 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08004456#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07004457 /* if tdls disagree scan right now, return immediately.
4458 tdls will schedule the scan when scan is allowed. (return SUCCESS)
4459 or will reject the scan if any TDLS is in progress. (return -EBUSY)
4460 */
4461 status = wlan_hdd_tdls_scan_callback (pAdapter,
4462 wiphy,
4463#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
4464 dev,
Gopichand Nakkalac3c42b92013-03-20 19:42:34 -07004465#endif
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07004466 request);
4467 if(status <= 0)
4468 {
4469 hddLog(VOS_TRACE_LEVEL_INFO, "%s: TDLS Pending %d", __func__, status);
4470 return status;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08004471 }
4472#endif
Jeff Johnson32d95a32012-09-10 13:15:23 -07004473
Jeff Johnson295189b2012-06-20 16:38:30 -07004474 if (mutex_lock_interruptible(&pHddCtx->tmInfo.tmOperationLock))
4475 {
4476 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_ERROR,
Jeff Johnson1250df42012-12-10 14:31:52 -08004477 "%s: Acquire lock fail", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004478 return -EAGAIN;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304479 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004480 if (TRUE == pHddCtx->tmInfo.tmAction.enterImps)
4481 {
4482 hddLog(VOS_TRACE_LEVEL_WARN,
4483 "%s: MAX TM Level Scan not allowed", __func__);
4484 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304485 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -07004486 }
4487 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
4488
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08004489 /* Check if scan is allowed at this point of time.
4490 */
4491 if (!hdd_isScanAllowed(pHddCtx))
4492 {
4493 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Scan not allowed", __func__);
4494 return -EBUSY;
4495 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304496
Jeff Johnson295189b2012-06-20 16:38:30 -07004497 vos_mem_zero( &scanRequest, sizeof(scanRequest));
4498
4499 if (NULL != request)
4500 {
4501 hddLog(VOS_TRACE_LEVEL_INFO, "scan request for ssid = %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304502 (int)request->n_ssids);
Jeff Johnson295189b2012-06-20 16:38:30 -07004503
4504 /* Even though supplicant doesn't provide any SSIDs, n_ssids is set to 1.
4505 * Becasue of this, driver is assuming that this is not wildcard scan and so
4506 * is not aging out the scan results.
4507 */
Jeff Johnson32d95a32012-09-10 13:15:23 -07004508 if (request->ssids && '\0' == request->ssids->ssid[0])
Jeff Johnson295189b2012-06-20 16:38:30 -07004509 {
4510 request->n_ssids = 0;
4511 }
4512
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07004513 if ((request->ssids) && (0 < request->n_ssids))
Jeff Johnson295189b2012-06-20 16:38:30 -07004514 {
4515 tCsrSSIDInfo *SsidInfo;
4516 int j;
4517 scanRequest.SSIDs.numOfSSIDs = request->n_ssids;
4518 /* Allocate num_ssid tCsrSSIDInfo structure */
4519 SsidInfo = scanRequest.SSIDs.SSIDList =
4520 ( tCsrSSIDInfo *)vos_mem_malloc(
4521 request->n_ssids*sizeof(tCsrSSIDInfo));
4522
4523 if(NULL == scanRequest.SSIDs.SSIDList)
4524 {
4525 hddLog(VOS_TRACE_LEVEL_ERROR,
4526 "memory alloc failed SSIDInfo buffer");
4527 return -ENOMEM;
4528 }
4529
4530 /* copy all the ssid's and their length */
4531 for(j = 0; j < request->n_ssids; j++, SsidInfo++)
4532 {
4533 /* get the ssid length */
4534 SsidInfo->SSID.length = request->ssids[j].ssid_len;
4535 vos_mem_copy(SsidInfo->SSID.ssId, &request->ssids[j].ssid[0],
4536 SsidInfo->SSID.length);
4537 SsidInfo->SSID.ssId[SsidInfo->SSID.length] = '\0';
4538 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "SSID number %d: %s",
4539 j, SsidInfo->SSID.ssId);
4540 }
4541 /* set the scan type to active */
4542 scanRequest.scanType = eSIR_ACTIVE_SCAN;
4543 }
4544 else if(WLAN_HDD_P2P_GO == pAdapter->device_mode)
4545 {
4546 /* set the scan type to active */
4547 scanRequest.scanType = eSIR_ACTIVE_SCAN;
4548 }
4549 else
4550 {
4551 /*Set the scan type to default type, in this case it is ACTIVE*/
4552 scanRequest.scanType = pScanInfo->scan_mode;
4553 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304554 scanRequest.minChnTime = cfg_param->nActiveMinChnTime;
Jeff Johnson295189b2012-06-20 16:38:30 -07004555 scanRequest.maxChnTime = cfg_param->nActiveMaxChnTime;
4556 }
4557 else
4558 {
4559 /* set the scan type to active */
4560 scanRequest.scanType = eSIR_ACTIVE_SCAN;
4561 vos_mem_set( scanRequest.bssid, sizeof( tCsrBssid ), 0xff );
4562
4563 /* set min and max channel time to zero */
4564 scanRequest.minChnTime = 0;
4565 scanRequest.maxChnTime = 0;
4566 }
4567
4568 /* set BSSType to default type */
4569 scanRequest.BSSType = eCSR_BSS_TYPE_ANY;
4570
4571 /*TODO: scan the requested channels only*/
4572
4573 /*Right now scanning all the channels */
4574 if( request )
4575 {
4576 if( request->n_channels )
4577 {
4578 channelList = vos_mem_malloc( request->n_channels );
4579 if( NULL == channelList )
4580 {
4581 status = -ENOMEM;
4582 goto free_mem;
4583 }
4584
4585 for( i = 0 ; i < request->n_channels ; i++ )
4586 channelList[i] = request->channels[i]->hw_value;
4587 }
4588
4589 scanRequest.ChannelInfo.numOfChannels = request->n_channels;
4590 scanRequest.ChannelInfo.ChannelList = channelList;
4591
4592 /* set requestType to full scan */
4593 scanRequest.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304594
4595 /* Flush the scan results(only p2p beacons) for STA scan and P2P
Madan Mohan Koyyalamudi8d50f312012-11-27 15:48:57 -08004596 * search (Flush on both full scan and social scan but not on single
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304597 * channel scan).P2P search happens on 3 social channels (1, 6, 11)
Madan Mohan Koyyalamudi8d50f312012-11-27 15:48:57 -08004598 */
4599
4600 /* Supplicant does single channel scan after 8-way handshake
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304601 * and in that case driver shoudnt flush scan results. If
4602 * driver flushes the scan results here and unfortunately if
4603 * the AP doesnt respond to our probe req then association
Madan Mohan Koyyalamudi8d50f312012-11-27 15:48:57 -08004604 * fails which is not desired
4605 */
4606
4607 if( request->n_channels != WLAN_HDD_P2P_SINGLE_CHANNEL_SCAN )
4608 {
4609 sme_ScanFlushP2PResult( WLAN_HDD_GET_HAL_CTX(pAdapter),
4610 pAdapter->sessionId );
4611 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004612
4613 if( request->ie_len )
4614 {
4615 /* save this for future association (join requires this) */
4616 memset( &pScanInfo->scanAddIE, 0, sizeof(pScanInfo->scanAddIE) );
4617 memcpy( pScanInfo->scanAddIE.addIEdata, request->ie, request->ie_len);
4618 pScanInfo->scanAddIE.length = request->ie_len;
4619
4620 if((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Jeff Johnsone7245742012-09-05 17:12:55 -07004621 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
4622 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -07004623 )
4624 {
4625 pwextBuf->roamProfile.pAddIEScan = pScanInfo->scanAddIE.addIEdata;
4626 pwextBuf->roamProfile.nAddIEScanLength = pScanInfo->scanAddIE.length;
4627 }
4628
4629 scanRequest.uIEFieldLen = pScanInfo->scanAddIE.length;
4630 scanRequest.pIEField = pScanInfo->scanAddIE.addIEdata;
4631
Jeff Johnson295189b2012-06-20 16:38:30 -07004632 pP2pIe = wlan_hdd_get_p2p_ie_ptr((v_U8_t*)request->ie,
4633 request->ie_len);
4634 if (pP2pIe != NULL)
4635 {
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07004636#ifdef WLAN_FEATURE_P2P_DEBUG
4637 if (((globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED) ||
4638 (globalP2PConnectionStatus == P2P_GO_NEG_PROCESS)) &&
4639 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
4640 {
4641 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_1;
4642 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
4643 "Go nego completed to Connection is started");
4644 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
4645 "for 8way Handshake");
4646 }
4647 else if((globalP2PConnectionStatus == P2P_CLIENT_DISCONNECTED_STATE) &&
4648 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
4649 {
4650 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_2;
4651 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
4652 "Disconnected state to Connection is started");
4653 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
4654 "for 4way Handshake");
4655 }
4656#endif
4657
Jeff Johnsone7245742012-09-05 17:12:55 -07004658 /* no_cck will be set during p2p find to disable 11b rates */
4659 if(TRUE == request->no_cck)
Jeff Johnson295189b2012-06-20 16:38:30 -07004660 {
Jeff Johnson295189b2012-06-20 16:38:30 -07004661 hddLog(VOS_TRACE_LEVEL_INFO,
4662 "%s: This is a P2P Search", __func__);
4663 scanRequest.p2pSearch = 1;
Jeff Johnsone7245742012-09-05 17:12:55 -07004664
Jeff Johnsone7245742012-09-05 17:12:55 -07004665 if( request->n_channels == WLAN_HDD_P2P_SOCIAL_CHANNELS )
4666 {
Madan Mohan Koyyalamudi1b1d9e82012-10-21 11:38:33 -07004667 /* set requestType to P2P Discovery */
4668 scanRequest.requestType = eCSR_SCAN_P2P_DISCOVERY;
Jeff Johnsone7245742012-09-05 17:12:55 -07004669 }
4670
4671 /*
4672 Skip Dfs Channel in case of P2P Search
4673 if it is set in ini file
4674 */
4675 if(cfg_param->skipDfsChnlInP2pSearch)
4676 {
4677 scanRequest.skipDfsChnlInP2pSearch = 1;
4678 }
4679 else
4680 {
4681 scanRequest.skipDfsChnlInP2pSearch = 0;
4682 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004683
Jeff Johnson295189b2012-06-20 16:38:30 -07004684 }
4685 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004686 }
4687 }
4688
4689 INIT_COMPLETION(pScanInfo->scan_req_completion_event);
4690
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07004691 /* acquire the wakelock to avoid the apps suspend during the scan. To
4692 * address the following issues.
4693 * 1) Disconnected scenario: we are not allowing the suspend as WLAN is not in
4694 * BMPS/IMPS this result in android trying to suspend aggressively and backing off
4695 * for long time, this result in apps running at full power for long time.
4696 * 2) Connected scenario: If we allow the suspend during the scan, RIVA will
4697 * be stuck in full power because of resume BMPS
4698 */
4699 hdd_prevent_suspend();
Jeff Johnsone7245742012-09-05 17:12:55 -07004700
4701 status = sme_ScanRequest( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07004702 pAdapter->sessionId, &scanRequest, &scanId,
4703 &hdd_cfg80211_scan_done_callback, dev );
Jeff Johnsone7245742012-09-05 17:12:55 -07004704
Jeff Johnson295189b2012-06-20 16:38:30 -07004705 if (eHAL_STATUS_SUCCESS != status)
4706 {
4707 hddLog(VOS_TRACE_LEVEL_ERROR,
4708 "%s: sme_ScanRequest returned error %d", __func__, status);
4709 complete(&pScanInfo->scan_req_completion_event);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -07004710 if(eHAL_STATUS_RESOURCES == status)
4711 {
Madan Mohan Koyyalamudia3fcf142012-10-18 15:01:20 -07004712 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 -07004713 status = -EBUSY;
4714 } else {
4715 status = -EIO;
4716 }
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07004717 hdd_allow_suspend();
Jeff Johnson295189b2012-06-20 16:38:30 -07004718 goto free_mem;
4719 }
4720
4721 pScanInfo->mScanPending = TRUE;
4722 pAdapter->request = request;
4723 pScanInfo->scanId = scanId;
4724
4725 complete(&pScanInfo->scan_req_completion_event);
4726
4727free_mem:
4728 if( scanRequest.SSIDs.SSIDList )
4729 {
4730 vos_mem_free(scanRequest.SSIDs.SSIDList);
4731 }
4732
4733 if( channelList )
4734 vos_mem_free( channelList );
4735
4736 EXIT();
4737
4738 return status;
4739}
4740
4741/*
4742 * FUNCTION: wlan_hdd_cfg80211_connect_start
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304743 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -07004744 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304745int wlan_hdd_cfg80211_connect_start( hdd_adapter_t *pAdapter,
Jeff Johnson32d95a32012-09-10 13:15:23 -07004746 const u8 *ssid, size_t ssid_len, const u8 *bssid, u8 operatingChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -07004747{
4748 int status = 0;
4749 hdd_wext_state_t *pWextState;
4750 v_U32_t roamId;
4751 tCsrRoamProfile *pRoamProfile;
4752 eMib_dot11DesiredBssType connectedBssType;
4753 eCsrAuthType RSNAuthType;
4754
4755 ENTER();
4756
4757 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304758
Jeff Johnson295189b2012-06-20 16:38:30 -07004759 if (SIR_MAC_MAX_SSID_LENGTH < ssid_len)
4760 {
4761 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wrong SSID len", __func__);
4762 return -EINVAL;
4763 }
4764
4765 pRoamProfile = &pWextState->roamProfile;
4766
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304767 if (pRoamProfile)
Jeff Johnson295189b2012-06-20 16:38:30 -07004768 {
Jeff Johnsone7245742012-09-05 17:12:55 -07004769 int ret = 0;
4770 hdd_station_ctx_t *pHddStaCtx;
4771 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4772 hdd_connGetConnectedBssType(pHddStaCtx,&connectedBssType );
4773
4774 if((eMib_dot11DesiredBssType_independent == connectedBssType) ||
4775 (eConnectionState_Associated == pHddStaCtx->conn_info.connState) ||
4776 (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState))
Jeff Johnson295189b2012-06-20 16:38:30 -07004777 {
4778 /* Issue disconnect to CSR */
4779 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304780 if( eHAL_STATUS_SUCCESS ==
Jeff Johnson295189b2012-06-20 16:38:30 -07004781 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
4782 pAdapter->sessionId,
4783 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
4784 {
Jeff Johnsone7245742012-09-05 17:12:55 -07004785 ret = wait_for_completion_interruptible_timeout(
4786 &pAdapter->disconnect_comp_var,
4787 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
4788 if (0 == ret)
4789 {
4790 VOS_ASSERT(0);
4791 }
4792 }
4793 }
4794 else if(eConnectionState_Disconnecting == pHddStaCtx->conn_info.connState)
4795 {
4796 ret = wait_for_completion_interruptible_timeout(
4797 &pAdapter->disconnect_comp_var,
4798 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
4799 if (0 == ret)
4800 {
4801 VOS_ASSERT(0);
Jeff Johnson295189b2012-06-20 16:38:30 -07004802 }
4803 }
4804
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304805 if (HDD_WMM_USER_MODE_NO_QOS ==
Jeff Johnson295189b2012-06-20 16:38:30 -07004806 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->WmmMode)
4807 {
4808 /*QoS not enabled in cfg file*/
4809 pRoamProfile->uapsd_mask = 0;
4810 }
4811 else
4812 {
4813 /*QoS enabled, update uapsd mask from cfg file*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304814 pRoamProfile->uapsd_mask =
Jeff Johnson295189b2012-06-20 16:38:30 -07004815 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask;
4816 }
4817
4818 pRoamProfile->SSIDs.numOfSSIDs = 1;
4819 pRoamProfile->SSIDs.SSIDList->SSID.length = ssid_len;
4820 vos_mem_zero(pRoamProfile->SSIDs.SSIDList->SSID.ssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304821 sizeof(pRoamProfile->SSIDs.SSIDList->SSID.ssId));
Jeff Johnson295189b2012-06-20 16:38:30 -07004822 vos_mem_copy((void *)(pRoamProfile->SSIDs.SSIDList->SSID.ssId),
4823 ssid, ssid_len);
4824
4825 if (bssid)
4826 {
4827 pRoamProfile->BSSIDs.numOfBSSIDs = 1;
4828 vos_mem_copy((void *)(pRoamProfile->BSSIDs.bssid), bssid,
4829 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304830 /* Save BSSID in seperate variable as well, as RoamProfile
4831 BSSID is getting zeroed out in the association process. And in
Jeff Johnson295189b2012-06-20 16:38:30 -07004832 case of join failure we should send valid BSSID to supplicant
4833 */
4834 vos_mem_copy((void *)(pWextState->req_bssId), bssid,
4835 WNI_CFG_BSSID_LEN);
4836 }
4837
4838 if ((IW_AUTH_WPA_VERSION_WPA == pWextState->wpaVersion) ||
4839 (IW_AUTH_WPA_VERSION_WPA2 == pWextState->wpaVersion))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304840 {
Jeff Johnson295189b2012-06-20 16:38:30 -07004841 /*set gen ie*/
4842 hdd_SetGENIEToCsr(pAdapter, &RSNAuthType);
4843 /*set auth*/
4844 hdd_set_csr_auth_type(pAdapter, RSNAuthType);
4845 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304846 else if ( (pWextState->roamProfile.AuthType.authType[0] ==
Jeff Johnson295189b2012-06-20 16:38:30 -07004847 eCSR_AUTH_TYPE_OPEN_SYSTEM)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304848 && ((pWextState->roamProfile.EncryptionType.encryptionType[0] ==
4849 eCSR_ENCRYPT_TYPE_WEP40_STATICKEY)
4850 || (pWextState->roamProfile.EncryptionType.encryptionType[0] ==
Jeff Johnson295189b2012-06-20 16:38:30 -07004851 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY))
4852 )
4853 {
4854 /*Android UI not having any option to configure the Authentication type to OPEN/SHARED;
4855 * The authentication type will be always eCSR_AUTH_TYPE_OPEN_SYSTEM when WEP is used
4856 * Use eCSR_AUTH_TYPE_AUTOSWITCH when WEP encryption used*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304857 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.authType =
Jeff Johnson295189b2012-06-20 16:38:30 -07004858 eCSR_AUTH_TYPE_AUTOSWITCH;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304859 pWextState->roamProfile.AuthType.authType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -07004860 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.authType;
4861 }
4862#ifdef FEATURE_WLAN_WAPI
4863 if (pAdapter->wapi_info.nWapiMode)
4864 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004865 hddLog(LOG1, "%s: Setting WAPI AUTH Type and Encryption Mode values", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004866 switch (pAdapter->wapi_info.wapiAuthMode)
4867 {
4868 case WAPI_AUTH_MODE_PSK:
4869 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004870 hddLog(LOG1, "%s: WAPI AUTH TYPE: PSK: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07004871 pAdapter->wapi_info.wapiAuthMode);
4872 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_PSK;
4873 break;
4874 }
4875 case WAPI_AUTH_MODE_CERT:
4876 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004877 hddLog(LOG1, "%s: WAPI AUTH TYPE: CERT: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07004878 pAdapter->wapi_info.wapiAuthMode);
4879 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE;
4880 break;
4881 }
4882 } // End of switch
4883 if ( pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_PSK ||
4884 pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_CERT)
4885 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004886 hddLog(LOG1, "%s: WAPI PAIRWISE/GROUP ENCRYPTION: WPI", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004887 pRoamProfile->AuthType.numEntries = 1;
4888 pRoamProfile->EncryptionType.numEntries = 1;
4889 pRoamProfile->EncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
4890 pRoamProfile->mcEncryptionType.numEntries = 1;
4891 pRoamProfile->mcEncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
4892 }
4893 }
4894#endif /* FEATURE_WLAN_WAPI */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05304895#ifdef WLAN_FEATURE_GTK_OFFLOAD
4896 /* Initializing gtkOffloadRequestParams */
4897 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
4898 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
4899 {
4900 pHddStaCtx->gtkOffloadRequestParams.requested = FALSE;
4901 memset(&pHddStaCtx->gtkOffloadRequestParams.gtkOffloadReqParams,
4902 0, sizeof (tSirGtkOffloadParams));
4903 }
4904#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07004905 pRoamProfile->csrPersona = pAdapter->device_mode;
4906
Jeff Johnson32d95a32012-09-10 13:15:23 -07004907 if( operatingChannel )
4908 {
4909 pRoamProfile->ChannelInfo.ChannelList = &operatingChannel;
4910 pRoamProfile->ChannelInfo.numOfChannels = 1;
4911 }
Chet Lanctot186b5732013-03-18 10:26:30 -07004912 else
4913 {
4914 pRoamProfile->ChannelInfo.ChannelList = NULL;
4915 pRoamProfile->ChannelInfo.numOfChannels = 0;
4916 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07004917
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08004918 /* change conn_state to connecting before sme_RoamConnect(), because sme_RoamConnect()
4919 * has a direct path to call hdd_smeRoamCallback(), which will change the conn_state
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304920 * If direct path, conn_state will be accordingly changed to NotConnected or Associated
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08004921 * by either hdd_AssociationCompletionHandler() or hdd_DisConnectHandler() in sme_RoamCallback()
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -08004922 * if sme_RomConnect is to be queued, Connecting state will remain until it is completed.
4923 */
4924 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode)
4925 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
4926 eConnectionState_Connecting);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304927
4928 status = sme_RoamConnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07004929 pAdapter->sessionId, pRoamProfile, &roamId);
4930
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08004931 if( (eHAL_STATUS_SUCCESS != status) &&
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +05304932 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) )
4933
4934 {
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08004935 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: sme_RoamConnect (session %d) failed with "
4936 "status %d. -> NotConnected", __func__, pAdapter->sessionId, status);
4937 /* change back to NotAssociated */
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +05304938 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08004939 eConnectionState_NotConnected);
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +05304940 }
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -08004941
4942 pRoamProfile->ChannelInfo.ChannelList = NULL;
4943 pRoamProfile->ChannelInfo.numOfChannels = 0;
4944
Jeff Johnson295189b2012-06-20 16:38:30 -07004945 }
4946 else
4947 {
4948 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid Roam profile", __func__);
4949 return -EINVAL;
4950 }
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08004951 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07004952 return status;
4953}
4954
4955/*
4956 * FUNCTION: wlan_hdd_set_cfg80211_auth_type
4957 * This function is used to set the authentication type (OPEN/SHARED).
4958 *
4959 */
4960static int wlan_hdd_cfg80211_set_auth_type(hdd_adapter_t *pAdapter,
4961 enum nl80211_auth_type auth_type)
4962{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304963 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07004964 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4965
4966 ENTER();
4967
4968 /*set authentication type*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304969 switch (auth_type)
Jeff Johnson295189b2012-06-20 16:38:30 -07004970 {
4971 case NL80211_AUTHTYPE_OPEN_SYSTEM:
4972 case NL80211_AUTHTYPE_AUTOMATIC:
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07004973#ifdef WLAN_FEATURE_VOWIFI_11R
4974 case NL80211_AUTHTYPE_FT:
4975#endif /* WLAN_FEATURE_VOWIFI_11R */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304976 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -07004977 "%s: set authentication type to OPEN", __func__);
4978 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
4979 break;
4980
4981 case NL80211_AUTHTYPE_SHARED_KEY:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304982 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -07004983 "%s: set authentication type to SHARED", __func__);
4984 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_SHARED_KEY;
4985 break;
4986#ifdef FEATURE_WLAN_CCX
4987 case NL80211_AUTHTYPE_NETWORK_EAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304988 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -07004989 "%s: set authentication type to CCKM WPA", __func__);
4990 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_CCKM_WPA;//eCSR_AUTH_TYPE_CCKM_RSN needs to be handled as well if required.
4991 break;
4992#endif
4993
4994
4995 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304996 hddLog(VOS_TRACE_LEVEL_ERROR,
4997 "%s: Unsupported authentication type %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07004998 auth_type);
4999 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_UNKNOWN;
5000 return -EINVAL;
5001 }
5002
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305003 pWextState->roamProfile.AuthType.authType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -07005004 pHddStaCtx->conn_info.authType;
5005 return 0;
5006}
5007
5008/*
5009 * FUNCTION: wlan_hdd_set_akm_suite
5010 * This function is used to set the key mgmt type(PSK/8021x).
5011 *
5012 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305013static int wlan_hdd_set_akm_suite( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07005014 u32 key_mgmt
5015 )
5016{
5017 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
5018 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305019
Jeff Johnson295189b2012-06-20 16:38:30 -07005020 /*set key mgmt type*/
5021 switch(key_mgmt)
5022 {
5023 case WLAN_AKM_SUITE_PSK:
Gopichand Nakkala356fb102013-03-06 12:34:04 +05305024#ifdef WLAN_FEATURE_VOWIFI_11R
5025 case WLAN_AKM_SUITE_FT_PSK:
5026#endif
5027 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to PSK",
Jeff Johnson295189b2012-06-20 16:38:30 -07005028 __func__);
5029 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_PSK;
5030 break;
5031
5032 case WLAN_AKM_SUITE_8021X:
Gopichand Nakkala356fb102013-03-06 12:34:04 +05305033#ifdef WLAN_FEATURE_VOWIFI_11R
5034 case WLAN_AKM_SUITE_FT_8021X:
5035#endif
5036 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to 8021x",
Jeff Johnson295189b2012-06-20 16:38:30 -07005037 __func__);
5038 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
5039 break;
5040#ifdef FEATURE_WLAN_CCX
5041#define WLAN_AKM_SUITE_CCKM 0x00409600 /* Should be in ieee802_11_defs.h */
5042#define IW_AUTH_KEY_MGMT_CCKM 8 /* Should be in linux/wireless.h */
5043 case WLAN_AKM_SUITE_CCKM:
5044 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to CCKM",
5045 __func__);
5046 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_CCKM;
5047 break;
5048#endif
5049
5050 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305051 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported key mgmt type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07005052 __func__, key_mgmt);
5053 return -EINVAL;
5054
5055 }
5056 return 0;
5057}
5058
5059/*
5060 * FUNCTION: wlan_hdd_cfg80211_set_cipher
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305061 * This function is used to set the encryption type
Jeff Johnson295189b2012-06-20 16:38:30 -07005062 * (NONE/WEP40/WEP104/TKIP/CCMP).
5063 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305064static int wlan_hdd_cfg80211_set_cipher( hdd_adapter_t *pAdapter,
5065 u32 cipher,
Jeff Johnson295189b2012-06-20 16:38:30 -07005066 bool ucast
5067 )
5068{
5069 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305070 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07005071 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
5072
5073 ENTER();
5074
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305075 if (!cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -07005076 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305077 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: received cipher %d - considering none",
Jeff Johnson295189b2012-06-20 16:38:30 -07005078 __func__, cipher);
5079 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
5080 }
5081 else
5082 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305083
Jeff Johnson295189b2012-06-20 16:38:30 -07005084 /*set encryption method*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305085 switch (cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -07005086 {
5087 case IW_AUTH_CIPHER_NONE:
5088 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
5089 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305090
Jeff Johnson295189b2012-06-20 16:38:30 -07005091 case WLAN_CIPHER_SUITE_WEP40:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305092 if ((IW_AUTH_KEY_MGMT_802_1X == pWextState->authKeyMgmt) &&
Jeff Johnson295189b2012-06-20 16:38:30 -07005093 (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType))
5094 encryptionType = eCSR_ENCRYPT_TYPE_WEP40;
5095 else
5096 encryptionType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
5097 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305098
Jeff Johnson295189b2012-06-20 16:38:30 -07005099 case WLAN_CIPHER_SUITE_WEP104:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305100 if ((IW_AUTH_KEY_MGMT_802_1X == pWextState->authKeyMgmt) &&
Jeff Johnson295189b2012-06-20 16:38:30 -07005101 (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType))
5102 encryptionType = eCSR_ENCRYPT_TYPE_WEP104;
5103 else
5104 encryptionType = eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
5105 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305106
Jeff Johnson295189b2012-06-20 16:38:30 -07005107 case WLAN_CIPHER_SUITE_TKIP:
5108 encryptionType = eCSR_ENCRYPT_TYPE_TKIP;
5109 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305110
Jeff Johnson295189b2012-06-20 16:38:30 -07005111 case WLAN_CIPHER_SUITE_CCMP:
5112 encryptionType = eCSR_ENCRYPT_TYPE_AES;
5113 break;
5114#ifdef FEATURE_WLAN_WAPI
5115 case WLAN_CIPHER_SUITE_SMS4:
5116 encryptionType = eCSR_ENCRYPT_TYPE_WPI;
5117 break;
5118#endif
5119
5120#ifdef FEATURE_WLAN_CCX
5121 case WLAN_CIPHER_SUITE_KRK:
5122 encryptionType = eCSR_ENCRYPT_TYPE_KRK;
5123 break;
5124#endif
5125 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305126 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported cipher type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07005127 __func__, cipher);
5128 return -EOPNOTSUPP;
5129 }
5130 }
5131
5132 if (ucast)
5133 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305134 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting unicast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07005135 __func__, encryptionType);
5136 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
5137 pWextState->roamProfile.EncryptionType.numEntries = 1;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305138 pWextState->roamProfile.EncryptionType.encryptionType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -07005139 encryptionType;
5140 }
5141 else
5142 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305143 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting mcast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07005144 __func__, encryptionType);
5145 pHddStaCtx->conn_info.mcEncryptionType = encryptionType;
5146 pWextState->roamProfile.mcEncryptionType.numEntries = 1;
5147 pWextState->roamProfile.mcEncryptionType.encryptionType[0] = encryptionType;
5148 }
5149
5150 return 0;
5151}
5152
5153
5154/*
5155 * FUNCTION: wlan_hdd_cfg80211_set_ie
5156 * This function is used to parse WPA/RSN IE's.
5157 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305158int wlan_hdd_cfg80211_set_ie( hdd_adapter_t *pAdapter,
5159 u8 *ie,
Jeff Johnson295189b2012-06-20 16:38:30 -07005160 size_t ie_len
5161 )
5162{
5163 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
5164 u8 *genie = ie;
5165 v_U16_t remLen = ie_len;
5166#ifdef FEATURE_WLAN_WAPI
5167 v_U32_t akmsuite[MAX_NUM_AKM_SUITES];
5168 u16 *tmp;
5169 v_U16_t akmsuiteCount;
5170 int *akmlist;
5171#endif
5172 ENTER();
5173
5174 /* clear previous assocAddIE */
5175 pWextState->assocAddIE.length = 0;
5176 pWextState->roamProfile.bWPSAssociation = VOS_FALSE;
5177
5178 while (remLen >= 2)
5179 {
5180 v_U16_t eLen = 0;
5181 v_U8_t elementId;
5182 elementId = *genie++;
5183 eLen = *genie++;
5184 remLen -= 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305185
5186 hddLog(VOS_TRACE_LEVEL_INFO, "%s: IE[0x%X], LEN[%d]\n",
Jeff Johnson295189b2012-06-20 16:38:30 -07005187 __func__, elementId, eLen);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305188
5189 switch ( elementId )
Jeff Johnson295189b2012-06-20 16:38:30 -07005190 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305191 case DOT11F_EID_WPA:
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005192 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 -07005193 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305194 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07005195 "%s: Invalid WPA IE", __func__);
5196 return -EINVAL;
5197 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305198 else if (0 == memcmp(&genie[0], "\x00\x50\xf2\x04", 4))
Jeff Johnson295189b2012-06-20 16:38:30 -07005199 {
5200 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305201 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPS IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -07005202 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305203
Jeff Johnson295189b2012-06-20 16:38:30 -07005204 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
5205 {
Jeff Johnson902c9832012-12-10 14:28:09 -08005206 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE. "
5207 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -07005208 VOS_ASSERT(0);
5209 return -ENOMEM;
5210 }
5211 // WSC IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
5212 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
5213 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305214
Jeff Johnson295189b2012-06-20 16:38:30 -07005215 pWextState->roamProfile.bWPSAssociation = VOS_TRUE;
5216 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
5217 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
5218 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305219 else if (0 == memcmp(&genie[0], "\x00\x50\xf2", 3))
5220 {
Jeff Johnson295189b2012-06-20 16:38:30 -07005221 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPA IE (len %d)",__func__, eLen + 2);
5222 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
5223 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2) /*ie_len*/);
5224 pWextState->roamProfile.pWPAReqIE = pWextState->WPARSNIE;
5225 pWextState->roamProfile.nWPAReqIELength = eLen + 2;//ie_len;
5226 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305227 else if ( (0 == memcmp(&genie[0], P2P_OUI_TYPE,
5228 P2P_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07005229 /*Consider P2P IE, only for P2P Client */
5230 && (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
5231 {
5232 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305233 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set P2P IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -07005234 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305235
Jeff Johnson295189b2012-06-20 16:38:30 -07005236 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
5237 {
Jeff Johnson902c9832012-12-10 14:28:09 -08005238 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
5239 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -07005240 VOS_ASSERT(0);
5241 return -ENOMEM;
5242 }
5243 // P2P IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
5244 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
5245 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305246
Jeff Johnson295189b2012-06-20 16:38:30 -07005247 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
5248 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
5249 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005250#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305251 else if ( (0 == memcmp(&genie[0], WFD_OUI_TYPE,
5252 WFD_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07005253 /*Consider WFD IE, only for P2P Client */
5254 && (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
5255 {
5256 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305257 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WFD IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -07005258 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305259
Jeff Johnson295189b2012-06-20 16:38:30 -07005260 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
5261 {
Jeff Johnson902c9832012-12-10 14:28:09 -08005262 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
5263 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -07005264 VOS_ASSERT(0);
5265 return -ENOMEM;
5266 }
5267 // WFD IE is saved to Additional IE ; it should be accumulated to handle
5268 // WPS IE + P2P IE + WFD IE
5269 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
5270 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305271
Jeff Johnson295189b2012-06-20 16:38:30 -07005272 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
5273 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
5274 }
5275#endif
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005276 /* Appending HS 2.0 Indication Element in Assiciation Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305277 else if ( (0 == memcmp(&genie[0], HS20_OUI_TYPE,
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07005278 HS20_OUI_TYPE_SIZE)) )
5279 {
5280 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305281 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set HS20 IE(len %d)",
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07005282 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005283
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07005284 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
5285 {
Jeff Johnson902c9832012-12-10 14:28:09 -08005286 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
5287 "Need bigger buffer space");
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07005288 VOS_ASSERT(0);
5289 return -ENOMEM;
5290 }
5291 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
5292 pWextState->assocAddIE.length += eLen + 2;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005293
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07005294 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
5295 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
5296 }
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005297
Jeff Johnson295189b2012-06-20 16:38:30 -07005298 break;
5299 case DOT11F_EID_RSN:
5300 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set RSN IE(len %d)",__func__, eLen + 2);
5301 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
5302 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2)/*ie_len*/);
5303 pWextState->roamProfile.pRSNReqIE = pWextState->WPARSNIE;
5304 pWextState->roamProfile.nRSNReqIELength = eLen + 2; //ie_len;
5305 break;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005306 /* Appending Extended Capabilities with Interworking bit set in Assoc Req */
5307 case DOT11F_EID_EXTCAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305308 {
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005309 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305310 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set Extended CAPS IE(len %d)",
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005311 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305312
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005313 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
5314 {
Jeff Johnson902c9832012-12-10 14:28:09 -08005315 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
5316 "Need bigger buffer space");
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005317 VOS_ASSERT(0);
5318 return -ENOMEM;
5319 }
5320 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
5321 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305322
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005323 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
5324 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
5325 break;
5326 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005327#ifdef FEATURE_WLAN_WAPI
5328 case WLAN_EID_WAPI:
5329 pAdapter->wapi_info.nWapiMode = 1; //Setting WAPI Mode to ON=1
5330 hddLog(VOS_TRACE_LEVEL_INFO,"WAPI MODE IS %lu \n",
5331 pAdapter->wapi_info.nWapiMode);
5332 tmp = (u16 *)ie;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305333 tmp = tmp + 2; // Skip element Id and Len, Version
Jeff Johnson295189b2012-06-20 16:38:30 -07005334 akmsuiteCount = WPA_GET_LE16(tmp);
5335 tmp = tmp + 1;
5336 akmlist = (int *)(tmp);
5337 if(akmsuiteCount <= MAX_NUM_AKM_SUITES)
5338 {
5339 memcpy(akmsuite, akmlist, (4*akmsuiteCount));
5340 }
5341 else
5342 {
5343 hddLog(VOS_TRACE_LEVEL_FATAL, "Invalid akmSuite count\n");
5344 VOS_ASSERT(0);
5345 return -EINVAL;
5346 }
5347
5348 if (WAPI_PSK_AKM_SUITE == akmsuite[0])
5349 {
5350 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO PSK",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005351 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005352 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_PSK;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305353 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005354 if (WAPI_CERT_AKM_SUITE == akmsuite[0])
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305355 {
Jeff Johnson295189b2012-06-20 16:38:30 -07005356 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO CERTIFICATE",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005357 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005358 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_CERT;
5359 }
5360 break;
5361#endif
5362 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305363 hddLog (VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07005364 "%s Set UNKNOWN IE %X", __func__, elementId);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005365 /* when Unknown IE is received we should break and continue
5366 * to the next IE in the buffer instead we were returning
5367 * so changing this to break */
5368 break;
Jeff Johnson295189b2012-06-20 16:38:30 -07005369 }
5370 genie += eLen;
5371 remLen -= eLen;
5372 }
5373 EXIT();
5374 return 0;
5375}
5376
5377/*
5378 * FUNCTION: wlan_hdd_cfg80211_set_privacy
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305379 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -07005380 * parameters during connect operation.
5381 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305382int wlan_hdd_cfg80211_set_privacy( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07005383 struct cfg80211_connect_params *req
5384 )
5385{
5386 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305387 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07005388 ENTER();
5389
5390 /*set wpa version*/
5391 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
5392
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305393 if (req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -07005394 {
5395 if ( (NL80211_WPA_VERSION_1 == req->crypto.wpa_versions)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305396 && ( (req->ie_len)
5397 && (0 == memcmp( &req->ie[2], "\x00\x50\xf2",3) ) ) )
Jeff Johnson295189b2012-06-20 16:38:30 -07005398 // Make sure that it is including a WPA IE.
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305399 /* Currently NL is putting WPA version 1 even for open,
Jeff Johnson295189b2012-06-20 16:38:30 -07005400 * since p2p ie is also put in same buffer.
5401 * */
5402 {
5403 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
5404 }
5405 else if (NL80211_WPA_VERSION_2 == req->crypto.wpa_versions)
5406 {
5407 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
5408 }
5409 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305410
5411 hddLog(VOS_TRACE_LEVEL_INFO, "%s: set wpa version to %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07005412 pWextState->wpaVersion);
5413
5414 /*set authentication type*/
5415 status = wlan_hdd_cfg80211_set_auth_type(pAdapter, req->auth_type);
5416
5417 if (0 > status)
5418 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305419 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07005420 "%s: failed to set authentication type ", __func__);
5421 return status;
5422 }
5423
5424 /*set key mgmt type*/
5425 if (req->crypto.n_akm_suites)
5426 {
5427 status = wlan_hdd_set_akm_suite(pAdapter, req->crypto.akm_suites[0]);
5428 if (0 > status)
5429 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305430 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set akm suite",
Jeff Johnson295189b2012-06-20 16:38:30 -07005431 __func__);
5432 return status;
5433 }
5434 }
5435
5436 /*set pairwise cipher type*/
5437 if (req->crypto.n_ciphers_pairwise)
5438 {
5439 status = wlan_hdd_cfg80211_set_cipher(pAdapter,
5440 req->crypto.ciphers_pairwise[0], true);
5441 if (0 > status)
5442 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305443 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07005444 "%s: failed to set unicast cipher type", __func__);
5445 return status;
5446 }
5447 }
5448 else
5449 {
5450 /*Reset previous cipher suite to none*/
5451 status = wlan_hdd_cfg80211_set_cipher(pAdapter, 0, true);
5452 if (0 > status)
5453 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305454 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07005455 "%s: failed to set unicast cipher type", __func__);
5456 return status;
5457 }
5458 }
5459
5460 /*set group cipher type*/
5461 status = wlan_hdd_cfg80211_set_cipher(pAdapter, req->crypto.cipher_group,
5462 false);
5463
5464 if (0 > status)
5465 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305466 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set mcast cipher type",
Jeff Johnson295189b2012-06-20 16:38:30 -07005467 __func__);
5468 return status;
5469 }
5470
Chet Lanctot186b5732013-03-18 10:26:30 -07005471#ifdef WLAN_FEATURE_11W
5472 pWextState->roamProfile.MFPEnabled = (req->mfp == NL80211_MFP_REQUIRED);
5473#endif
5474
Jeff Johnson295189b2012-06-20 16:38:30 -07005475 /*parse WPA/RSN IE, and set the correspoing fileds in Roam profile*/
5476 if (req->ie_len)
5477 {
5478 status = wlan_hdd_cfg80211_set_ie(pAdapter, req->ie, req->ie_len);
5479 if ( 0 > status)
5480 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305481 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse the WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -07005482 __func__);
5483 return status;
5484 }
5485 }
5486
5487 /*incase of WEP set default key information*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305488 if (req->key && req->key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -07005489 {
5490 if ( (WLAN_CIPHER_SUITE_WEP40 == req->crypto.ciphers_pairwise[0])
5491 || (WLAN_CIPHER_SUITE_WEP104 == req->crypto.ciphers_pairwise[0])
5492 )
5493 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305494 if ( IW_AUTH_KEY_MGMT_802_1X
Jeff Johnson295189b2012-06-20 16:38:30 -07005495 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X ))
5496 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305497 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Dynamic WEP not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -07005498 __func__);
5499 return -EOPNOTSUPP;
5500 }
5501 else
5502 {
5503 u8 key_len = req->key_len;
5504 u8 key_idx = req->key_idx;
5505
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305506 if ((eCSR_SECURITY_WEP_KEYSIZE_MAX_BYTES >= key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -07005507 && (CSR_MAX_NUM_KEY > key_idx)
5508 )
5509 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305510 hddLog(VOS_TRACE_LEVEL_INFO,
5511 "%s: setting default wep key, key_idx = %hu key_len %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07005512 __func__, key_idx, key_len);
5513 vos_mem_copy(
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305514 &pWextState->roamProfile.Keys.KeyMaterial[key_idx][0],
Jeff Johnson295189b2012-06-20 16:38:30 -07005515 req->key, key_len);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305516 pWextState->roamProfile.Keys.KeyLength[key_idx] =
Jeff Johnson295189b2012-06-20 16:38:30 -07005517 (u8)key_len;
5518 pWextState->roamProfile.Keys.defaultIndex = (u8)key_idx;
5519 }
5520 }
5521 }
5522 }
5523
5524 return status;
5525}
5526
5527/*
5528 * FUNCTION: wlan_hdd_cfg80211_set_privacy
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305529 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -07005530 * parameters during connect operation.
5531 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305532static int wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07005533 struct net_device *ndev,
5534 struct cfg80211_connect_params *req
5535 )
5536{
5537 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305538 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -07005539 VOS_STATUS exitbmpsStatus = VOS_STATUS_E_INVAL;
5540 hdd_context_t *pHddCtx = NULL;
5541
5542 ENTER();
5543
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305544 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -07005545 "%s: device_mode = %d\n",__func__,pAdapter->device_mode);
5546
5547 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
5548 {
5549 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5550 "%s:LOGP in Progress. Ignore!!!", __func__);
5551 return -EAGAIN;
5552 }
5553
5554#ifdef WLAN_BTAMP_FEATURE
5555 //Infra connect not supported when AMP traffic is on.
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305556 if( VOS_TRUE == WLANBAP_AmpSessionOn() )
Jeff Johnson295189b2012-06-20 16:38:30 -07005557 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305558 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07005559 "%s: No connection when AMP is on", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08005560 return -ECONNREFUSED;
Jeff Johnson295189b2012-06-20 16:38:30 -07005561 }
5562#endif
5563 /*initialise security parameters*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305564 status = wlan_hdd_cfg80211_set_privacy(pAdapter, req);
Jeff Johnson295189b2012-06-20 16:38:30 -07005565
5566 if ( 0 > status)
5567 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305568 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security params",
Jeff Johnson295189b2012-06-20 16:38:30 -07005569 __func__);
5570 return status;
5571 }
5572
5573 //If Device Mode is Station Concurrent Sessions Exit BMps
Jeff Johnsona8a1a482012-12-12 16:49:33 -08005574 //P2P Mode will be taken care in Open/close adapter
Jeff Johnson295189b2012-06-20 16:38:30 -07005575 if((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
5576 (vos_concurrent_sessions_running()))
5577 {
5578 v_CONTEXT_t pVosContext = vos_get_global_context( VOS_MODULE_ID_HDD, NULL );
5579
5580 if (NULL != pVosContext)
5581 {
5582 pHddCtx = vos_get_context( VOS_MODULE_ID_HDD, pVosContext);
5583 if(NULL != pHddCtx)
5584 {
5585 exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
5586 }
5587 }
5588 }
5589
Mohit Khanna765234a2012-09-11 15:08:35 -07005590 if ( req->channel )
5591 {
5592 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
5593 req->ssid_len, req->bssid,
5594 req->channel->hw_value);
5595 }
5596 else
5597 {
5598 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
5599 req->ssid_len, req->bssid,
5600 0);
5601 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005602
5603 if (0 > status)
5604 {
5605 //ReEnable BMPS if disabled
5606 if((VOS_STATUS_SUCCESS == exitbmpsStatus) &&
5607 (NULL != pHddCtx))
5608 {
5609 //ReEnable Bmps and Imps back
5610 hdd_enable_bmps_imps(pHddCtx);
5611 }
5612
5613 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: connect failed", __func__);
5614 return status;
5615 }
5616 (WLAN_HDD_GET_CTX(pAdapter))->isAmpAllowed = VOS_FALSE;
5617 EXIT();
5618 return status;
5619}
5620
5621
5622/*
5623 * FUNCTION: wlan_hdd_cfg80211_disconnect
5624 * This function is used to issue a disconnect request to SME
5625 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305626static int wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07005627 struct net_device *dev,
5628 u16 reason
5629 )
5630{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305631 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
5632 tCsrRoamProfile *pRoamProfile =
Jeff Johnson295189b2012-06-20 16:38:30 -07005633 &(WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter))->roamProfile;
5634 int status = 0;
5635 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08005636#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala4327a152013-03-04 23:22:42 -08005637 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08005638 tANI_U8 staIdx;
5639#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305640
Jeff Johnson295189b2012-06-20 16:38:30 -07005641 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305642
5643 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",
Jeff Johnson295189b2012-06-20 16:38:30 -07005644 __func__,pAdapter->device_mode);
5645
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305646 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Disconnect called with reason code %d",
5647 __func__, reason);
Jeff Johnson295189b2012-06-20 16:38:30 -07005648
5649 if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress)
5650 {
5651 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5652 "%s:LOGP in Progress. Ignore!!!",__func__);
5653 return -EAGAIN;
5654 }
5655 if (NULL != pRoamProfile)
5656 {
5657 /*issue disconnect request to SME, if station is in connected state*/
5658 if (pHddStaCtx->conn_info.connState == eConnectionState_Associated)
5659 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305660 eCsrRoamDisconnectReason reasonCode =
Jeff Johnson295189b2012-06-20 16:38:30 -07005661 eCSR_DISCONNECT_REASON_UNSPECIFIED;
5662 switch(reason)
5663 {
5664 case WLAN_REASON_MIC_FAILURE:
5665 reasonCode = eCSR_DISCONNECT_REASON_MIC_ERROR;
5666 break;
5667
5668 case WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY:
5669 case WLAN_REASON_DISASSOC_AP_BUSY:
5670 case WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA:
5671 reasonCode = eCSR_DISCONNECT_REASON_DISASSOC;
5672 break;
5673
5674 case WLAN_REASON_PREV_AUTH_NOT_VALID:
5675 case WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA:
5676 reasonCode = eCSR_DISCONNECT_REASON_DEAUTH;
5677 break;
5678
5679 case WLAN_REASON_DEAUTH_LEAVING:
5680 default:
5681 reasonCode = eCSR_DISCONNECT_REASON_UNSPECIFIED;
5682 break;
5683 }
5684 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
5685 (WLAN_HDD_GET_CTX(pAdapter))->isAmpAllowed = VOS_TRUE;
5686 INIT_COMPLETION(pAdapter->disconnect_comp_var);
5687
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08005688#ifdef FEATURE_WLAN_TDLS
5689 /* First clean up the tdls peers if any */
Gopichand Nakkala4327a152013-03-04 23:22:42 -08005690 for (staIdx = 0 ; staIdx < HDD_MAX_NUM_TDLS_STA; staIdx++)
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08005691 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -08005692 if ((pHddCtx->tdlsConnInfo[staIdx].sessionId == pAdapter->sessionId) &&
5693 (pHddCtx->tdlsConnInfo[staIdx].staId))
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08005694 {
Hoonki Lee11f7dda2013-02-14 16:55:44 -08005695 uint8 *mac;
Gopichand Nakkala4327a152013-03-04 23:22:42 -08005696 mac = pHddCtx->tdlsConnInfo[staIdx].peerMac.bytes;
Hoonki Lee11f7dda2013-02-14 16:55:44 -08005697 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07005698 "%s: call sme_DeleteTdlsPeerSta staId %d sessionId %d " MAC_ADDRESS_STR,
Gopichand Nakkala4327a152013-03-04 23:22:42 -08005699 __func__, pHddCtx->tdlsConnInfo[staIdx].staId, pAdapter->sessionId,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07005700 MAC_ADDR_ARRAY(mac));
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08005701 sme_DeleteTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala4327a152013-03-04 23:22:42 -08005702 pAdapter->sessionId,
5703 mac);
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08005704 }
5705 }
5706#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005707 /*issue disconnect*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305708 status = sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07005709 pAdapter->sessionId, reasonCode);
5710
5711 if ( 0 != status)
5712 {
5713 hddLog(VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305714 "%s csrRoamDisconnect failure, returned %d \n",
Jeff Johnson295189b2012-06-20 16:38:30 -07005715 __func__, (int)status );
5716 return -EINVAL;
5717 }
5718
5719 wait_for_completion_interruptible_timeout(
5720 &pAdapter->disconnect_comp_var,
5721 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
5722
5723
5724 /*stop tx queues*/
5725 netif_tx_disable(dev);
5726 netif_carrier_off(dev);
5727 }
5728 }
5729 else
5730 {
5731 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid roam profile", __func__);
5732 }
5733
5734 return status;
5735}
5736
5737/*
5738 * FUNCTION: wlan_hdd_cfg80211_set_privacy_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305739 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -07005740 * settings in IBSS mode.
5741 */
5742static int wlan_hdd_cfg80211_set_privacy_ibss(
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305743 hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07005744 struct cfg80211_ibss_params *params
5745 )
5746{
5747 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305748 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07005749 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
5750 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305751
Jeff Johnson295189b2012-06-20 16:38:30 -07005752 ENTER();
5753
5754 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
5755
5756 if (params->ie_len && ( NULL != params->ie) )
5757 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305758 if (WLAN_EID_RSN == params->ie[0])
Jeff Johnson295189b2012-06-20 16:38:30 -07005759 {
5760 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
5761 encryptionType = eCSR_ENCRYPT_TYPE_AES;
5762 }
5763 else
5764 {
5765 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
5766 encryptionType = eCSR_ENCRYPT_TYPE_TKIP;
5767 }
5768 status = wlan_hdd_cfg80211_set_ie(pAdapter, params->ie, params->ie_len);
5769
5770 if (0 > status)
5771 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305772 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -07005773 __func__);
5774 return status;
5775 }
5776 }
5777
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305778 pWextState->roamProfile.AuthType.authType[0] =
5779 pHddStaCtx->conn_info.authType =
Jeff Johnson295189b2012-06-20 16:38:30 -07005780 eCSR_AUTH_TYPE_OPEN_SYSTEM;
5781
5782 if (params->privacy)
5783 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305784 /* Security enabled IBSS, At this time there is no information available
5785 * about the security paramters, so initialise the encryption type to
Jeff Johnson295189b2012-06-20 16:38:30 -07005786 * eCSR_ENCRYPT_TYPE_WEP40_STATICKEY.
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305787 * The correct security parameters will be updated later in
Jeff Johnson295189b2012-06-20 16:38:30 -07005788 * wlan_hdd_cfg80211_add_key */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305789 /* Hal expects encryption type to be set inorder
Jeff Johnson295189b2012-06-20 16:38:30 -07005790 *enable privacy bit in beacons */
5791
5792 encryptionType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
5793 }
5794
5795 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
5796 pWextState->roamProfile.EncryptionType.numEntries = 1;
5797 pWextState->roamProfile.EncryptionType.encryptionType[0] = encryptionType;
5798
5799 return status;
5800}
5801
5802/*
5803 * FUNCTION: wlan_hdd_cfg80211_join_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305804 * This function is used to create/join an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -07005805 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305806static int wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07005807 struct net_device *dev,
5808 struct cfg80211_ibss_params *params
5809 )
5810{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305811 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Jeff Johnson295189b2012-06-20 16:38:30 -07005812 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
5813 tCsrRoamProfile *pRoamProfile;
5814 int status;
5815 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
5816
5817 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305818
5819 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -07005820 "%s: device_mode = %d\n",__func__,pAdapter->device_mode);
5821
5822 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
5823 {
5824 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5825 "%s:LOGP in Progress. Ignore!!!", __func__);
5826 return -EAGAIN;
5827 }
5828
5829 if (NULL == pWextState)
5830 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305831 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption\n",
Jeff Johnson295189b2012-06-20 16:38:30 -07005832 __func__);
5833 return -EIO;
5834 }
5835
5836 pRoamProfile = &pWextState->roamProfile;
5837
5838 if ( eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType )
5839 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305840 hddLog (VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07005841 "%s Interface type is not set to IBSS \n", __func__);
5842 return -EINVAL;
5843 }
5844
5845 /* Set Channel */
5846 if (NULL != params->channel)
5847 {
5848 u8 channelNum;
5849 if (IEEE80211_BAND_5GHZ == params->channel->band)
5850 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305851 hddLog(VOS_TRACE_LEVEL_ERROR,
5852 "%s: IBSS join is called with unsupported band %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07005853 __func__, params->channel->band);
5854 return -EOPNOTSUPP;
5855 }
5856
5857 /* Get channel number */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305858 channelNum =
Jeff Johnson295189b2012-06-20 16:38:30 -07005859 ieee80211_frequency_to_channel(params->channel->center_freq);
5860
5861 /*TODO: use macro*/
5862 if (14 >= channelNum)
5863 {
5864 v_U32_t numChans = WNI_CFG_VALID_CHANNEL_LIST_LEN;
5865 v_U8_t validChan[WNI_CFG_VALID_CHANNEL_LIST_LEN];
5866 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
5867 int indx;
5868
5869 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
5870 validChan, &numChans))
5871 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305872 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid channel list",
Jeff Johnson295189b2012-06-20 16:38:30 -07005873 __func__);
5874 return -EOPNOTSUPP;
5875 }
5876
5877 for (indx = 0; indx < numChans; indx++)
5878 {
5879 if (channelNum == validChan[indx])
5880 {
5881 break;
5882 }
5883 }
5884 if (indx >= numChans)
5885 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305886 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Not valid Channel %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07005887 __func__, channelNum);
5888 return -EINVAL;
5889 }
5890 /* Set the Operational Channel */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305891 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: set channel %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07005892 channelNum);
5893 pRoamProfile->ChannelInfo.numOfChannels = 1;
5894 pHddStaCtx->conn_info.operationChannel = channelNum;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305895 pRoamProfile->ChannelInfo.ChannelList =
Jeff Johnson295189b2012-06-20 16:38:30 -07005896 &pHddStaCtx->conn_info.operationChannel;
5897 }
5898 else
5899 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305900 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Not valid Channel %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07005901 __func__, channelNum);
5902 return -EINVAL;
5903 }
5904 }
5905
5906 /* Initialize security parameters */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305907 status = wlan_hdd_cfg80211_set_privacy_ibss(pAdapter, params);
Jeff Johnson295189b2012-06-20 16:38:30 -07005908 if (status < 0)
5909 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305910 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security parameters",
Jeff Johnson295189b2012-06-20 16:38:30 -07005911 __func__);
5912 return status;
5913 }
5914
5915 /* Issue connect start */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305916 status = wlan_hdd_cfg80211_connect_start(pAdapter, params->ssid,
Jeff Johnson32d95a32012-09-10 13:15:23 -07005917 params->ssid_len, params->bssid, 0);
Jeff Johnson295189b2012-06-20 16:38:30 -07005918
5919 if (0 > status)
5920 {
5921 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: connect failed", __func__);
5922 return status;
5923 }
5924
5925 return 0;
5926}
5927
5928/*
5929 * FUNCTION: wlan_hdd_cfg80211_leave_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305930 * This function is used to leave an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -07005931 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305932static int wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07005933 struct net_device *dev
5934 )
5935{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305936 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Jeff Johnson295189b2012-06-20 16:38:30 -07005937 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
5938 tCsrRoamProfile *pRoamProfile;
5939
5940 ENTER();
5941
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005942 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
5943 {
5944 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5945 "%s:LOGP in Progress. Ignore!!!", __func__);
5946 return -EAGAIN;
5947 }
5948
Jeff Johnson295189b2012-06-20 16:38:30 -07005949 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",__func__,pAdapter->device_mode);
5950 if (NULL == pWextState)
5951 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305952 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption\n",
Jeff Johnson295189b2012-06-20 16:38:30 -07005953 __func__);
5954 return -EIO;
5955 }
5956
5957 pRoamProfile = &pWextState->roamProfile;
5958
5959 /* Issue disconnect only if interface type is set to IBSS */
5960 if (eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType)
5961 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305962 hddLog (VOS_TRACE_LEVEL_ERROR, "%s: BSS Type is not set to IBSS",
Jeff Johnson295189b2012-06-20 16:38:30 -07005963 __func__);
5964 return -EINVAL;
5965 }
5966
5967 /* Issue Disconnect request */
5968 INIT_COMPLETION(pAdapter->disconnect_comp_var);
5969 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
5970 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
5971
5972 return 0;
5973}
5974
5975/*
5976 * FUNCTION: wlan_hdd_cfg80211_set_wiphy_params
5977 * This function is used to set the phy parameters
5978 * (RTS Threshold/FRAG Threshold/Retry Count etc ...)
5979 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305980static int wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07005981 u32 changed)
5982{
5983 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5984 tHalHandle hHal = pHddCtx->hHal;
5985
5986 ENTER();
5987
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005988 if ( pHddCtx->isLogpInProgress )
5989 {
5990 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5991 "%s:LOGP in Progress. Ignore!!!", __func__);
5992 return -EAGAIN;
5993 }
5994
Jeff Johnson295189b2012-06-20 16:38:30 -07005995 if (changed & WIPHY_PARAM_RTS_THRESHOLD)
5996 {
5997 u16 rts_threshold = (wiphy->rts_threshold == -1) ?
5998 WNI_CFG_RTS_THRESHOLD_STAMAX :
5999 wiphy->rts_threshold;
6000
6001 if ((WNI_CFG_RTS_THRESHOLD_STAMIN > rts_threshold) ||
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306002 (WNI_CFG_RTS_THRESHOLD_STAMAX < rts_threshold))
Jeff Johnson295189b2012-06-20 16:38:30 -07006003 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306004 hddLog(VOS_TRACE_LEVEL_ERROR,
6005 "%s: Invalid RTS Threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07006006 __func__, rts_threshold);
6007 return -EINVAL;
6008 }
6009
6010 if (0 != ccmCfgSetInt(hHal, WNI_CFG_RTS_THRESHOLD,
6011 rts_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306012 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -07006013 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306014 hddLog(VOS_TRACE_LEVEL_ERROR,
6015 "%s: ccmCfgSetInt failed for rts_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07006016 __func__, rts_threshold);
6017 return -EIO;
6018 }
6019
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306020 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set rts threshold %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07006021 rts_threshold);
6022 }
6023
6024 if (changed & WIPHY_PARAM_FRAG_THRESHOLD)
6025 {
6026 u16 frag_threshold = (wiphy->frag_threshold == -1) ?
6027 WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX :
6028 wiphy->frag_threshold;
6029
6030 if ((WNI_CFG_FRAGMENTATION_THRESHOLD_STAMIN > frag_threshold)||
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306031 (WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX < frag_threshold) )
Jeff Johnson295189b2012-06-20 16:38:30 -07006032 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306033 hddLog(VOS_TRACE_LEVEL_ERROR,
6034 "%s: Invalid frag_threshold value %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07006035 frag_threshold);
6036 return -EINVAL;
6037 }
6038
6039 if (0 != ccmCfgSetInt(hHal, WNI_CFG_FRAGMENTATION_THRESHOLD,
6040 frag_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306041 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -07006042 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306043 hddLog(VOS_TRACE_LEVEL_ERROR,
6044 "%s: ccmCfgSetInt failed for frag_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07006045 __func__, frag_threshold);
6046 return -EIO;
6047 }
6048
6049 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set frag threshold %hu", __func__,
6050 frag_threshold);
6051 }
6052
6053 if ((changed & WIPHY_PARAM_RETRY_SHORT)
6054 || (changed & WIPHY_PARAM_RETRY_LONG))
6055 {
6056 u8 retry_value = (changed & WIPHY_PARAM_RETRY_SHORT) ?
6057 wiphy->retry_short :
6058 wiphy->retry_long;
6059
6060 if ((WNI_CFG_LONG_RETRY_LIMIT_STAMIN > retry_value) ||
6061 (WNI_CFG_LONG_RETRY_LIMIT_STAMAX < retry_value))
6062 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306063 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07006064 __func__, retry_value);
6065 return -EINVAL;
6066 }
6067
6068 if (changed & WIPHY_PARAM_RETRY_SHORT)
6069 {
6070 if (0 != ccmCfgSetInt(hHal, WNI_CFG_LONG_RETRY_LIMIT,
6071 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306072 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -07006073 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306074 hddLog(VOS_TRACE_LEVEL_ERROR,
6075 "%s: ccmCfgSetInt failed for long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07006076 __func__, retry_value);
6077 return -EIO;
6078 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306079 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07006080 __func__, retry_value);
6081 }
6082 else if (changed & WIPHY_PARAM_RETRY_SHORT)
6083 {
6084 if (0 != ccmCfgSetInt(hHal, WNI_CFG_SHORT_RETRY_LIMIT,
6085 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306086 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -07006087 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306088 hddLog(VOS_TRACE_LEVEL_ERROR,
6089 "%s: ccmCfgSetInt failed for short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07006090 __func__, retry_value);
6091 return -EIO;
6092 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306093 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07006094 __func__, retry_value);
6095 }
6096 }
6097
6098 return 0;
6099}
6100
6101/*
6102 * FUNCTION: wlan_hdd_cfg80211_set_txpower
6103 * This function is used to set the txpower
6104 */
6105static int wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
6106#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306107 enum tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -07006108#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306109 enum nl80211_tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -07006110#endif
6111 int dbm)
6112{
6113 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
6114 tHalHandle hHal = pHddCtx->hHal;
6115 tSirMacAddr bssid = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
6116 tSirMacAddr selfMac = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
6117
6118 ENTER();
6119
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306120 if (0 != ccmCfgSetInt(hHal, WNI_CFG_CURRENT_TX_POWER_LEVEL,
6121 dbm, ccmCfgSetCallback,
6122 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -07006123 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306124 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07006125 "%s: ccmCfgSetInt failed for tx power %hu", __func__, dbm);
6126 return -EIO;
6127 }
6128
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006129 if ( pHddCtx->isLogpInProgress )
6130 {
6131 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6132 "%s:LOGP in Progress. Ignore!!!", __func__);
6133 return -EAGAIN;
6134 }
6135
Jeff Johnson295189b2012-06-20 16:38:30 -07006136 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set tx power level %d dbm", __func__,
6137 dbm);
6138
6139 switch(type)
6140 {
6141 case NL80211_TX_POWER_AUTOMATIC: /*automatically determine transmit power*/
6142 /* Fall through */
6143 case NL80211_TX_POWER_LIMITED: /*limit TX power by the mBm parameter*/
6144 if( sme_SetMaxTxPower(hHal, bssid, selfMac, dbm) != eHAL_STATUS_SUCCESS )
6145 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306146 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Setting maximum tx power failed",
6147 __func__);
6148 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -07006149 }
6150 break;
6151 case NL80211_TX_POWER_FIXED: /*fix TX power to the mBm parameter*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306152 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: NL80211_TX_POWER_FIXED not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -07006153 __func__);
6154 return -EOPNOTSUPP;
6155 break;
6156 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306157 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid power setting type %d",
6158 __func__, type);
Jeff Johnson295189b2012-06-20 16:38:30 -07006159 return -EIO;
6160 }
6161
6162 return 0;
6163}
6164
6165/*
6166 * FUNCTION: wlan_hdd_cfg80211_get_txpower
6167 * This function is used to read the txpower
6168 */
6169static int wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy, int *dbm)
6170{
6171
6172 hdd_adapter_t *pAdapter;
6173 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
6174
Jeff Johnsone7245742012-09-05 17:12:55 -07006175 ENTER();
6176
Jeff Johnson295189b2012-06-20 16:38:30 -07006177 if (NULL == pHddCtx)
6178 {
6179 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD context is Null",__func__);
6180 *dbm = 0;
6181 return -ENOENT;
6182 }
6183
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006184 if ( pHddCtx->isLogpInProgress )
6185 {
6186 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6187 "%s:LOGP in Progress. Ignore!!!", __func__);
6188 return -EAGAIN;
6189 }
6190
Jeff Johnson295189b2012-06-20 16:38:30 -07006191 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
6192 if (NULL == pAdapter)
6193 {
6194 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Not in station context " ,__func__);
6195 return -ENOENT;
6196 }
6197
6198 wlan_hdd_get_classAstats(pAdapter);
6199 *dbm = pAdapter->hdd_stats.ClassA_stat.max_pwr;
6200
Jeff Johnsone7245742012-09-05 17:12:55 -07006201 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07006202 return 0;
6203}
6204
6205static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
6206 u8* mac, struct station_info *sinfo)
6207{
6208 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
6209 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6210 int ssidlen = pHddStaCtx->conn_info.SSID.SSID.length;
6211 tANI_U8 rate_flags;
6212
6213 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
6214 hdd_config_t *pCfg = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -07006215
6216 tANI_U8 OperationalRates[CSR_DOT11_SUPPORTED_RATES_MAX];
6217 tANI_U32 ORLeng = CSR_DOT11_SUPPORTED_RATES_MAX;
6218 tANI_U8 ExtendedRates[CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX];
6219 tANI_U32 ERLeng = CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX;
6220 tANI_U8 MCSRates[SIZE_OF_BASIC_MCS_SET];
6221 tANI_U32 MCSLeng = SIZE_OF_BASIC_MCS_SET;
6222 tANI_U16 maxRate = 0;
6223 tANI_U16 myRate;
6224 tANI_U16 currentRate = 0;
6225 tANI_U8 maxSpeedMCS = 0;
6226 tANI_U8 maxMCSIdx = 0;
6227 tANI_U8 rateFlag = 1;
6228 tANI_U8 i, j, rssidx;
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07006229 tANI_U16 temp;
Jeff Johnson295189b2012-06-20 16:38:30 -07006230
Leo Chang6f8870f2013-03-26 18:11:36 -07006231#ifdef WLAN_FEATURE_11AC
6232 tANI_U32 vht_mcs_map;
6233 eDataRate11ACMaxMcs vhtMaxMcs;
6234#endif /* WLAN_FEATURE_11AC */
6235
Jeff Johnsone7245742012-09-05 17:12:55 -07006236 ENTER();
6237
Jeff Johnson295189b2012-06-20 16:38:30 -07006238 if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) ||
6239 (0 == ssidlen))
6240 {
6241 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Not associated or"
6242 " Invalid ssidlen, %d", __func__, ssidlen);
6243 /*To keep GUI happy*/
6244 return 0;
6245 }
6246
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006247 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
6248 {
6249 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6250 "%s:LOGP in Progress. Ignore!!!", __func__);
6251 return -EAGAIN;
6252 }
6253
Jeff Johnson295189b2012-06-20 16:38:30 -07006254 wlan_hdd_get_rssi(pAdapter, &sinfo->signal);
6255 sinfo->filled |= STATION_INFO_SIGNAL;
6256
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -07006257 wlan_hdd_get_station_stats(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07006258 rate_flags = pAdapter->hdd_stats.ClassA_stat.tx_rate_flags;
6259
6260 //convert to the UI units of 100kbps
6261 myRate = pAdapter->hdd_stats.ClassA_stat.tx_rate * 5;
6262
6263#ifdef LINKSPEED_DEBUG_ENABLED
Leo Chang6f8870f2013-03-26 18:11:36 -07006264 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 -07006265 sinfo->signal,
6266 pCfg->reportMaxLinkSpeed,
6267 myRate,
6268 (int) pCfg->linkSpeedRssiHigh,
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07006269 (int) pCfg->linkSpeedRssiMid,
6270 (int) pCfg->linkSpeedRssiLow,
Leo Chang6f8870f2013-03-26 18:11:36 -07006271 (int) rate_flags,
6272 (int) pAdapter->hdd_stats.ClassA_stat.mcs_index);
Jeff Johnson295189b2012-06-20 16:38:30 -07006273#endif //LINKSPEED_DEBUG_ENABLED
6274
6275 if (eHDD_LINK_SPEED_REPORT_ACTUAL != pCfg->reportMaxLinkSpeed)
6276 {
6277 // we do not want to necessarily report the current speed
6278 if (eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed)
6279 {
6280 // report the max possible speed
6281 rssidx = 0;
6282 }
6283 else if (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed)
6284 {
6285 // report the max possible speed with RSSI scaling
6286 if (sinfo->signal >= pCfg->linkSpeedRssiHigh)
6287 {
6288 // report the max possible speed
6289 rssidx = 0;
6290 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07006291 else if (sinfo->signal >= pCfg->linkSpeedRssiMid)
Jeff Johnson295189b2012-06-20 16:38:30 -07006292 {
6293 // report middle speed
6294 rssidx = 1;
6295 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07006296 else if (sinfo->signal >= pCfg->linkSpeedRssiLow)
6297 {
6298 // report middle speed
6299 rssidx = 2;
6300 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006301 else
6302 {
6303 // report actual speed
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07006304 rssidx = 3;
Jeff Johnson295189b2012-06-20 16:38:30 -07006305 }
6306 }
6307 else
6308 {
6309 // unknown, treat as eHDD_LINK_SPEED_REPORT_MAX
6310 hddLog(VOS_TRACE_LEVEL_ERROR,
6311 "%s: Invalid value for reportMaxLinkSpeed: %u",
6312 __func__, pCfg->reportMaxLinkSpeed);
6313 rssidx = 0;
6314 }
6315
6316 maxRate = 0;
6317
6318 /* Get Basic Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +05306319 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_OPERATIONAL_RATE_SET,
6320 OperationalRates, &ORLeng))
6321 {
6322 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
6323 /*To keep GUI happy*/
6324 return 0;
6325 }
6326
Jeff Johnson295189b2012-06-20 16:38:30 -07006327 for (i = 0; i < ORLeng; i++)
6328 {
Jeff Johnsone7245742012-09-05 17:12:55 -07006329 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -07006330 {
6331 /* Validate Rate Set */
6332 if (supported_data_rate[j].beacon_rate_index == (OperationalRates[i] & 0x7F))
6333 {
6334 currentRate = supported_data_rate[j].supported_rate[rssidx];
6335 break;
6336 }
6337 }
6338 /* Update MAX rate */
6339 maxRate = (currentRate > maxRate)?currentRate:maxRate;
6340 }
6341
6342 /* Get Extended Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +05306343 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET,
6344 ExtendedRates, &ERLeng))
6345 {
6346 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
6347 /*To keep GUI happy*/
6348 return 0;
6349 }
6350
Jeff Johnson295189b2012-06-20 16:38:30 -07006351 for (i = 0; i < ERLeng; i++)
6352 {
Jeff Johnsone7245742012-09-05 17:12:55 -07006353 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -07006354 {
6355 if (supported_data_rate[j].beacon_rate_index == (ExtendedRates[i] & 0x7F))
6356 {
6357 currentRate = supported_data_rate[j].supported_rate[rssidx];
6358 break;
6359 }
6360 }
6361 /* Update MAX rate */
6362 maxRate = (currentRate > maxRate)?currentRate:maxRate;
6363 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006364 /* Get MCS Rate Set -- but only if we are connected at MCS
6365 rates or if we are always reporting max speed or if we have
6366 good rssi */
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07006367 if ((0 == rssidx) && !(rate_flags & eHAL_TX_RATE_LEGACY))
Jeff Johnson295189b2012-06-20 16:38:30 -07006368 {
Gopichand Nakkala05ab1322013-02-15 11:28:38 +05306369 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_CURRENT_MCS_SET,
6370 MCSRates, &MCSLeng))
6371 {
6372 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
6373 /*To keep GUI happy*/
6374 return 0;
6375 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006376 rateFlag = 0;
Leo Chang6f8870f2013-03-26 18:11:36 -07006377#ifdef WLAN_FEATURE_11AC
6378 /* VHT80 rate has seperate rate table */
Gopichand Nakkala4c705372013-04-24 13:20:33 +05306379 if (rate_flags & (eHAL_TX_RATE_VHT20|eHAL_TX_RATE_VHT40|eHAL_TX_RATE_VHT80))
Jeff Johnson295189b2012-06-20 16:38:30 -07006380 {
Leo Chang6f8870f2013-03-26 18:11:36 -07006381 ccmCfgGetInt(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_VHT_TX_MCS_MAP, &vht_mcs_map);
Gopichand Nakkala4c705372013-04-24 13:20:33 +05306382 vhtMaxMcs = (eDataRate11ACMaxMcs)(vht_mcs_map & DATA_RATE_11AC_MCS_MASK );
Leo Chang6f8870f2013-03-26 18:11:36 -07006383 if (rate_flags & eHAL_TX_RATE_SGI)
Jeff Johnson295189b2012-06-20 16:38:30 -07006384 {
Leo Chang6f8870f2013-03-26 18:11:36 -07006385 rateFlag |= 1;
Jeff Johnson295189b2012-06-20 16:38:30 -07006386 }
Leo Chang6f8870f2013-03-26 18:11:36 -07006387 if (DATA_RATE_11AC_MAX_MCS_7 == vhtMaxMcs)
Jeff Johnson295189b2012-06-20 16:38:30 -07006388 {
Leo Chang6f8870f2013-03-26 18:11:36 -07006389 maxMCSIdx = 7;
6390 }
6391 else if (DATA_RATE_11AC_MAX_MCS_8 == vhtMaxMcs)
6392 {
6393 maxMCSIdx = 8;
6394 }
6395 else if (DATA_RATE_11AC_MAX_MCS_9 == vhtMaxMcs)
6396 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +05306397 //VHT20 is supporting 0~8
6398 if (rate_flags & eHAL_TX_RATE_VHT20)
6399 maxMCSIdx = 8;
6400 else
6401 maxMCSIdx = 9;
Leo Chang6f8870f2013-03-26 18:11:36 -07006402 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +05306403
6404 if (rate_flags & eHAL_TX_RATE_VHT80)
6405 {
6406 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT80_rate[rateFlag];
6407 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT80_rate[rateFlag];
6408 }
6409 else if (rate_flags & eHAL_TX_RATE_VHT40)
6410 {
6411 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT40_rate[rateFlag];
6412 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT40_rate[rateFlag];
6413 }
6414 else if (rate_flags & eHAL_TX_RATE_VHT20)
6415 {
6416 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT20_rate[rateFlag];
6417 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT20_rate[rateFlag];
6418 }
6419
Leo Chang6f8870f2013-03-26 18:11:36 -07006420 maxSpeedMCS = 1;
6421 if (currentRate > maxRate)
6422 {
6423 maxRate = currentRate;
6424 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +05306425
Leo Chang6f8870f2013-03-26 18:11:36 -07006426 }
6427 else
6428#endif /* WLAN_FEATURE_11AC */
6429 {
6430 if (rate_flags & eHAL_TX_RATE_HT40)
6431 {
6432 rateFlag |= 1;
6433 }
6434 if (rate_flags & eHAL_TX_RATE_SGI)
6435 {
6436 rateFlag |= 2;
6437 }
6438
6439 for (i = 0; i < MCSLeng; i++)
6440 {
6441 temp = sizeof(supported_mcs_rate) / sizeof(supported_mcs_rate[0]);
6442 for (j = 0; j < temp; j++)
6443 {
6444 if (supported_mcs_rate[j].beacon_rate_index == MCSRates[i])
6445 {
6446 currentRate = supported_mcs_rate[j].supported_rate[rateFlag];
6447 break;
6448 }
6449 }
6450 if ((j < temp) && (currentRate > maxRate))
6451 {
6452 maxRate = currentRate;
6453 maxSpeedMCS = 1;
6454 maxMCSIdx = supported_mcs_rate[j].beacon_rate_index;
6455 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006456 }
6457 }
6458 }
6459
Gopichand Nakkala4c705372013-04-24 13:20:33 +05306460 else if (!(rate_flags & eHAL_TX_RATE_LEGACY))
6461 {
6462 maxRate = myRate;
6463 maxSpeedMCS = 1;
6464 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
6465 }
6466
Jeff Johnson295189b2012-06-20 16:38:30 -07006467 // make sure we report a value at least as big as our current rate
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07006468 if (((maxRate < myRate) && (0 == rssidx)) ||
6469 (0 == maxRate))
Jeff Johnson295189b2012-06-20 16:38:30 -07006470 {
6471 maxRate = myRate;
6472 if (rate_flags & eHAL_TX_RATE_LEGACY)
6473 {
6474 maxSpeedMCS = 0;
6475 }
6476 else
6477 {
6478 maxSpeedMCS = 1;
6479 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
6480 }
6481 }
6482
Gopichand Nakkala4c705372013-04-24 13:20:33 +05306483 if (rate_flags & eHAL_TX_RATE_LEGACY)
Jeff Johnson295189b2012-06-20 16:38:30 -07006484 {
6485 sinfo->txrate.legacy = maxRate;
6486#ifdef LINKSPEED_DEBUG_ENABLED
6487 pr_info("Reporting legacy rate %d\n", sinfo->txrate.legacy);
6488#endif //LINKSPEED_DEBUG_ENABLED
6489 }
6490 else
6491 {
6492 sinfo->txrate.mcs = maxMCSIdx;
Leo Chang6f8870f2013-03-26 18:11:36 -07006493#ifdef WLAN_FEATURE_11AC
6494 sinfo->txrate.nss = 1;
6495 if (rate_flags & eHAL_TX_RATE_VHT80)
6496 {
6497 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
Gopichand Nakkala4c705372013-04-24 13:20:33 +05306498 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
Leo Chang6f8870f2013-03-26 18:11:36 -07006499 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +05306500 else if (rate_flags & eHAL_TX_RATE_VHT40)
Leo Chang6f8870f2013-03-26 18:11:36 -07006501 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +05306502 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
6503 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
6504 }
6505 else if (rate_flags & eHAL_TX_RATE_VHT20)
6506 {
6507 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
6508 }
6509#endif /* WLAN_FEATURE_11AC */
6510 if (rate_flags & (eHAL_TX_RATE_HT20 | eHAL_TX_RATE_HT40))
6511 {
6512 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
6513 if (rate_flags & eHAL_TX_RATE_HT40)
6514 {
6515 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
6516 }
Leo Chang6f8870f2013-03-26 18:11:36 -07006517 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006518 if (rate_flags & eHAL_TX_RATE_SGI)
6519 {
6520 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
6521 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +05306522
Jeff Johnson295189b2012-06-20 16:38:30 -07006523#ifdef LINKSPEED_DEBUG_ENABLED
6524 pr_info("Reporting MCS rate %d flags %x\n",
6525 sinfo->txrate.mcs,
6526 sinfo->txrate.flags );
6527#endif //LINKSPEED_DEBUG_ENABLED
6528 }
6529 }
6530 else
6531 {
6532 // report current rate instead of max rate
6533
6534 if (rate_flags & eHAL_TX_RATE_LEGACY)
6535 {
6536 //provide to the UI in units of 100kbps
6537 sinfo->txrate.legacy = myRate;
6538#ifdef LINKSPEED_DEBUG_ENABLED
6539 pr_info("Reporting actual legacy rate %d\n", sinfo->txrate.legacy);
6540#endif //LINKSPEED_DEBUG_ENABLED
6541 }
6542 else
6543 {
6544 //must be MCS
6545 sinfo->txrate.mcs = pAdapter->hdd_stats.ClassA_stat.mcs_index;
Leo Chang6f8870f2013-03-26 18:11:36 -07006546#ifdef WLAN_FEATURE_11AC
6547 sinfo->txrate.nss = 1;
6548 if (rate_flags & eHAL_TX_RATE_VHT80)
6549 {
6550 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
6551 }
6552 else
6553#endif /* WLAN_FEATURE_11AC */
6554 {
6555 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
6556 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006557 if (rate_flags & eHAL_TX_RATE_SGI)
6558 {
6559 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
6560 }
6561 if (rate_flags & eHAL_TX_RATE_HT40)
6562 {
6563 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
6564 }
Leo Chang6f8870f2013-03-26 18:11:36 -07006565#ifdef WLAN_FEATURE_11AC
6566 else if (rate_flags & eHAL_TX_RATE_VHT80)
6567 {
6568 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
6569 }
6570#endif /* WLAN_FEATURE_11AC */
Jeff Johnson295189b2012-06-20 16:38:30 -07006571#ifdef LINKSPEED_DEBUG_ENABLED
6572 pr_info("Reporting actual MCS rate %d flags %x\n",
6573 sinfo->txrate.mcs,
6574 sinfo->txrate.flags );
6575#endif //LINKSPEED_DEBUG_ENABLED
6576 }
6577 }
6578 sinfo->filled |= STATION_INFO_TX_BITRATE;
6579
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -07006580 sinfo->tx_packets =
6581 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[0] +
6582 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[1] +
6583 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[2] +
6584 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[3];
6585
6586 sinfo->tx_retries =
6587 pAdapter->hdd_stats.summary_stat.retry_cnt[0] +
6588 pAdapter->hdd_stats.summary_stat.retry_cnt[1] +
6589 pAdapter->hdd_stats.summary_stat.retry_cnt[2] +
6590 pAdapter->hdd_stats.summary_stat.retry_cnt[3];
6591
6592 sinfo->tx_failed =
6593 pAdapter->hdd_stats.summary_stat.fail_cnt[0] +
6594 pAdapter->hdd_stats.summary_stat.fail_cnt[1] +
6595 pAdapter->hdd_stats.summary_stat.fail_cnt[2] +
6596 pAdapter->hdd_stats.summary_stat.fail_cnt[3];
6597
6598 sinfo->filled |=
6599 STATION_INFO_TX_PACKETS |
6600 STATION_INFO_TX_RETRIES |
6601 STATION_INFO_TX_FAILED;
6602
6603 EXIT();
6604 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07006605}
6606
6607static int wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
6608 struct net_device *dev, bool mode, v_SINT_t timeout)
6609{
6610 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +05306611 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07006612 VOS_STATUS vos_status;
6613
Jeff Johnsone7245742012-09-05 17:12:55 -07006614 ENTER();
6615
Jeff Johnson295189b2012-06-20 16:38:30 -07006616 if (NULL == pAdapter)
6617 {
6618 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL\n", __func__);
6619 return -ENODEV;
6620 }
6621
Gopichand Nakkala20c4c042013-04-19 22:08:55 +05306622 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
6623 if (NULL == pHddCtx)
6624 {
6625 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: HDD context is NULL\n", __func__);
6626 return -ENODEV;
6627 }
6628
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306629 if ( pHddCtx->isLogpInProgress )
6630 {
6631 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6632 "%s:LOGP in Progress. Ignore!!!", __func__);
6633 return -EAGAIN;
6634 }
6635
Gopichand Nakkala20c4c042013-04-19 22:08:55 +05306636 if ((DRIVER_POWER_MODE_AUTO == !mode) &&
6637 (TRUE == pHddCtx->hdd_wlan_suspended) &&
6638 (pHddCtx->cfg_ini->fhostArpOffload) &&
6639 (eConnectionState_Associated ==
6640 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
6641 {
6642 vos_status = hdd_conf_hostarpoffload(pAdapter, TRUE);
6643 if (!VOS_IS_STATUS_SUCCESS(vos_status))
6644 {
6645 hddLog(VOS_TRACE_LEVEL_INFO,
6646 "%s:Failed to enable ARPOFFLOAD Feature %d\n",
6647 __func__, vos_status);
6648 }
6649 }
6650
Jeff Johnson295189b2012-06-20 16:38:30 -07006651 /**The get power cmd from the supplicant gets updated by the nl only
6652 *on successful execution of the function call
6653 *we are oppositely mapped w.r.t mode in the driver
6654 **/
6655 vos_status = wlan_hdd_enter_bmps(pAdapter, !mode);
6656
Jeff Johnsone7245742012-09-05 17:12:55 -07006657 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07006658 if (VOS_STATUS_E_FAILURE == vos_status)
6659 {
6660 return -EINVAL;
6661 }
6662 return 0;
6663}
6664
6665
6666#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
6667static int wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
6668 struct net_device *netdev,
6669 u8 key_index)
6670{
Jeff Johnsone7245742012-09-05 17:12:55 -07006671 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07006672 return 0;
6673}
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306674#endif //LINUX_VERSION_CODE
Jeff Johnson295189b2012-06-20 16:38:30 -07006675
6676#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
6677static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
6678 struct net_device *dev,
6679 struct ieee80211_txq_params *params)
6680{
Jeff Johnsone7245742012-09-05 17:12:55 -07006681 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07006682 return 0;
6683}
6684#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
6685static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
6686 struct ieee80211_txq_params *params)
6687{
Jeff Johnsone7245742012-09-05 17:12:55 -07006688 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07006689 return 0;
6690}
6691#endif //LINUX_VERSION_CODE
6692
6693static int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
6694 struct net_device *dev, u8 *mac)
6695{
6696 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08006697 VOS_STATUS vos_status;
6698 v_U8_t staId;
Jeff Johnson295189b2012-06-20 16:38:30 -07006699
Jeff Johnsone7245742012-09-05 17:12:55 -07006700 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07006701 if ( NULL == pAdapter || NULL == pAdapter->pHddCtx)
6702 {
6703 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Invalid Adapter or HDD Context " ,__func__);
6704 return -EINVAL;
6705 }
6706
6707 if (((hdd_context_t*)pAdapter->pHddCtx)->isLoadUnloadInProgress)
6708 {
6709 hddLog( LOGE,
6710 "%s: Wlan Load/Unload is in progress", __func__);
6711 return -EBUSY;
6712 }
6713
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006714 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
6715 {
6716 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6717 "%s:LOGP in Progress. Ignore!!!", __func__);
6718 return -EAGAIN;
6719 }
6720
Jeff Johnson295189b2012-06-20 16:38:30 -07006721 if ( (WLAN_HDD_SOFTAP == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -07006722 || (WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -07006723 )
6724 {
6725 if( NULL == mac )
6726 {
6727 v_U16_t i;
6728 for(i = 0; i < WLAN_MAX_STA_COUNT; i++)
6729 {
6730 if(pAdapter->aStaInfo[i].isUsed)
6731 {
6732 u8 *macAddr = pAdapter->aStaInfo[i].macAddrSTA.bytes;
6733 hddLog(VOS_TRACE_LEVEL_INFO,
6734 "%s: Delete STA with MAC::"
6735 "%02x:%02x:%02x:%02x:%02x:%02x",
6736 __func__,
6737 macAddr[0], macAddr[1], macAddr[2],
6738 macAddr[3], macAddr[4], macAddr[5]);
6739 hdd_softap_sta_deauth(pAdapter, macAddr);
6740 }
6741 }
6742 }
6743 else
6744 {
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08006745
6746 vos_status = hdd_softap_GetStaId(pAdapter,(v_MACADDR_t *)mac, &staId);
6747 if (!VOS_IS_STATUS_SUCCESS(vos_status))
6748 {
6749 hddLog(VOS_TRACE_LEVEL_INFO,
6750 "%s: Skip this DEL STA as this is not used::"
6751 "%02x:%02x:%02x:%02x:%02x:%02x",
6752 __func__,
6753 mac[0], mac[1], mac[2],
6754 mac[3], mac[4], mac[5]);
6755 return -ENOENT;
6756 }
6757
6758 if( pAdapter->aStaInfo[staId].isDeauthInProgress == TRUE)
6759 {
6760 hddLog(VOS_TRACE_LEVEL_INFO,
6761 "%s: Skip this DEL STA as deauth is in progress::"
6762 "%02x:%02x:%02x:%02x:%02x:%02x",
6763 __func__,
6764 mac[0], mac[1], mac[2],
6765 mac[3], mac[4], mac[5]);
6766 return -ENOENT;
6767 }
6768
6769 pAdapter->aStaInfo[staId].isDeauthInProgress = TRUE;
6770
Jeff Johnson295189b2012-06-20 16:38:30 -07006771 hddLog(VOS_TRACE_LEVEL_INFO,
6772 "%s: Delete STA with MAC::"
6773 "%02x:%02x:%02x:%02x:%02x:%02x",
6774 __func__,
6775 mac[0], mac[1], mac[2],
6776 mac[3], mac[4], mac[5]);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08006777
6778 vos_status = hdd_softap_sta_deauth(pAdapter, mac);
6779 if (!VOS_IS_STATUS_SUCCESS(vos_status))
6780 {
6781 pAdapter->aStaInfo[staId].isDeauthInProgress = FALSE;
6782 hddLog(VOS_TRACE_LEVEL_INFO,
6783 "%s: STA removal failed for ::"
6784 "%02x:%02x:%02x:%02x:%02x:%02x",
6785 __func__,
6786 mac[0], mac[1], mac[2],
6787 mac[3], mac[4], mac[5]);
6788 return -ENOENT;
6789 }
6790
Jeff Johnson295189b2012-06-20 16:38:30 -07006791 }
6792 }
6793
6794 EXIT();
6795
6796 return 0;
6797}
6798
Hoonki Lee11f7dda2013-02-14 16:55:44 -08006799static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
6800 struct net_device *dev, u8 *mac, struct station_parameters *params)
6801{
Gopichand Nakkalab977a972013-02-18 19:15:09 -08006802 int status = -EPERM;
Hoonki Lee11f7dda2013-02-14 16:55:44 -08006803#ifdef FEATURE_WLAN_TDLS
6804 u32 mask, set;
Hoonki Lee11f7dda2013-02-14 16:55:44 -08006805 ENTER();
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006806 mask = params->sta_flags_mask;
6807
6808 set = params->sta_flags_set;
6809
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07006810#ifdef WLAN_FEATURE_TDLS_DEBUG
6811 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6812 "%s: mask 0x%x set 0x%x " MAC_ADDRESS_STR,
6813 __func__, mask, set, MAC_ADDR_ARRAY(mac));
6814#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006815
6816 if (mask & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
6817 if (set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006818 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 0, NULL);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006819 }
6820 }
6821#endif
Gopichand Nakkalab977a972013-02-18 19:15:09 -08006822 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -07006823}
6824
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006825
6826#ifdef FEATURE_WLAN_LFR
6827static int wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
Jeff Johnsond13512a2012-07-17 11:42:19 -07006828 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006829{
6830#define MAX_PMKSAIDS_IN_CACHE 8
6831 static tPmkidCacheInfo PMKIDCache[MAX_PMKSAIDS_IN_CACHE]; // HDD Local cache
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306832 static tANI_U32 i; // HDD Local Cache index
6833 tANI_U32 j=0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006834 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6835 tHalHandle halHandle;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306836 eHalStatus result;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006837 tANI_U8 BSSIDMatched = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306838
Jeff Johnsone7245742012-09-05 17:12:55 -07006839 ENTER();
6840
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306841 // Validate pAdapter
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006842 if ( NULL == pAdapter || NULL == pAdapter->pHddCtx)
6843 {
6844 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Invalid Adapter or HDD Context " ,__func__);
6845 return -EINVAL;
6846 }
6847
6848 if (((hdd_context_t*)pAdapter->pHddCtx)->isLoadUnloadInProgress)
6849 {
6850 hddLog( LOGE,
6851 "%s: Wlan Load/Unload is in progress", __func__);
6852 return -EBUSY;
6853 }
6854
6855 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
6856 {
6857 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6858 "%s:LOGP in Progress. Ignore!!!", __func__);
6859 return -EAGAIN;
6860 }
6861
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306862 // Retrieve halHandle
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006863 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
6864
6865 for (j = 0; j < i; j++)
6866 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306867 if(vos_mem_compare(PMKIDCache[j].BSSID,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006868 pmksa->bssid, WNI_CFG_BSSID_LEN))
6869 {
6870 /* BSSID matched previous entry. Overwrite it. */
6871 BSSIDMatched = 1;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306872 vos_mem_copy(PMKIDCache[j].BSSID,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006873 pmksa->bssid, WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306874 vos_mem_copy(PMKIDCache[j].PMKID,
6875 pmksa->pmkid,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006876 CSR_RSN_PMKID_SIZE);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306877 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Reusing cache entry %d.",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006878 __func__, j );
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006879 dump_bssid(pmksa->bssid);
6880 dump_pmkid(halHandle, pmksa->pmkid);
6881 break;
6882 }
6883 }
6884
Madan Mohan Koyyalamudic4b317d2012-10-18 19:43:08 -07006885 /* Check we compared all entries,if then take the first slot now */
6886 if(j == MAX_PMKSAIDS_IN_CACHE) i=0;
6887
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006888 if (!BSSIDMatched)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306889 {
6890 // Now, we DON'T have a BSSID match, so take a new entry in the cache.
6891 vos_mem_copy(PMKIDCache[i].BSSID,
6892 pmksa->bssid, ETHER_ADDR_LEN);
6893 vos_mem_copy(PMKIDCache[i].PMKID,
6894 pmksa->pmkid,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006895 CSR_RSN_PMKID_SIZE);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306896 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Adding a new cache entry %d.",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006897 __func__, i );
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006898 dump_bssid(pmksa->bssid);
6899 dump_pmkid(halHandle, pmksa->pmkid);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306900 // Increment the HDD Local Cache index
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006901 // The "i=0" doesn't work for the call to sme_RoamSetPMKIDCache() - LFR FIXME
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306902 if (i<=(MAX_PMKSAIDS_IN_CACHE-1)) i++; else i=0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006903 }
6904
6905
6906 // Calling csrRoamSetPMKIDCache to configure the PMKIDs into the cache
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306907 //hddLog(LOG1, FL("%s: Calling csrRoamSetPMKIDCache with %d cache entries."),
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006908 // __func__, i );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306909 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Calling csrRoamSetPMKIDCache with %d cache entries.",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006910 __func__, i );
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006911 // Finally set the PMKSA ID Cache in CSR
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306912 result = sme_RoamSetPMKIDCache(halHandle,pAdapter->sessionId,
6913 PMKIDCache,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006914 i );
6915 return 0;
6916}
6917
6918
6919static int wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
Jeff Johnsond13512a2012-07-17 11:42:19 -07006920 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006921{
Jeff Johnsone7245742012-09-05 17:12:55 -07006922 ENTER();
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006923 // TODO: Implement this later.
6924 return 0;
6925}
6926
6927static int wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
6928{
Jeff Johnsone7245742012-09-05 17:12:55 -07006929 ENTER();
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006930 // TODO: Implement this later.
6931 return 0;
6932}
6933#endif
6934
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07006935#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306936static int wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07006937 struct net_device *dev, struct cfg80211_update_ft_ies_params *ftie)
6938{
6939 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6940 hdd_station_ctx_t *pHddStaCtx;
6941
6942 if (NULL == pAdapter)
6943 {
6944 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL\n", __func__);
6945 return -ENODEV;
6946 }
6947
6948 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6949
6950 // Added for debug on reception of Re-assoc Req.
6951 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
6952 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306953 hddLog(LOGE, FL("Called with Ie of length = %d when not associated\n"),
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07006954 ftie->ie_len);
6955 hddLog(LOGE, FL("Should be Re-assoc Req IEs\n"));
6956 }
6957
6958#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306959 hddLog(LOGE, FL("%s called with Ie of length = %d\n"), __func__,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07006960 ftie->ie_len);
6961#endif
6962
6963 // Pass the received FT IEs to SME
Gopichand Nakkala356fb102013-03-06 12:34:04 +05306964 sme_SetFTIEs( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
6965 (const u8 *)ftie->ie,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07006966 ftie->ie_len);
6967 return 0;
6968}
6969#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006970
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006971#ifdef FEATURE_WLAN_TDLS
6972static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
6973 u8 *peer, u8 action_code, u8 dialog_token,
6974 u16 status_code, const u8 *buf, size_t len)
6975{
6976
6977 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6978 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006979 u8 peerMac[6];
6980 VOS_STATUS status;
Gopichand Nakkala05922802013-03-14 12:23:19 -07006981 int max_sta_failed = 0;
Hoonki Leea34dd892013-02-05 22:56:02 -08006982 int responder;
Hoonki Leed37cbb32013-04-20 00:31:14 -07006983 long rc;
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006984
Hoonki Lee11f7dda2013-02-14 16:55:44 -08006985 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006986 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306987 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006988 "Invalid arguments");
6989 return -EINVAL;
6990 }
6991
Sameer Thalappil75ea31a2013-02-21 19:38:16 -08006992 if (pHddCtx->isLogpInProgress)
6993 {
6994 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6995 "%s:LOGP in Progress. Ignore!!!", __func__);
Gopichand Nakkala05922802013-03-14 12:23:19 -07006996 wlan_hdd_tdls_set_link_status(pAdapter, peer, eTDLS_LINK_IDLE);
Sameer Thalappil75ea31a2013-02-21 19:38:16 -08006997 return -EBUSY;
6998 }
6999
Hoonki Lee27511902013-03-14 18:19:06 -07007000 if (eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode)
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007001 {
Hoonki Lee27511902013-03-14 18:19:06 -07007002 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
7003 "%s: TDLS mode is disabled OR not enabled in FW."
7004 MAC_ADDRESS_STR " action %d declined.",
7005 __func__, MAC_ADDR_ARRAY(peer), action_code);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007006 return -ENOTSUPP;
7007 }
Lee Hoonkic1262f22013-01-24 21:59:00 -08007008
Hoonki Lee27511902013-03-14 18:19:06 -07007009 /* other than teardown frame, other mgmt frames are not sent if disabled */
7010 if (SIR_MAC_TDLS_TEARDOWN != action_code)
7011 {
7012 /* if tdls_mode is disabled to respond to peer's request */
7013 if (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode)
7014 {
7015 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
7016 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07007017 " TDLS mode is disabled. action %d declined.",
7018 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee27511902013-03-14 18:19:06 -07007019
7020 return -ENOTSUPP;
7021 }
7022 }
7023
Gopichand Nakkalab977a972013-02-18 19:15:09 -08007024 if (WLAN_IS_TDLS_SETUP_ACTION(action_code))
7025 {
Hoonki Leefb8df672013-04-10 18:20:34 -07007026 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, peer, TRUE, TRUE))
Gopichand Nakkalab977a972013-02-18 19:15:09 -08007027 {
7028 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007029 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07007030 " TDLS setup is ongoing. action %d declined.",
7031 __func__, MAC_ADDR_ARRAY(peer), action_code);
7032 return -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -08007033 }
7034 }
7035
Hoonki Lee11f7dda2013-02-14 16:55:44 -08007036 if (SIR_MAC_TDLS_SETUP_REQ == action_code ||
7037 SIR_MAC_TDLS_SETUP_RSP == action_code )
Lee Hoonkic1262f22013-01-24 21:59:00 -08007038 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -08007039 if (HDD_MAX_NUM_TDLS_STA <= wlan_hdd_tdlsConnectedPeers(pAdapter))
Lee Hoonkic1262f22013-01-24 21:59:00 -08007040 {
7041 /* supplicant still sends tdls_mgmt(SETUP_REQ) even after
7042 we return error code at 'add_station()'. Hence we have this
7043 check again in addtion to add_station().
7044 Anyway, there is no hard to double-check. */
Hoonki Lee11f7dda2013-02-14 16:55:44 -08007045 if (SIR_MAC_TDLS_SETUP_REQ == action_code)
Lee Hoonkic1262f22013-01-24 21:59:00 -08007046 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007047 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7048 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07007049 " TDLS Max peer already connected. action %d declined.",
7050 __func__, MAC_ADDR_ARRAY(peer), action_code);
Gopichand Nakkala05922802013-03-14 12:23:19 -07007051 goto error;
Lee Hoonkic1262f22013-01-24 21:59:00 -08007052 }
7053 else
7054 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -08007055 /* maximum reached. tweak to send error code to peer and return
7056 error code to supplicant */
Lee Hoonkic1262f22013-01-24 21:59:00 -08007057 status_code = eSIR_MAC_UNSPEC_FAILURE_STATUS;
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007058 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7059 "%s: " MAC_ADDRESS_STR
7060 " TDLS Max peer already connected send response status %d",
7061 __func__, MAC_ADDR_ARRAY(peer), status_code);
Gopichand Nakkala05922802013-03-14 12:23:19 -07007062 max_sta_failed = -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -08007063 /* fall through to send setup resp with failure status
7064 code */
Lee Hoonkic1262f22013-01-24 21:59:00 -08007065 }
7066 }
Hoonki Lee11f7dda2013-02-14 16:55:44 -08007067 else
7068 {
7069 hddTdlsPeer_t *pTdlsPeer;
Gopichand Nakkala4327a152013-03-04 23:22:42 -08007070 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007071 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Hoonki Lee11f7dda2013-02-14 16:55:44 -08007072 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007073 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07007074 "%s:" MAC_ADDRESS_STR " already connected. action %d declined.",
7075 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee11f7dda2013-02-14 16:55:44 -08007076 return -EPERM;
7077 }
7078 }
Lee Hoonkic1262f22013-01-24 21:59:00 -08007079 }
Hoonki Lee11f7dda2013-02-14 16:55:44 -08007080 vos_mem_copy(peerMac, peer, 6);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007081
Hoonki Lee1090c6a2013-01-16 17:40:54 -08007082#ifdef WLAN_FEATURE_TDLS_DEBUG
7083 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007084 "%s: " MAC_ADDRESS_STR " action %d, dialog_token %d status %d, len = %d",
7085 "tdls_mgmt", MAC_ADDR_ARRAY(peer),
7086 action_code, dialog_token, status_code, len);
Hoonki Lee1090c6a2013-01-16 17:40:54 -08007087#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007088
Hoonki Leea34dd892013-02-05 22:56:02 -08007089 /*Except teardown responder will not be used so just make 0*/
7090 responder = 0;
Hoonki Lee11f7dda2013-02-14 16:55:44 -08007091 if (SIR_MAC_TDLS_TEARDOWN == action_code)
Hoonki Leea34dd892013-02-05 22:56:02 -08007092 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -07007093
7094 hddTdlsPeer_t *pTdlsPeer;
7095 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peerMac);
7096
7097 if(pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
7098 responder = pTdlsPeer->is_responder;
7099 else
Hoonki Leea34dd892013-02-05 22:56:02 -08007100 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -07007101 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7102 "%s: " MAC_ADDRESS_STR " peer doesn't exist or not connected %d dialog_token %d status %d, len = %d",
7103 __func__, MAC_ADDR_ARRAY(peer), (NULL == pTdlsPeer) ? -1 : pTdlsPeer->link_status,
7104 dialog_token, status_code, len);
7105 return -EPERM;
Hoonki Leea34dd892013-02-05 22:56:02 -08007106 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007107 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007108
Hoonki Lee14621352013-04-16 17:51:19 -07007109 if ((SIR_MAC_TDLS_SETUP_RSP == action_code) ||
7110 (SIR_MAC_TDLS_DIS_RSP == action_code))
7111 {
7112 if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter)))
7113 {
7114 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
7115 "%s: Sending Disc/Setup Rsp Frame.Disable BMPS", __func__);
7116 hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
7117 }
7118 wlan_hdd_tdls_set_cap(pAdapter, peerMac, eTDLS_CAP_SUPPORTED);
7119 }
7120
Gopichand Nakkalab977a972013-02-18 19:15:09 -08007121 INIT_COMPLETION(pAdapter->tdls_mgmt_comp);
7122
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007123 status = sme_SendTdlsMgmtFrame(WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
Hoonki Leea34dd892013-02-05 22:56:02 -08007124 peerMac, action_code, dialog_token, status_code, (tANI_U8 *)buf, len, responder);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007125
Gopichand Nakkalab977a972013-02-18 19:15:09 -08007126 if (VOS_STATUS_SUCCESS != status)
7127 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007128 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7129 "%s: sme_SendTdlsMgmtFrame failed!", __func__);
Hoonki Lee14621352013-04-16 17:51:19 -07007130 wlan_hdd_tdls_check_bmps(pAdapter);
7131 goto error;
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007132 }
7133
Hoonki Leed37cbb32013-04-20 00:31:14 -07007134 rc = wait_for_completion_interruptible_timeout(&pAdapter->tdls_mgmt_comp,
7135 msecs_to_jiffies(WAIT_TIME_TDLS_MGMT));
7136
7137 if ((rc <= 0) || (TRUE != pAdapter->mgmtTxCompletionStatus))
Gopichand Nakkalab977a972013-02-18 19:15:09 -08007138 {
Hoonki Leed37cbb32013-04-20 00:31:14 -07007139 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7140 "%s: Mgmt Tx Completion failed status %ld TxCompletion %lu",
7141 __func__, rc, pAdapter->mgmtTxCompletionStatus);
7142 wlan_hdd_tdls_check_bmps(pAdapter);
7143 goto error;
Gopichand Nakkalab977a972013-02-18 19:15:09 -08007144 }
7145
Gopichand Nakkala05922802013-03-14 12:23:19 -07007146 if (max_sta_failed)
Hoonki Lee14621352013-04-16 17:51:19 -07007147 {
7148 wlan_hdd_tdls_check_bmps(pAdapter);
Gopichand Nakkala05922802013-03-14 12:23:19 -07007149 return max_sta_failed;
Hoonki Lee14621352013-04-16 17:51:19 -07007150 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -08007151
Hoonki Leea34dd892013-02-05 22:56:02 -08007152 if (SIR_MAC_TDLS_SETUP_RSP == action_code)
7153 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -08007154 wlan_hdd_tdls_set_responder(pAdapter, peerMac, TRUE);
Hoonki Leea34dd892013-02-05 22:56:02 -08007155 }
7156 else if (SIR_MAC_TDLS_SETUP_CNF == action_code)
7157 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -08007158 wlan_hdd_tdls_set_responder(pAdapter, peerMac, FALSE);
Hoonki Leea34dd892013-02-05 22:56:02 -08007159 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007160
7161 return 0;
Gopichand Nakkala05922802013-03-14 12:23:19 -07007162error:
7163 /* max_sta_failed ; we didn't set to CONNECTING for this case,
7164 because we already know that this transaction will be failed,
7165 but we weren't sure if supplicant call DISABLE_LINK or not. So,
7166 to be safe, do not change the state mahine.
7167 */
7168 if(max_sta_failed == 0 &&
7169 (WLAN_IS_TDLS_SETUP_ACTION(action_code)))
7170 wlan_hdd_tdls_set_link_status(pAdapter, peerMac, eTDLS_LINK_IDLE);
7171 return -EPERM;
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007172}
7173
7174static int wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
7175 u8 *peer, enum nl80211_tdls_operation oper)
7176{
7177 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
7178 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Hoonki Lee1090c6a2013-01-16 17:40:54 -08007179#ifdef WLAN_FEATURE_TDLS_DEBUG
7180 const char *tdls_oper_str[]= {
7181 "NL80211_TDLS_DISCOVERY_REQ",
7182 "NL80211_TDLS_SETUP",
7183 "NL80211_TDLS_TEARDOWN",
7184 "NL80211_TDLS_ENABLE_LINK",
7185 "NL80211_TDLS_DISABLE_LINK",
7186 "NL80211_TDLS_UNKONW_OPER"};
7187#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007188
Chilam Ngc4244af2013-04-01 15:37:32 -07007189 if ( NULL == pHddCtx || NULL == pHddCtx->cfg_ini || NULL == peer )
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007190 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -08007191 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chilam Ngc4244af2013-04-01 15:37:32 -07007192 "%s: Invalid arguments", __func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007193 return -EINVAL;
7194 }
Hoonki Lee1090c6a2013-01-16 17:40:54 -08007195
Sameer Thalappil75ea31a2013-02-21 19:38:16 -08007196 if (pHddCtx->isLogpInProgress)
7197 {
7198 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7199 "%s:LOGP in Progress. Ignore!!!", __func__);
7200 return -EBUSY;
7201 }
7202
Hoonki Lee1090c6a2013-01-16 17:40:54 -08007203#ifdef WLAN_FEATURE_TDLS_DEBUG
7204 if((int)oper > 4)
7205 oper = 5;
7206
7207 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007208 "%s: " MAC_ADDRESS_STR " %d (%s) ", "tdls_oper",
7209 MAC_ADDR_ARRAY(peer), (int)oper,
7210 tdls_oper_str[(int)oper]);
Hoonki Lee1090c6a2013-01-16 17:40:54 -08007211#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007212
7213 if( FALSE == pHddCtx->cfg_ini->fEnableTDLSSupport ||
Hoonki Lee1090c6a2013-01-16 17:40:54 -08007214 FALSE == sme_IsFeatureSupportedByFW(TDLS))
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007215 {
Hoonki Lee1090c6a2013-01-16 17:40:54 -08007216 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chilam Ngc4244af2013-04-01 15:37:32 -07007217 "TDLS Disabled in INI OR not enabled in FW. "
7218 "Cannot process TDLS commands");
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007219 return -ENOTSUPP;
7220 }
7221
7222 switch (oper) {
7223 case NL80211_TDLS_ENABLE_LINK:
7224 {
Hoonki Lee387663d2013-02-05 18:08:43 -08007225 hddTdlsPeer_t *pTdlsPeer;
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007226 VOS_STATUS status;
7227
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007228 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007229
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007230 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
7231 "%s: TDLS_LINK_ENABLE " MAC_ADDRESS_STR,
7232 __func__, MAC_ADDR_ARRAY(peer));
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007233
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007234 if ( NULL == pTdlsPeer ) {
7235 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wlan_hdd_tdls_find_peer "
7236 MAC_ADDRESS_STR " failed",
7237 __func__, MAC_ADDR_ARRAY(peer));
7238 return -EINVAL;
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007239 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007240
Gopichand Nakkala2f4a2822013-04-17 11:22:01 -07007241 if (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
7242 {
7243 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Staion Index %u "
7244 MAC_ADDRESS_STR " failed",
7245 __func__, pTdlsPeer->staId, MAC_ADDR_ARRAY(peer));
7246 return -EINVAL;
7247 }
7248
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007249 if (eTDLS_LINK_CONNECTING == pTdlsPeer->link_status)
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007250 {
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -07007251 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer, eTDLS_LINK_CONNECTED);
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007252 /* start TDLS client registration with TL */
7253 status = hdd_roamRegisterTDLSSTA( pAdapter, peer, pTdlsPeer->staId, pTdlsPeer->signature);
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -07007254 if (VOS_STATUS_SUCCESS == status)
7255 {
Hoonki Lee14621352013-04-16 17:51:19 -07007256 if (pTdlsPeer->is_responder == 0)
7257 {
7258 v_U8_t staId = (v_U8_t)pTdlsPeer->staId;
7259
7260 wlan_hdd_tdls_timer_restart(pAdapter,
7261 &pTdlsPeer->initiatorWaitTimeoutTimer,
7262 WAIT_TIME_TDLS_INITIATOR);
7263 /* suspend initiator TX until it receives direct packet from the
7264 reponder or WAIT_TIME_TDLS_INITIATOR timer expires */
7265 WLANTL_SuspendDataTx( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
7266 &staId, NULL);
7267 }
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -07007268 wlan_hdd_tdls_increment_peer_count(pAdapter);
7269 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007270 wlan_hdd_tdls_check_bmps(pAdapter);
7271 }
7272
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007273 }
7274 break;
7275 case NL80211_TDLS_DISABLE_LINK:
Lee Hoonkic1262f22013-01-24 21:59:00 -08007276 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -08007277 hddTdlsPeer_t *curr_peer = wlan_hdd_tdls_find_peer(pAdapter, peer);
Gopichand Nakkalab977a972013-02-18 19:15:09 -08007278
Gopichand Nakkala2f4a2822013-04-17 11:22:01 -07007279 if((NULL != curr_peer) && TDLS_STA_INDEX_VALID(curr_peer->staId))
Lee Hoonkic1262f22013-01-24 21:59:00 -08007280 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007281 long status;
7282
7283 INIT_COMPLETION(pAdapter->tdls_del_station_comp);
7284
Lee Hoonkic1262f22013-01-24 21:59:00 -08007285 sme_DeleteTdlsPeerSta( WLAN_HDD_GET_HAL_CTX(pAdapter),
7286 pAdapter->sessionId, peer );
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007287
7288 status = wait_for_completion_interruptible_timeout(&pAdapter->tdls_del_station_comp,
7289 msecs_to_jiffies(WAIT_TIME_TDLS_DEL_STA));
7290 if (status <= 0)
7291 {
7292 wlan_hdd_tdls_set_peer_link_status(curr_peer, eTDLS_LINK_IDLE);
7293 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7294 "%s: Del station failed status %ld",
7295 __func__, status);
7296 return -EPERM;
7297 }
Gopichand Nakkala8b00c632013-03-08 19:47:52 -08007298 wlan_hdd_tdls_set_peer_link_status(curr_peer, eTDLS_LINK_IDLE);
Lee Hoonkic1262f22013-01-24 21:59:00 -08007299 }
7300 else
7301 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007302 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7303 "%s: TDLS Peer Station doesn't exist.", __func__);
Lee Hoonkic1262f22013-01-24 21:59:00 -08007304 }
Lee Hoonkic1262f22013-01-24 21:59:00 -08007305 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007306 break;
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007307 case NL80211_TDLS_TEARDOWN:
7308 case NL80211_TDLS_SETUP:
7309 case NL80211_TDLS_DISCOVERY_REQ:
7310 /* We don't support in-driver setup/teardown/discovery */
7311 return -ENOTSUPP;
7312 default:
7313 return -ENOTSUPP;
7314 }
7315 return 0;
7316}
Chilam NG571c65a2013-01-19 12:27:36 +05307317
7318int wlan_hdd_cfg80211_send_tdls_discover_req(struct wiphy *wiphy,
7319 struct net_device *dev, u8 *peer)
7320{
7321 hddLog(VOS_TRACE_LEVEL_INFO, "tdls send discover req: %x %x %x %x %x %x",
7322 peer[0], peer[1], peer[2], peer[3], peer[4], peer[5]);
7323
7324 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
7325 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, NULL, 0);
7326}
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007327#endif
7328
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05307329#ifdef WLAN_FEATURE_GTK_OFFLOAD
7330/*
7331 * FUNCTION: wlan_hdd_cfg80211_update_replayCounterCallback
7332 * Callback rountine called upon receiving response for
7333 * get offload info
7334 */
7335void wlan_hdd_cfg80211_update_replayCounterCallback(void *callbackContext,
7336 tpSirGtkOffloadGetInfoRspParams pGtkOffloadGetInfoRsp)
7337{
7338
7339 hdd_adapter_t *pAdapter = (hdd_adapter_t *)callbackContext;
7340
7341 ENTER();
7342
7343 if (NULL == pAdapter)
7344 {
7345 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
7346 "%s: HDD adapter is Null", __func__);
7347 return ;
7348 }
7349
7350 if (NULL == pGtkOffloadGetInfoRsp)
7351 {
7352 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7353 "%s: pGtkOffloadGetInfoRsp is Null", __func__);
7354 return ;
7355 }
7356
7357 if (VOS_STATUS_SUCCESS != pGtkOffloadGetInfoRsp->ulStatus)
7358 {
7359 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7360 "%s: wlan Failed to get replay counter value",
7361 __func__);
7362 return ;
7363 }
7364
7365 /* Update replay counter to NL */
7366 cfg80211_gtk_rekey_notify(pAdapter->dev, pGtkOffloadGetInfoRsp->bssId,
7367 (tANI_U8 *)&pGtkOffloadGetInfoRsp->ullKeyReplayCounter, GFP_KERNEL);
7368}
7369
7370/*
7371 * FUNCTION: wlan_hdd_cfg80211_set_rekey_data
7372 * This function is used to offload GTK rekeying job to the firmware.
7373 */
7374int wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
7375 struct cfg80211_gtk_rekey_data *data)
7376{
7377 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
7378 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
7379 hdd_station_ctx_t *pHddStaCtx;
7380 tHalHandle hHal;
7381 tpSirGtkOffloadParams pGtkOffloadReqParams;
7382 eHalStatus status = eHAL_STATUS_FAILURE;
7383
7384 ENTER();
7385
7386 if (NULL == pAdapter)
7387 {
7388 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
7389 "%s: HDD adapter is Null", __func__);
7390 return -ENODEV;
7391 }
7392
7393 if (NULL == pHddCtx)
7394 {
7395 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7396 "%s: HDD context is Null!!!", __func__);
7397 return -ENODEV;
7398 }
7399
7400 if (pHddCtx->isLogpInProgress)
7401 {
7402 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
7403 "%s: LOGP in Progress. Ignore!!!", __func__);
7404 return -EAGAIN;
7405 }
7406
7407 if (pHddCtx->isLoadUnloadInProgress)
7408 {
7409 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
7410 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
7411 return -EAGAIN;
7412 }
7413
7414 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7415 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
7416 if (NULL == hHal)
7417 {
7418 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7419 "%s: HAL context is Null!!!", __func__);
7420 return -EAGAIN;
7421 }
7422
7423 pGtkOffloadReqParams =
7424 &pHddStaCtx->gtkOffloadRequestParams.gtkOffloadReqParams;
7425
7426 pGtkOffloadReqParams->ulFlags = GTK_OFFLOAD_ENABLE;
7427 memcpy(pGtkOffloadReqParams->aKCK, data->kck, NL80211_KCK_LEN);
7428 memcpy(pGtkOffloadReqParams->aKEK, data->kek, NL80211_KEK_LEN);
7429 memcpy(pGtkOffloadReqParams->bssId, &pHddStaCtx->conn_info.bssId,
7430 WNI_CFG_BSSID_LEN);
7431 memcpy(&pGtkOffloadReqParams->ullKeyReplayCounter, &data->replay_ctr,
7432 sizeof (tANI_U64));
7433
7434 if (TRUE == pHddCtx->hdd_wlan_suspended)
7435 {
7436 /* if wlan is suspended, enable GTK offload directly from here */
7437 status = sme_SetGTKOffload(hHal, pGtkOffloadReqParams,
7438 pAdapter->sessionId);
7439
7440 if (eHAL_STATUS_SUCCESS != status)
7441 {
7442 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7443 "%s: sme_SetGTKOffload failed, returned %d",
7444 __func__, status);
7445 return status;
7446 }
7447 pHddStaCtx->gtkOffloadRequestParams.requested = FALSE;
7448 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
7449 "%s: sme_SetGTKOffload successfull", __func__);
7450 }
7451 else
7452 {
7453 pHddStaCtx->gtkOffloadRequestParams.requested = TRUE;
7454 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
7455 "%s: wlan not suspended GTKOffload request is stored",
7456 __func__);
7457 return eHAL_STATUS_SUCCESS;
7458 }
7459 return status;
7460}
7461#endif /*WLAN_FEATURE_GTK_OFFLOAD*/
7462
Jeff Johnson295189b2012-06-20 16:38:30 -07007463/* cfg80211_ops */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307464static struct cfg80211_ops wlan_hdd_cfg80211_ops =
Jeff Johnson295189b2012-06-20 16:38:30 -07007465{
7466 .add_virtual_intf = wlan_hdd_add_virtual_intf,
7467 .del_virtual_intf = wlan_hdd_del_virtual_intf,
7468 .change_virtual_intf = wlan_hdd_cfg80211_change_iface,
7469 .change_station = wlan_hdd_change_station,
7470#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
7471 .add_beacon = wlan_hdd_cfg80211_add_beacon,
7472 .del_beacon = wlan_hdd_cfg80211_del_beacon,
7473 .set_beacon = wlan_hdd_cfg80211_set_beacon,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007474#else
7475 .start_ap = wlan_hdd_cfg80211_start_ap,
7476 .change_beacon = wlan_hdd_cfg80211_change_beacon,
7477 .stop_ap = wlan_hdd_cfg80211_stop_ap,
Jeff Johnson295189b2012-06-20 16:38:30 -07007478#endif
7479 .change_bss = wlan_hdd_cfg80211_change_bss,
7480 .add_key = wlan_hdd_cfg80211_add_key,
7481 .get_key = wlan_hdd_cfg80211_get_key,
7482 .del_key = wlan_hdd_cfg80211_del_key,
7483 .set_default_key = wlan_hdd_cfg80211_set_default_key,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -08007484#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07007485 .set_channel = wlan_hdd_cfg80211_set_channel,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -08007486#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007487 .scan = wlan_hdd_cfg80211_scan,
7488 .connect = wlan_hdd_cfg80211_connect,
7489 .disconnect = wlan_hdd_cfg80211_disconnect,
7490 .join_ibss = wlan_hdd_cfg80211_join_ibss,
7491 .leave_ibss = wlan_hdd_cfg80211_leave_ibss,
7492 .set_wiphy_params = wlan_hdd_cfg80211_set_wiphy_params,
7493 .set_tx_power = wlan_hdd_cfg80211_set_txpower,
7494 .get_tx_power = wlan_hdd_cfg80211_get_txpower,
Jeff Johnson295189b2012-06-20 16:38:30 -07007495 .remain_on_channel = wlan_hdd_cfg80211_remain_on_channel,
7496 .cancel_remain_on_channel = wlan_hdd_cfg80211_cancel_remain_on_channel,
7497 .mgmt_tx = wlan_hdd_action,
7498#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
7499 .mgmt_tx_cancel_wait = wlan_hdd_cfg80211_mgmt_tx_cancel_wait,
7500 .set_default_mgmt_key = wlan_hdd_set_default_mgmt_key,
7501 .set_txq_params = wlan_hdd_set_txq_params,
7502#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007503 .get_station = wlan_hdd_cfg80211_get_station,
7504 .set_power_mgmt = wlan_hdd_cfg80211_set_power_mgmt,
7505 .del_station = wlan_hdd_cfg80211_del_station,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007506 .add_station = wlan_hdd_cfg80211_add_station,
7507#ifdef FEATURE_WLAN_LFR
7508 .set_pmksa = wlan_hdd_cfg80211_set_pmksa,
7509 .del_pmksa = wlan_hdd_cfg80211_del_pmksa,
7510 .flush_pmksa = wlan_hdd_cfg80211_flush_pmksa,
7511#endif
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07007512#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
7513 .update_ft_ies = wlan_hdd_cfg80211_update_ft_ies,
7514#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007515#ifdef FEATURE_WLAN_TDLS
7516 .tdls_mgmt = wlan_hdd_cfg80211_tdls_mgmt,
7517 .tdls_oper = wlan_hdd_cfg80211_tdls_oper,
7518#endif
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05307519#ifdef WLAN_FEATURE_GTK_OFFLOAD
7520 .set_rekey_data = wlan_hdd_cfg80211_set_rekey_data,
7521#endif /* WLAN_FEATURE_GTK_OFFLOAD */
Jeff Johnson295189b2012-06-20 16:38:30 -07007522};
7523