blob: 2e2a6d55d00659cf9d143e05dbb0c638d20abeb6 [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
743#ifdef WLAN_FEATURE_11W
744 /* SA Query Response Action Frame */
745 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
746 (v_U8_t*)SA_QUERY_FRAME_RSP,
747 SA_QUERY_FRAME_RSP_SIZE );
748#endif /* WLAN_FEATURE_11W */
Jeff Johnson295189b2012-06-20 16:38:30 -0700749}
750
751void wlan_hdd_cfg80211_pre_voss_stop(hdd_adapter_t* pAdapter)
752{
Jeff Johnson295189b2012-06-20 16:38:30 -0700753 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
754 /* Register for all P2P action, public action etc frames */
755 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
756
Jeff Johnsone7245742012-09-05 17:12:55 -0700757 ENTER();
758
Jeff Johnson295189b2012-06-20 16:38:30 -0700759 /* Right now we are registering these frame when driver is getting
760 initialized. Once we will move to 2.6.37 kernel, in which we have
761 frame register ops, we will move this code as a part of that */
762 /* GAS Initial Request */
763
764 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
765 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
766
767 /* GAS Initial Response */
768 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
769 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530770
Jeff Johnson295189b2012-06-20 16:38:30 -0700771 /* GAS Comeback Request */
772 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
773 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
774
775 /* GAS Comeback Response */
776 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
777 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
778
779 /* P2P Public Action */
780 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530781 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -0700782 P2P_PUBLIC_ACTION_FRAME_SIZE );
783
784 /* P2P Action */
785 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
786 (v_U8_t*)P2P_ACTION_FRAME,
787 P2P_ACTION_FRAME_SIZE );
Chet Lanctot186b5732013-03-18 10:26:30 -0700788
789#ifdef WLAN_FEATURE_11W
790 /* SA Query Response Action Frame */
791 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
792 (v_U8_t*)SA_QUERY_FRAME_RSP,
793 SA_QUERY_FRAME_RSP_SIZE );
794#endif /* WLAN_FEATURE_11W */
Jeff Johnson295189b2012-06-20 16:38:30 -0700795}
796
797#ifdef FEATURE_WLAN_WAPI
798void wlan_hdd_cfg80211_set_key_wapi(hdd_adapter_t* pAdapter, u8 key_index,
799 const u8 *mac_addr, u8 *key , int key_Len)
800{
801 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
802 tCsrRoamSetKey setKey;
803 v_BOOL_t isConnected = TRUE;
804 int status = 0;
805 v_U32_t roamId= 0xFF;
806 tANI_U8 *pKeyPtr = NULL;
807 int n = 0;
808
809 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",
810 __func__,pAdapter->device_mode);
811
Gopichand Nakkalae7480202013-02-11 15:24:22 +0530812 vos_mem_zero(&setKey, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -0700813 setKey.keyId = key_index; // Store Key ID
814 setKey.encType = eCSR_ENCRYPT_TYPE_WPI; // SET WAPI Encryption
815 setKey.keyDirection = eSIR_TX_RX; // Key Directionn both TX and RX
816 setKey.paeRole = 0 ; // the PAE role
817 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
818 {
819 vos_set_macaddr_broadcast( (v_MACADDR_t *)setKey.peerMac );
820 }
821 else
822 {
823 isConnected = hdd_connIsConnected(pHddStaCtx);
824 vos_mem_copy(setKey.peerMac,&pHddStaCtx->conn_info.bssId,WNI_CFG_BSSID_LEN);
825 }
826 setKey.keyLength = key_Len;
827 pKeyPtr = setKey.Key;
828 memcpy( pKeyPtr, key, key_Len);
829
830 hddLog(VOS_TRACE_LEVEL_INFO,"\n%s: WAPI KEY LENGTH:0x%04x",
831 __func__, key_Len);
832 for (n = 0 ; n < key_Len; n++)
833 hddLog(VOS_TRACE_LEVEL_INFO, "%s WAPI KEY Data[%d]:%02x ",
834 __func__,n,setKey.Key[n]);
835
836 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
837 if ( isConnected )
838 {
839 status= sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
840 pAdapter->sessionId, &setKey, &roamId );
841 }
842 if ( status != 0 )
843 {
844 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
845 "[%4d] sme_RoamSetKey returned ERROR status= %d",
846 __LINE__, status );
847 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
848 }
849}
850#endif /* FEATURE_WLAN_WAPI*/
851
852#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530853int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -0700854 beacon_data_t **ppBeacon,
855 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700856#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530857int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700858 beacon_data_t **ppBeacon,
859 struct cfg80211_beacon_data *params,
860 int dtim_period)
861#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530862{
Jeff Johnson295189b2012-06-20 16:38:30 -0700863 int size;
864 beacon_data_t *beacon = NULL;
865 beacon_data_t *old = NULL;
866 int head_len,tail_len;
867
Jeff Johnsone7245742012-09-05 17:12:55 -0700868 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -0700869 if (params->head && !params->head_len)
870 return -EINVAL;
871
872 old = pAdapter->sessionCtx.ap.beacon;
873
874 if (!params->head && !old)
875 return -EINVAL;
876
877 if (params->tail && !params->tail_len)
878 return -EINVAL;
879
880#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,38))
881 /* Kernel 3.0 is not updating dtim_period for set beacon */
882 if (!params->dtim_period)
883 return -EINVAL;
884#endif
885
886 if(params->head)
887 head_len = params->head_len;
888 else
889 head_len = old->head_len;
890
891 if(params->tail || !old)
892 tail_len = params->tail_len;
893 else
894 tail_len = old->tail_len;
895
896 size = sizeof(beacon_data_t) + head_len + tail_len;
897
898 beacon = kzalloc(size, GFP_KERNEL);
899
900 if( beacon == NULL )
901 return -ENOMEM;
902
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700903#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -0700904 if(params->dtim_period || !old )
905 beacon->dtim_period = params->dtim_period;
906 else
907 beacon->dtim_period = old->dtim_period;
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700908#else
909 if(dtim_period || !old )
910 beacon->dtim_period = dtim_period;
911 else
912 beacon->dtim_period = old->dtim_period;
913#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530914
Jeff Johnson295189b2012-06-20 16:38:30 -0700915 beacon->head = ((u8 *) beacon) + sizeof(beacon_data_t);
916 beacon->tail = beacon->head + head_len;
917 beacon->head_len = head_len;
918 beacon->tail_len = tail_len;
919
920 if(params->head) {
921 memcpy (beacon->head,params->head,beacon->head_len);
922 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530923 else {
Jeff Johnson295189b2012-06-20 16:38:30 -0700924 if(old)
925 memcpy (beacon->head,old->head,beacon->head_len);
926 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530927
Jeff Johnson295189b2012-06-20 16:38:30 -0700928 if(params->tail) {
929 memcpy (beacon->tail,params->tail,beacon->tail_len);
930 }
931 else {
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530932 if(old)
Jeff Johnson295189b2012-06-20 16:38:30 -0700933 memcpy (beacon->tail,old->tail,beacon->tail_len);
934 }
935
936 *ppBeacon = beacon;
937
938 kfree(old);
939
940 return 0;
941
942}
Jeff Johnson295189b2012-06-20 16:38:30 -0700943
944v_U8_t* wlan_hdd_cfg80211_get_ie_ptr(v_U8_t *pIes, int length, v_U8_t eid)
945{
946 int left = length;
947 v_U8_t *ptr = pIes;
948 v_U8_t elem_id,elem_len;
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530949
Jeff Johnson295189b2012-06-20 16:38:30 -0700950 while(left >= 2)
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530951 {
Jeff Johnson295189b2012-06-20 16:38:30 -0700952 elem_id = ptr[0];
953 elem_len = ptr[1];
954 left -= 2;
955 if(elem_len > left)
956 {
957 hddLog(VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -0700958 FL("****Invalid IEs eid = %d elem_len=%d left=%d*****"),
Jeff Johnson295189b2012-06-20 16:38:30 -0700959 eid,elem_len,left);
960 return NULL;
961 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530962 if (elem_id == eid)
Jeff Johnson295189b2012-06-20 16:38:30 -0700963 {
964 return ptr;
965 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530966
Jeff Johnson295189b2012-06-20 16:38:30 -0700967 left -= elem_len;
968 ptr += (elem_len + 2);
969 }
970 return NULL;
971}
972
Jeff Johnson295189b2012-06-20 16:38:30 -0700973/* Check if rate is 11g rate or not */
974static int wlan_hdd_rate_is_11g(u8 rate)
975{
976 u8 gRateArray[8] = {12, 18, 24, 36, 48, 72, 96, 104}; /* actual rate * 2 */
977 u8 i;
978 for (i = 0; i < 8; i++)
979 {
980 if(rate == gRateArray[i])
981 return TRUE;
982 }
983 return FALSE;
984}
985
986/* Check for 11g rate and set proper 11g only mode */
987static void wlan_hdd_check_11gmode(u8 *pIe, u8* require_ht,
988 u8* pCheckRatesfor11g, eSapPhyMode* pSapHw_mode)
989{
990 u8 i, num_rates = pIe[0];
991
992 pIe += 1;
993 for ( i = 0; i < num_rates; i++)
994 {
995 if( *pCheckRatesfor11g && (TRUE == wlan_hdd_rate_is_11g(pIe[i] & RATE_MASK)))
996 {
997 /* If rate set have 11g rate than change the mode to 11G */
998 *pSapHw_mode = eSAP_DOT11_MODE_11g;
999 if (pIe[i] & BASIC_RATE_MASK)
1000 {
1001 /* If we have 11g rate as basic rate, it means mode
1002 is 11g only mode.
1003 */
1004 *pSapHw_mode = eSAP_DOT11_MODE_11g_ONLY;
1005 *pCheckRatesfor11g = FALSE;
1006 }
1007 }
1008 else if((BASIC_RATE_MASK | WLAN_BSS_MEMBERSHIP_SELECTOR_HT_PHY) == pIe[i])
1009 {
1010 *require_ht = TRUE;
1011 }
1012 }
1013 return;
1014}
1015
1016static void wlan_hdd_set_sapHwmode(hdd_adapter_t *pHostapdAdapter)
1017{
1018 tsap_Config_t *pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
1019 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
1020 struct ieee80211_mgmt *pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
1021 u8 checkRatesfor11g = TRUE;
1022 u8 require_ht = FALSE;
1023 u8 *pIe=NULL;
1024
1025 pConfig->SapHw_mode= eSAP_DOT11_MODE_11b;
1026
1027 pIe = wlan_hdd_cfg80211_get_ie_ptr(&pMgmt_frame->u.beacon.variable[0],
1028 pBeacon->head_len, WLAN_EID_SUPP_RATES);
1029 if (pIe != NULL)
1030 {
1031 pIe += 1;
1032 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
1033 &pConfig->SapHw_mode);
1034 }
1035
1036 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
1037 WLAN_EID_EXT_SUPP_RATES);
1038 if (pIe != NULL)
1039 {
1040
1041 pIe += 1;
1042 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
1043 &pConfig->SapHw_mode);
1044 }
1045
1046 if( pConfig->channel > 14 )
1047 {
1048 pConfig->SapHw_mode= eSAP_DOT11_MODE_11a;
1049 }
1050
1051 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
1052 WLAN_EID_HT_CAPABILITY);
1053
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301054 if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07001055 {
1056 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n;
1057 if(require_ht)
1058 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n_ONLY;
1059 }
1060}
1061
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05301062static int wlan_hdd_add_ie(hdd_adapter_t* pHostapdAdapter, v_U8_t *genie,
1063 v_U8_t *total_ielen, v_U8_t *oui, v_U8_t oui_size)
1064{
1065 v_U8_t ielen = 0;
1066 v_U8_t *pIe = NULL;
1067 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
1068
1069 pIe = wlan_hdd_get_vendor_oui_ie_ptr(oui, oui_size,
1070 pBeacon->tail, pBeacon->tail_len);
1071
1072 if (pIe)
1073 {
1074 ielen = pIe[1] + 2;
1075 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
1076 {
1077 vos_mem_copy(&genie[*total_ielen], pIe, ielen);
1078 }
1079 else
1080 {
1081 hddLog( VOS_TRACE_LEVEL_ERROR, "**Ie Length is too big***");
1082 return -EINVAL;
1083 }
1084 *total_ielen += ielen;
1085 }
1086 return 0;
1087}
1088
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001089#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07001090static int wlan_hdd_cfg80211_update_apies(hdd_adapter_t* pHostapdAdapter,
1091 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001092#else
1093static int wlan_hdd_cfg80211_update_apies(hdd_adapter_t* pHostapdAdapter,
1094 struct cfg80211_beacon_data *params)
1095#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07001096{
1097 v_U8_t *genie;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05301098 v_U8_t total_ielen = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07001099 v_U8_t addIE[1] = {0};
Jeff Johnsone7245742012-09-05 17:12:55 -07001100 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07001101
1102 genie = vos_mem_malloc(MAX_GENIE_LEN);
1103
1104 if(genie == NULL) {
1105
1106 return -ENOMEM;
1107 }
1108
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05301109 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
1110 &total_ielen, WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07001111 {
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05301112 ret = -EINVAL;
1113 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001114 }
1115
1116#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05301117 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
1118 &total_ielen, WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE))
1119 {
1120 ret = -EINVAL;
1121 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001122 }
1123#endif
1124
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05301125 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
1126 &total_ielen, P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07001127 {
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05301128 ret = -EINVAL;
1129 goto done;
1130 }
1131
1132 if (WLAN_HDD_SOFTAP == pHostapdAdapter->device_mode)
1133 {
1134 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
1135 &total_ielen, SS_OUI_TYPE, SS_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07001136 {
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05301137 ret = -EINVAL;
1138 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001139 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001140 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001141
1142 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1143 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, genie, total_ielen, NULL,
1144 eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
1145 {
1146 hddLog(LOGE,
1147 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001148 ret = -EINVAL;
1149 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001150 }
1151
1152 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1153 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
1154 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
1155 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
1156 ==eHAL_STATUS_FAILURE)
1157 {
1158 hddLog(LOGE,
1159 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001160 ret = -EINVAL;
1161 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001162 }
1163
1164 // Added for ProResp IE
1165 if ( (params->proberesp_ies != NULL) && (params->proberesp_ies_len != 0) )
1166 {
1167 u16 rem_probe_resp_ie_len = params->proberesp_ies_len;
1168 u8 probe_rsp_ie_len[3] = {0};
1169 u8 counter = 0;
1170 /* Check Probe Resp Length if it is greater then 255 then Store
1171 Probe Resp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1 &
1172 WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are not able
1173 Store More then 255 bytes into One Variable.
1174 */
1175 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
1176 {
1177 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
1178 {
1179 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
1180 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
1181 }
1182 else
1183 {
1184 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
1185 rem_probe_resp_ie_len = 0;
1186 }
1187 }
1188
1189 rem_probe_resp_ie_len = 0;
1190
1191 if (probe_rsp_ie_len[0] > 0)
1192 {
1193 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1194 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
1195 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
1196 probe_rsp_ie_len[0], NULL,
1197 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
1198 {
1199 hddLog(LOGE,
1200 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001201 ret = -EINVAL;
1202 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001203 }
1204 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
1205 }
1206
1207 if (probe_rsp_ie_len[1] > 0)
1208 {
1209 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1210 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
1211 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
1212 probe_rsp_ie_len[1], NULL,
1213 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
1214 {
1215 hddLog(LOGE,
1216 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001217 ret = -EINVAL;
1218 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001219 }
1220 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
1221 }
1222
1223 if (probe_rsp_ie_len[2] > 0)
1224 {
1225 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1226 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
1227 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
1228 probe_rsp_ie_len[2], NULL,
1229 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
1230 {
1231 hddLog(LOGE,
1232 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001233 ret = -EINVAL;
1234 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001235 }
1236 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
1237 }
1238
1239 if (probe_rsp_ie_len[1] == 0 )
1240 {
1241 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1242 WNI_CFG_PROBE_RSP_ADDNIE_DATA2, (tANI_U8*)addIE, 0, NULL,
1243 eANI_BOOLEAN_FALSE) )
1244 {
1245 hddLog(LOGE,
1246 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM\n");
1247 }
1248 }
1249
1250 if (probe_rsp_ie_len[2] == 0 )
1251 {
1252 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1253 WNI_CFG_PROBE_RSP_ADDNIE_DATA3, (tANI_U8*)addIE, 0, NULL,
1254 eANI_BOOLEAN_FALSE) )
1255 {
1256 hddLog(LOGE,
1257 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM\n");
1258 }
1259 }
1260
1261 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1262 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
1263 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
1264 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
1265 == eHAL_STATUS_FAILURE)
1266 {
1267 hddLog(LOGE,
1268 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001269 ret = -EINVAL;
1270 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001271 }
1272 }
1273 else
1274 {
1275 // Reset WNI_CFG_PROBE_RSP Flags
1276 wlan_hdd_reset_prob_rspies(pHostapdAdapter);
1277
1278 hddLog(VOS_TRACE_LEVEL_INFO,
1279 "%s: No Probe Response IE received in set beacon",
1280 __func__);
1281 }
1282
1283 // Added for AssocResp IE
1284 if ( (params->assocresp_ies != NULL) && (params->assocresp_ies_len != 0) )
1285 {
1286 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1287 WNI_CFG_ASSOC_RSP_ADDNIE_DATA, (tANI_U8*)params->assocresp_ies,
1288 params->assocresp_ies_len, NULL,
1289 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
1290 {
1291 hddLog(LOGE,
1292 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001293 ret = -EINVAL;
1294 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001295 }
1296
1297 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1298 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 1, NULL,
1299 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
1300 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
1301 == eHAL_STATUS_FAILURE)
1302 {
1303 hddLog(LOGE,
1304 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001305 ret = -EINVAL;
1306 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001307 }
1308 }
1309 else
1310 {
1311 hddLog(VOS_TRACE_LEVEL_INFO,
1312 "%s: No Assoc Response IE received in set beacon",
1313 __func__);
1314
1315 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1316 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
1317 eANI_BOOLEAN_FALSE) )
1318 {
1319 hddLog(LOGE,
1320 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM\n");
1321 }
1322 }
1323
Jeff Johnsone7245742012-09-05 17:12:55 -07001324done:
Jeff Johnson295189b2012-06-20 16:38:30 -07001325 vos_mem_free(genie);
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05301326 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07001327}
Jeff Johnson295189b2012-06-20 16:38:30 -07001328
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301329/*
Jeff Johnson295189b2012-06-20 16:38:30 -07001330 * FUNCTION: wlan_hdd_validate_operation_channel
1331 * called by wlan_hdd_cfg80211_start_bss() and
1332 * wlan_hdd_cfg80211_set_channel()
1333 * This function validates whether given channel is part of valid
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301334 * channel list.
1335 */
Jeff Johnson295189b2012-06-20 16:38:30 -07001336static VOS_STATUS wlan_hdd_validate_operation_channel(hdd_adapter_t *pAdapter,int channel)
1337{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301338
Jeff Johnson295189b2012-06-20 16:38:30 -07001339 v_U32_t num_ch = 0;
1340 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN];
1341 u32 indx = 0;
1342 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05301343 v_U8_t fValidChannel = FALSE, count = 0;
1344 hdd_config_t *hdd_pConfig_ini= (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301345
Jeff Johnson295189b2012-06-20 16:38:30 -07001346 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
1347
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05301348 if ( hdd_pConfig_ini->sapAllowAllChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -07001349 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05301350 /* Validate the channel */
1351 for (count = RF_CHAN_1 ; count <= RF_CHAN_165 ; count++)
Jeff Johnson295189b2012-06-20 16:38:30 -07001352 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05301353 if ( channel == rfChannels[count].channelNum )
1354 {
1355 fValidChannel = TRUE;
1356 break;
1357 }
1358 }
1359 if (fValidChannel != TRUE)
1360 {
1361 hddLog(VOS_TRACE_LEVEL_ERROR,
1362 "%s: Invalid Channel [%d]", __func__, channel);
1363 return VOS_STATUS_E_FAILURE;
Jeff Johnson295189b2012-06-20 16:38:30 -07001364 }
1365 }
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05301366 else
Jeff Johnson295189b2012-06-20 16:38:30 -07001367 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05301368 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
1369 valid_ch, &num_ch))
1370 {
1371 hddLog(VOS_TRACE_LEVEL_ERROR,
1372 "%s: failed to get valid channel list", __func__);
1373 return VOS_STATUS_E_FAILURE;
1374 }
1375 for (indx = 0; indx < num_ch; indx++)
1376 {
1377 if (channel == valid_ch[indx])
1378 {
1379 break;
1380 }
1381 }
1382
1383 if (indx >= num_ch)
1384 {
1385 hddLog(VOS_TRACE_LEVEL_ERROR,
1386 "%s: Invalid Channel [%d]", __func__, channel);
1387 return VOS_STATUS_E_FAILURE;
1388 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001389 }
1390 return VOS_STATUS_SUCCESS;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301391
Jeff Johnson295189b2012-06-20 16:38:30 -07001392}
1393
Viral Modi3a32cc52013-02-08 11:14:52 -08001394/**
1395 * FUNCTION: wlan_hdd_cfg80211_set_channel
1396 * This function is used to set the channel number
1397 */
1398static int wlan_hdd_cfg80211_set_channel( struct wiphy *wiphy, struct net_device *dev,
1399 struct ieee80211_channel *chan,
1400 enum nl80211_channel_type channel_type
1401 )
1402{
1403 v_U32_t num_ch = 0;
Jeff Johnson4416a782013-03-25 14:17:50 -07001404 int channel = 0;
Viral Modi3a32cc52013-02-08 11:14:52 -08001405 hdd_adapter_t *pAdapter = NULL;
1406 int freq = chan->center_freq; /* freq is in MHZ */
1407
1408 ENTER();
1409
1410 if( NULL == dev )
1411 {
1412 hddLog(VOS_TRACE_LEVEL_ERROR,
1413 "%s: Called with dev = NULL.\n", __func__);
1414 return -ENODEV;
1415 }
1416 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
1417
1418 hddLog(VOS_TRACE_LEVEL_INFO,
1419 "%s: device_mode = %d freq = %d \n",__func__,
1420 pAdapter->device_mode, chan->center_freq);
1421 if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress)
1422 {
1423 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:LOGP in Progress. Ignore!!!",__func__);
1424 return -EAGAIN;
1425 }
1426
1427 /*
1428 * Do freq to chan conversion
1429 * TODO: for 11a
1430 */
1431
1432 channel = ieee80211_frequency_to_channel(freq);
1433
1434 /* Check freq range */
1435 if ((WNI_CFG_CURRENT_CHANNEL_STAMIN > channel) ||
1436 (WNI_CFG_CURRENT_CHANNEL_STAMAX < channel))
1437 {
1438 hddLog(VOS_TRACE_LEVEL_ERROR,
1439 "%s: Channel [%d] is outside valid range from %d to %d\n",
1440 __func__, channel, WNI_CFG_CURRENT_CHANNEL_STAMIN,
1441 WNI_CFG_CURRENT_CHANNEL_STAMAX);
1442 return -EINVAL;
1443 }
1444
1445 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
1446
Gopichand Nakkala6ab19562013-03-07 13:59:42 +05301447 if ((WLAN_HDD_SOFTAP != pAdapter->device_mode) &&
1448 (WLAN_HDD_P2P_GO != pAdapter->device_mode))
Viral Modi3a32cc52013-02-08 11:14:52 -08001449 {
1450 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pAdapter,channel))
1451 {
1452 hddLog(VOS_TRACE_LEVEL_ERROR,
1453 "%s: Invalid Channel [%d] \n", __func__, channel);
1454 return -EINVAL;
1455 }
1456 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
1457 "%s: set channel to [%d] for device mode =%d",
1458 __func__, channel,pAdapter->device_mode);
1459 }
1460 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Viral Modi3a32cc52013-02-08 11:14:52 -08001461 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Viral Modi3a32cc52013-02-08 11:14:52 -08001462 )
1463 {
1464 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
1465 tCsrRoamProfile * pRoamProfile = &pWextState->roamProfile;
1466 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
1467
1468 if (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState)
1469 {
1470 /* Link is up then return cant set channel*/
1471 hddLog( VOS_TRACE_LEVEL_ERROR,
1472 "%s: IBSS Associated, can't set the channel\n", __func__);
1473 return -EINVAL;
1474 }
1475
1476 num_ch = pRoamProfile->ChannelInfo.numOfChannels = 1;
1477 pHddStaCtx->conn_info.operationChannel = channel;
1478 pRoamProfile->ChannelInfo.ChannelList =
1479 &pHddStaCtx->conn_info.operationChannel;
1480 }
1481 else if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Viral Modi3a32cc52013-02-08 11:14:52 -08001482 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Viral Modi3a32cc52013-02-08 11:14:52 -08001483 )
1484 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05301485 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
1486 {
1487 if(VOS_STATUS_SUCCESS !=
1488 wlan_hdd_validate_operation_channel(pAdapter,channel))
1489 {
1490 hddLog(VOS_TRACE_LEVEL_ERROR,
1491 "%s: Invalid Channel [%d] \n", __func__, channel);
1492 return -EINVAL;
1493 }
1494 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
1495 }
1496 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
Viral Modi3a32cc52013-02-08 11:14:52 -08001497 {
1498 hdd_config_t *cfg_param = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
1499
1500 /* If auto channel selection is configured as enable/ 1 then ignore
1501 channel set by supplicant
1502 */
1503 if ( cfg_param->apAutoChannelSelection )
1504 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05301505 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel =
1506 AUTO_CHANNEL_SELECT;
Viral Modi3a32cc52013-02-08 11:14:52 -08001507 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
1508 "%s: set channel to auto channel (0) for device mode =%d",
1509 __func__, pAdapter->device_mode);
1510 }
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05301511 else
1512 {
1513 if(VOS_STATUS_SUCCESS !=
1514 wlan_hdd_validate_operation_channel(pAdapter,channel))
1515 {
1516 hddLog(VOS_TRACE_LEVEL_ERROR,
1517 "%s: Invalid Channel [%d] \n", __func__, channel);
1518 return -EINVAL;
1519 }
1520 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
1521 }
Viral Modi3a32cc52013-02-08 11:14:52 -08001522 }
1523 }
1524 else
1525 {
1526 hddLog(VOS_TRACE_LEVEL_FATAL,
1527 "%s: Invalid device mode failed to set valid channel", __func__);
1528 return -EINVAL;
1529 }
1530 EXIT();
1531 return 0;
1532}
1533
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301534/*
Madan Mohan Koyyalamudi59381622012-11-28 01:56:47 +05301535 * FUNCTION: wlan_hdd_select_cbmode
1536 * called by wlan_hdd_cfg80211_start_bss() and
1537 * This function selects the cbmode based on primary channel
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301538 */
Madan Mohan Koyyalamudi527935a2012-12-04 16:41:16 -08001539VOS_STATUS wlan_sap_select_cbmode(void *pAdapter,eSapPhyMode SapHw_mode, v_U8_t channel)
Madan Mohan Koyyalamudi59381622012-11-28 01:56:47 +05301540{
1541 tSmeConfigParams smeConfig;
Madan Mohan Koyyalamudi527935a2012-12-04 16:41:16 -08001542 hdd_context_t *pHddCtx = ( hdd_context_t *) pAdapter;
1543 hdd_config_t *pConfigIni = ((hdd_context_t *)(pAdapter))->cfg_ini;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301544
Madan Mohan Koyyalamudi59381622012-11-28 01:56:47 +05301545 if(
1546#ifdef WLAN_FEATURE_11AC
Madan Mohan Koyyalamudi527935a2012-12-04 16:41:16 -08001547 SapHw_mode != eSAP_DOT11_MODE_11ac &&
1548 SapHw_mode != eSAP_DOT11_MODE_11ac_ONLY &&
Madan Mohan Koyyalamudi59381622012-11-28 01:56:47 +05301549#endif
Madan Mohan Koyyalamudi527935a2012-12-04 16:41:16 -08001550 SapHw_mode != eSAP_DOT11_MODE_11n &&
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301551 SapHw_mode != eSAP_DOT11_MODE_11n_ONLY
Madan Mohan Koyyalamudi59381622012-11-28 01:56:47 +05301552 )
1553 {
1554 return VOS_STATUS_SUCCESS;
1555 }
1556
1557 if (!pConfigIni->nChannelBondingMode5GHz) {
1558 return VOS_STATUS_SUCCESS;
1559 }
1560
Madan Mohan Koyyalamudi527935a2012-12-04 16:41:16 -08001561 //channel = pSapConfig->channel;
Madan Mohan Koyyalamudi59381622012-11-28 01:56:47 +05301562 vos_mem_zero(&smeConfig, sizeof (tSmeConfigParams));
1563
1564 sme_GetConfigParam(pHddCtx->hHal, &smeConfig);
1565
1566#ifdef WLAN_FEATURE_11AC
1567
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301568 if ( SapHw_mode == eSAP_DOT11_MODE_11ac ||
Madan Mohan Koyyalamudi527935a2012-12-04 16:41:16 -08001569 SapHw_mode == eSAP_DOT11_MODE_11ac_ONLY )
Madan Mohan Koyyalamudi59381622012-11-28 01:56:47 +05301570 {
1571 if ( channel== 36 || channel == 52 || channel == 100 ||
1572 channel == 116 || channel == 149 )
1573 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301574 smeConfig.csrConfig.channelBondingMode5GHz =
Madan Mohan Koyyalamudi59381622012-11-28 01:56:47 +05301575 PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_LOW - 1;
1576 }
1577 else if ( channel == 40 || channel == 56 || channel == 104 ||
1578 channel == 120 || channel == 153 )
1579 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301580 smeConfig.csrConfig.channelBondingMode5GHz =
Madan Mohan Koyyalamudi59381622012-11-28 01:56:47 +05301581 PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_LOW - 1;
1582 }
1583 else if ( channel == 44 || channel == 60 || channel == 108 ||
1584 channel == 124 || channel == 157 )
1585 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301586 smeConfig.csrConfig.channelBondingMode5GHz =
Madan Mohan Koyyalamudi59381622012-11-28 01:56:47 +05301587 PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_HIGH -1;
1588 }
1589 else if ( channel == 48 || channel == 64 || channel == 112 ||
1590 channel == 128 || channel == 161 )
1591 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301592 smeConfig.csrConfig.channelBondingMode5GHz =
Madan Mohan Koyyalamudi59381622012-11-28 01:56:47 +05301593 PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_HIGH - 1;
1594 }
Shailender Karmuchi84f11f02013-02-12 17:11:45 -08001595 else if ( channel == 165 )
1596 {
1597 smeConfig.csrConfig.channelBondingMode5GHz = 0;
1598 }
Madan Mohan Koyyalamudi59381622012-11-28 01:56:47 +05301599 }
1600#endif
Madan Mohan Koyyalamudi527935a2012-12-04 16:41:16 -08001601 if ( SapHw_mode == eSAP_DOT11_MODE_11n ||
1602 SapHw_mode == eSAP_DOT11_MODE_11n_ONLY )
Madan Mohan Koyyalamudi59381622012-11-28 01:56:47 +05301603 {
1604 if ( channel== 40 || channel == 48 || channel == 56 ||
1605 channel == 64 || channel == 104 || channel == 112 ||
1606 channel == 120 || channel == 128 || channel == 136 ||
1607 channel == 144 || channel == 153 || channel == 161 )
1608 {
1609 smeConfig.csrConfig.channelBondingMode5GHz = 1;
1610 }
1611 else if ( channel== 36 || channel == 44 || channel == 52 ||
1612 channel == 60 || channel == 100 || channel == 108 ||
1613 channel == 116 || channel == 124 || channel == 132 ||
1614 channel == 140 || channel == 149 || channel == 157 )
1615 {
1616 smeConfig.csrConfig.channelBondingMode5GHz = 2;
1617 }
Shailender Karmuchi84f11f02013-02-12 17:11:45 -08001618 else if ( channel == 165 )
1619 {
1620 smeConfig.csrConfig.channelBondingMode5GHz = 0;
1621 }
Madan Mohan Koyyalamudi59381622012-11-28 01:56:47 +05301622 }
1623 pr_info ("cbmode selected=%ld\n",smeConfig.csrConfig.channelBondingMode5GHz);
1624
1625 sme_UpdateConfig (pHddCtx->hHal,&smeConfig);
1626 return VOS_STATUS_SUCCESS;
1627}
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001628
Jeff Johnson295189b2012-06-20 16:38:30 -07001629#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
1630static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
1631 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001632#else
1633static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
1634 struct cfg80211_beacon_data *params,
1635 const u8 *ssid, size_t ssid_len,
1636 enum nl80211_hidden_ssid hidden_ssid)
1637#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07001638{
1639 tsap_Config_t *pConfig;
1640 beacon_data_t *pBeacon = NULL;
1641 struct ieee80211_mgmt *pMgmt_frame;
1642 v_U8_t *pIe=NULL;
1643 v_U16_t capab_info;
1644 eCsrAuthType RSNAuthType;
1645 eCsrEncryptionType RSNEncryptType;
1646 eCsrEncryptionType mcRSNEncryptType;
1647 int status = VOS_STATUS_SUCCESS;
1648 tpWLAN_SAPEventCB pSapEventCallback;
1649 hdd_hostapd_state_t *pHostapdState;
1650 v_U8_t wpaRsnIEdata[(SIR_MAC_MAX_IE_LENGTH * 2)+4]; //Max ie length 255 * 2(WPA+RSN) + 2 bytes (vendor specific ID) * 2
1651 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05301652 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07001653 struct qc_mac_acl_entry *acl_entry = NULL;
1654 v_SINT_t i;
Madan Mohan Koyyalamudi543172b2012-12-05 16:40:18 -08001655 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07001656
1657 ENTER();
1658
1659 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter);
1660
1661 pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
1662
1663 pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
1664
1665 pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
1666
1667 pConfig->beacon_int = pMgmt_frame->u.beacon.beacon_int;
1668
1669 //channel is already set in the set_channel Call back
1670 //pConfig->channel = pCommitConfig->channel;
1671
1672 /*Protection parameter to enable or disable*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301673 pConfig->protEnabled =
Jeff Johnson295189b2012-06-20 16:38:30 -07001674 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtEnabled;
1675
1676 pConfig->dtim_period = pBeacon->dtim_period;
1677
1678 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"****pConfig->dtim_period=%d***\n",
1679 pConfig->dtim_period);
1680
1681
Madan Mohan Koyyalamudie0ca11f2012-11-27 15:57:52 -08001682 if (pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson32d95a32012-09-10 13:15:23 -07001683 {
1684 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -07001685 WLAN_EID_COUNTRY);
Jeff Johnson32d95a32012-09-10 13:15:23 -07001686 if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07001687 {
Jeff Johnson32d95a32012-09-10 13:15:23 -07001688 tANI_BOOLEAN restartNeeded;
Jeff Johnson32d95a32012-09-10 13:15:23 -07001689 pConfig->ieee80211d = 1;
1690 vos_mem_copy(pConfig->countryCode, &pIe[2], 3);
1691 sme_setRegInfo(hHal, pConfig->countryCode);
1692 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
Jeff Johnson295189b2012-06-20 16:38:30 -07001693 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07001694 else
1695 {
1696 pConfig->ieee80211d = 0;
1697 }
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05301698 /*
1699 * If auto channel is configured i.e. channel is 0,
1700 * so skip channel validation.
1701 */
1702 if( AUTO_CHANNEL_SELECT != pConfig->channel )
1703 {
1704 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pHostapdAdapter,pConfig->channel))
1705 {
1706 hddLog(VOS_TRACE_LEVEL_ERROR,
1707 "%s: Invalid Channel [%d] \n", __func__, pConfig->channel);
1708 return -EINVAL;
1709 }
1710 }
1711 else
1712 {
1713 if(1 != pHddCtx->is_dynamic_channel_range_set)
1714 {
1715 hdd_config_t *hdd_pConfig= (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini;
1716 WLANSAP_SetChannelRange(hHal, hdd_pConfig->apStartChannelNum,
1717 hdd_pConfig->apEndChannelNum,hdd_pConfig->apOperatingBand);
1718 }
1719 pHddCtx->is_dynamic_channel_range_set = 0;
1720 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001721 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07001722 else
Jeff Johnson295189b2012-06-20 16:38:30 -07001723 {
1724 pConfig->ieee80211d = 0;
1725 }
1726 pConfig->authType = eSAP_AUTO_SWITCH;
1727
1728 capab_info = pMgmt_frame->u.beacon.capab_info;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301729
1730 pConfig->privacy = (pMgmt_frame->u.beacon.capab_info &
Jeff Johnson295189b2012-06-20 16:38:30 -07001731 WLAN_CAPABILITY_PRIVACY) ? VOS_TRUE : VOS_FALSE;
1732
1733 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uPrivacy = pConfig->privacy;
1734
1735 /*Set wps station to configured*/
1736 pIe = wlan_hdd_get_wps_ie_ptr(pBeacon->tail, pBeacon->tail_len);
1737
1738 if(pIe)
1739 {
1740 if(pIe[1] < (2 + WPS_OUI_TYPE_SIZE))
1741 {
1742 hddLog( VOS_TRACE_LEVEL_ERROR, "**Wps Ie Length is too small***\n");
1743 return -EINVAL;
1744 }
1745 else if(memcmp(&pIe[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) == 0)
1746 {
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07001747 hddLog( VOS_TRACE_LEVEL_INFO, "** WPS IE(len %d) ***", (pIe[1]+2));
Jeff Johnson295189b2012-06-20 16:38:30 -07001748 /* Check 15 bit of WPS IE as it contain information for wps state
1749 * WPS state
1750 */
1751 if(SAP_WPS_ENABLED_UNCONFIGURED == pIe[15])
1752 {
1753 pConfig->wps_state = SAP_WPS_ENABLED_UNCONFIGURED;
1754 } else if(SAP_WPS_ENABLED_CONFIGURED == pIe[15])
1755 {
1756 pConfig->wps_state = SAP_WPS_ENABLED_CONFIGURED;
1757 }
1758 }
1759 }
1760 else
1761 {
1762 pConfig->wps_state = SAP_WPS_DISABLED;
1763 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301764 pConfig->fwdWPSPBCProbeReq = 1; // Forward WPS PBC probe request frame up
Jeff Johnson295189b2012-06-20 16:38:30 -07001765
1766 pConfig->RSNWPAReqIELength = 0;
1767 pConfig->pRSNWPAReqIE = NULL;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301768 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -07001769 WLAN_EID_RSN);
1770 if(pIe && pIe[1])
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301771 {
Jeff Johnson295189b2012-06-20 16:38:30 -07001772 pConfig->RSNWPAReqIELength = pIe[1] + 2;
1773 memcpy(&wpaRsnIEdata[0], pIe, pConfig->RSNWPAReqIELength);
1774 pConfig->pRSNWPAReqIE = &wpaRsnIEdata[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301775 /* The actual processing may eventually be more extensive than
1776 * this. Right now, just consume any PMKIDs that are sent in
Jeff Johnson295189b2012-06-20 16:38:30 -07001777 * by the app.
1778 * */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301779 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -07001780 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
1781 &RSNEncryptType,
1782 &mcRSNEncryptType,
1783 &RSNAuthType,
1784 pConfig->pRSNWPAReqIE[1]+2,
1785 pConfig->pRSNWPAReqIE );
1786
1787 if( VOS_STATUS_SUCCESS == status )
1788 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301789 /* Now copy over all the security attributes you have
1790 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -07001791 * */
1792 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
1793 pConfig->mcRSNEncryptType = mcRSNEncryptType;
1794 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
1795 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05301796 hddLog( LOG1, FL("CSR AuthType = %d, "
Jeff Johnson295189b2012-06-20 16:38:30 -07001797 "EncryptionType = %d mcEncryptionType = %d\n"),
1798 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
1799 }
1800 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301801
Jeff Johnson295189b2012-06-20 16:38:30 -07001802 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE,
1803 pBeacon->tail, pBeacon->tail_len);
1804
1805 if(pIe && pIe[1] && (pIe[0] == DOT11F_EID_WPA))
1806 {
1807 if (pConfig->pRSNWPAReqIE)
1808 {
1809 /*Mixed mode WPA/WPA2*/
1810 memcpy((&wpaRsnIEdata[0] + pConfig->RSNWPAReqIELength), pIe, pIe[1] + 2);
1811 pConfig->RSNWPAReqIELength += pIe[1] + 2;
1812 }
1813 else
1814 {
1815 pConfig->RSNWPAReqIELength = pIe[1] + 2;
1816 memcpy(&wpaRsnIEdata[0], pIe, pConfig->RSNWPAReqIELength);
1817 pConfig->pRSNWPAReqIE = &wpaRsnIEdata[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301818 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -07001819 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
1820 &RSNEncryptType,
1821 &mcRSNEncryptType,
1822 &RSNAuthType,
1823 pConfig->pRSNWPAReqIE[1]+2,
1824 pConfig->pRSNWPAReqIE );
1825
1826 if( VOS_STATUS_SUCCESS == status )
1827 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301828 /* Now copy over all the security attributes you have
1829 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -07001830 * */
1831 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
1832 pConfig->mcRSNEncryptType = mcRSNEncryptType;
1833 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
1834 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05301835 hddLog( LOG1, FL("CSR AuthType = %d, "
Jeff Johnson295189b2012-06-20 16:38:30 -07001836 "EncryptionType = %d mcEncryptionType = %d\n"),
1837 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
1838 }
1839 }
1840 }
1841
Jeff Johnson4416a782013-03-25 14:17:50 -07001842 if (pConfig->RSNWPAReqIELength > sizeof wpaRsnIEdata) {
1843 hddLog( VOS_TRACE_LEVEL_ERROR, "**RSNWPAReqIELength is too large***");
1844 return -EINVAL;
1845 }
1846
Jeff Johnson295189b2012-06-20 16:38:30 -07001847 pConfig->SSIDinfo.ssidHidden = VOS_FALSE;
1848
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001849#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07001850 if (params->ssid != NULL)
1851 {
1852 memcpy(pConfig->SSIDinfo.ssid.ssId, params->ssid, params->ssid_len);
1853 pConfig->SSIDinfo.ssid.length = params->ssid_len;
1854 if (params->hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
1855 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
1856 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001857#else
1858 if (ssid != NULL)
1859 {
1860 memcpy(pConfig->SSIDinfo.ssid.ssId, ssid, ssid_len);
1861 pConfig->SSIDinfo.ssid.length = ssid_len;
1862 if (hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
1863 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
1864 }
1865#endif
1866
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301867 vos_mem_copy(pConfig->self_macaddr.bytes,
Jeff Johnson295189b2012-06-20 16:38:30 -07001868 pHostapdAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301869
Jeff Johnson295189b2012-06-20 16:38:30 -07001870 /* default value */
1871 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
1872 pConfig->num_accept_mac = 0;
1873 pConfig->num_deny_mac = 0;
1874
1875 pIe = wlan_hdd_get_vendor_oui_ie_ptr(BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
1876 pBeacon->tail, pBeacon->tail_len);
1877
1878 /* pIe for black list is following form:
1879 type : 1 byte
1880 length : 1 byte
1881 OUI : 4 bytes
1882 acl type : 1 byte
1883 no of mac addr in black list: 1 byte
1884 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301885 */
1886 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07001887 {
1888 pConfig->SapMacaddr_acl = pIe[6];
1889 pConfig->num_deny_mac = pIe[7];
1890 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no deny mac = %d\n",
1891 pIe[6], pIe[7]);
1892 if (pConfig->num_deny_mac > MAX_MAC_ADDRESS_DENIED)
1893 pConfig->num_deny_mac = MAX_MAC_ADDRESS_DENIED;
1894 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
1895 for (i = 0; i < pConfig->num_deny_mac; i++)
1896 {
1897 vos_mem_copy(&pConfig->deny_mac[i], acl_entry->addr, sizeof(qcmacaddr));
1898 acl_entry++;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301899 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001900 }
1901 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
1902 pBeacon->tail, pBeacon->tail_len);
1903
1904 /* pIe for white list is following form:
1905 type : 1 byte
1906 length : 1 byte
1907 OUI : 4 bytes
1908 acl type : 1 byte
1909 no of mac addr in white list: 1 byte
1910 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301911 */
1912 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07001913 {
1914 pConfig->SapMacaddr_acl = pIe[6];
1915 pConfig->num_accept_mac = pIe[7];
1916 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no accept mac = %d\n",
1917 pIe[6], pIe[7]);
1918 if (pConfig->num_accept_mac > MAX_MAC_ADDRESS_ACCEPTED)
1919 pConfig->num_accept_mac = MAX_MAC_ADDRESS_ACCEPTED;
1920 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
1921 for (i = 0; i < pConfig->num_accept_mac; i++)
1922 {
1923 vos_mem_copy(&pConfig->accept_mac[i], acl_entry->addr, sizeof(qcmacaddr));
1924 acl_entry++;
1925 }
1926 }
1927 wlan_hdd_set_sapHwmode(pHostapdAdapter);
1928
Jeff Johnsone7245742012-09-05 17:12:55 -07001929#ifdef WLAN_FEATURE_11AC
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -08001930 /* Overwrite the hostapd setting for HW mode only for 11ac.
1931 * This is valid only if mode is set to 11n in hostapd and either AUTO or 11ac in .ini .
1932 * Otherwise, leave whatever is set in hostapd (a OR b OR g OR n mode) */
1933 if( ((pConfig->SapHw_mode == eSAP_DOT11_MODE_11n) ||
1934 (pConfig->SapHw_mode == eSAP_DOT11_MODE_11n_ONLY)) &&
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301935 (((WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->dot11Mode == eHDD_DOT11_MODE_AUTO) ||
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -08001936 ((WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->dot11Mode == eHDD_DOT11_MODE_11ac) ||
1937 ((WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->dot11Mode == eHDD_DOT11_MODE_11ac_ONLY)) )
Jeff Johnsone7245742012-09-05 17:12:55 -07001938 {
1939 pConfig->SapHw_mode = eSAP_DOT11_MODE_11ac;
1940 }
1941#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301942
Madan Mohan Koyyalamudi527935a2012-12-04 16:41:16 -08001943 if( AUTO_CHANNEL_SELECT != pConfig->channel)
1944 wlan_sap_select_cbmode((WLAN_HDD_GET_CTX(pHostapdAdapter)),pConfig->SapHw_mode,pConfig->channel);
Jeff Johnson295189b2012-06-20 16:38:30 -07001945 // ht_capab is not what the name conveys,this is used for protection bitmap
1946 pConfig->ht_capab =
1947 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtection;
1948
1949 if ( 0 != wlan_hdd_cfg80211_update_apies(pHostapdAdapter, params) )
1950 {
1951 hddLog(LOGE, FL("SAP Not able to set AP IEs"));
1952 return -EINVAL;
1953 }
1954
1955 //Uapsd Enabled Bit
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301956 pConfig->UapsdEnable =
Jeff Johnson295189b2012-06-20 16:38:30 -07001957 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apUapsdEnabled;
1958 //Enable OBSS protection
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301959 pConfig->obssProtEnabled =
1960 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apOBSSProtEnabled;
Jeff Johnson295189b2012-06-20 16:38:30 -07001961
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301962 hddLog(LOGW, FL("SOftAP macaddress : "MAC_ADDRESS_STR"\n"),
Jeff Johnson295189b2012-06-20 16:38:30 -07001963 MAC_ADDR_ARRAY(pHostapdAdapter->macAddressCurrent.bytes));
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301964 hddLog(LOGW,FL("ssid =%s\n"), pConfig->SSIDinfo.ssid.ssId);
Jeff Johnson295189b2012-06-20 16:38:30 -07001965 hddLog(LOGW,FL("beaconint=%d, channel=%d\n"), (int)pConfig->beacon_int,
1966 (int)pConfig->channel);
1967 hddLog(LOGW,FL("hw_mode=%x\n"), pConfig->SapHw_mode);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301968 hddLog(LOGW,FL("privacy=%d, authType=%d\n"), pConfig->privacy,
1969 pConfig->authType);
Jeff Johnson295189b2012-06-20 16:38:30 -07001970 hddLog(LOGW,FL("RSN/WPALen=%d, \n"),(int)pConfig->RSNWPAReqIELength);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301971 hddLog(LOGW,FL("Uapsd = %d\n"),pConfig->UapsdEnable);
Jeff Johnson295189b2012-06-20 16:38:30 -07001972 hddLog(LOGW,FL("ProtEnabled = %d, OBSSProtEnabled = %d\n"),
1973 pConfig->protEnabled, pConfig->obssProtEnabled);
1974
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301975 if(test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -07001976 {
1977 //Bss already started. just return.
1978 //TODO Probably it should update some beacon params.
1979 hddLog( LOGE, "Bss Already started...Ignore the request");
1980 EXIT();
1981 return 0;
1982 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301983
Jeff Johnson295189b2012-06-20 16:38:30 -07001984 pConfig->persona = pHostapdAdapter->device_mode;
1985
1986 pSapEventCallback = hdd_hostapd_SAPEventCB;
1987 if(WLANSAP_StartBss(pVosContext, pSapEventCallback, pConfig,
1988 (v_PVOID_t)pHostapdAdapter->dev) != VOS_STATUS_SUCCESS)
1989 {
1990 hddLog(LOGE,FL("SAP Start Bss fail\n"));
1991 return -EINVAL;
1992 }
1993
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301994 hddLog(LOG1,
Jeff Johnson295189b2012-06-20 16:38:30 -07001995 FL("Waiting for Scan to complete(auto mode) and BSS to start"));
1996
1997 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301998
Jeff Johnson295189b2012-06-20 16:38:30 -07001999 if (!VOS_IS_STATUS_SUCCESS(status))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302000 {
2001 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07002002 ("ERROR: HDD vos wait for single_event failed!!\n"));
2003 VOS_ASSERT(0);
2004 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302005
Jeff Johnson295189b2012-06-20 16:38:30 -07002006 //Succesfully started Bss update the state bit.
2007 set_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags);
2008
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07002009#ifdef WLAN_FEATURE_P2P_DEBUG
2010 if (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO)
2011 {
2012 if(globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED)
2013 {
2014 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
2015 hddLog(LOGE,"[P2P State] From Go nego completed to "
Jeff Johnson1250df42012-12-10 14:31:52 -08002016 "Non-autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07002017 }
2018 else if(globalP2PConnectionStatus == P2P_NOT_ACTIVE)
2019 {
2020 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
2021 hddLog(LOGE,"[P2P State] From Inactive to "
Jeff Johnson1250df42012-12-10 14:31:52 -08002022 "Autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07002023 }
2024 }
2025#endif
2026
Jeff Johnson295189b2012-06-20 16:38:30 -07002027 pHostapdState->bCommit = TRUE;
2028 EXIT();
2029
2030 return 0;
2031}
2032
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002033#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302034static int wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy,
2035 struct net_device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -07002036 struct beacon_parameters *params)
2037{
2038 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302039 int status=VOS_STATUS_SUCCESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07002040
2041 ENTER();
2042
2043 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "device mode=%d\n",pAdapter->device_mode);
2044
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002045 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
2046 {
2047 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2048 "%s:LOGP in Progress. Ignore!!!", __func__);
2049 return -EAGAIN;
2050 }
2051
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302052 if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07002053 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07002054 )
2055 {
2056 beacon_data_t *old,*new;
2057
2058 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302059
Jeff Johnson295189b2012-06-20 16:38:30 -07002060 if (old)
2061 return -EALREADY;
2062
2063 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
2064
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302065 if(status != VOS_STATUS_SUCCESS)
Jeff Johnson295189b2012-06-20 16:38:30 -07002066 {
2067 hddLog(VOS_TRACE_LEVEL_FATAL,
2068 "%s:Error!!! Allocating the new beacon\n",__func__);
2069 return -EINVAL;
2070 }
2071
2072 pAdapter->sessionCtx.ap.beacon = new;
2073
2074 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
2075 }
2076
2077 EXIT();
2078 return status;
2079}
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302080
2081static int wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07002082 struct net_device *dev,
2083 struct beacon_parameters *params)
2084{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302085 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnson295189b2012-06-20 16:38:30 -07002086 int status=VOS_STATUS_SUCCESS;
2087
2088 ENTER();
2089
2090 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",
2091 __func__,pAdapter->device_mode);
2092
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002093 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
2094 {
2095 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2096 "%s:LOGP in Progress. Ignore!!!", __func__);
2097 return -EAGAIN;
2098 }
2099
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302100 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07002101 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302102 )
Jeff Johnson295189b2012-06-20 16:38:30 -07002103 {
2104 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302105
Jeff Johnson295189b2012-06-20 16:38:30 -07002106 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302107
Jeff Johnson295189b2012-06-20 16:38:30 -07002108 if (!old)
2109 return -ENOENT;
2110
2111 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
2112
2113 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302114 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson295189b2012-06-20 16:38:30 -07002115 "%s: Error!!! Allocating the new beacon\n",__func__);
2116 return -EINVAL;
2117 }
2118
2119 pAdapter->sessionCtx.ap.beacon = new;
2120
2121 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
2122 }
2123
2124 EXIT();
2125 return status;
2126}
2127
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002128#endif //(LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
2129
2130#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07002131static int wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy,
2132 struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002133#else
2134static int wlan_hdd_cfg80211_stop_ap (struct wiphy *wiphy,
2135 struct net_device *dev)
2136#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07002137{
2138 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnsone7245742012-09-05 17:12:55 -07002139 hdd_context_t *pHddCtx = NULL;
2140 hdd_scaninfo_t *pScanInfo = NULL;
2141 hdd_adapter_t *staAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07002142 VOS_STATUS status = 0;
2143
2144 ENTER();
2145
2146 if (NULL == pAdapter)
2147 {
2148 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002149 "%s: HDD adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002150 return -ENODEV;
2151 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07002152
Jeff Johnson4416a782013-03-25 14:17:50 -07002153 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07002154 if (NULL == pHddCtx)
2155 {
2156 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002157 "%s: HDD context is Null", __func__);
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07002158 return -ENODEV;
2159 }
Jeff Johnson4416a782013-03-25 14:17:50 -07002160 if (pHddCtx->isLogpInProgress)
2161 {
2162 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2163 "%s:LOGP in Progress. Ignore!!!", __func__);
2164 return -EAGAIN;
2165 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07002166
2167 staAdapter = hdd_get_adapter(pAdapter->pHddCtx, WLAN_HDD_INFRA_STATION);
2168 if (NULL == staAdapter)
2169 {
2170 staAdapter = hdd_get_adapter(pAdapter->pHddCtx, WLAN_HDD_P2P_CLIENT);
2171 if (NULL == staAdapter)
2172 {
2173 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002174 "%s: HDD adapter context is Null", __func__);
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07002175 return -ENODEV;
2176 }
2177 }
2178
2179 pScanInfo = &pHddCtx->scan_info;
2180
Jeff Johnson4416a782013-03-25 14:17:50 -07002181 if (pHddCtx->isLogpInProgress)
Jeff Johnson295189b2012-06-20 16:38:30 -07002182 {
2183 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:LOGP in Progress. Ignore!!!",__func__);
2184 return -EAGAIN;
2185 }
2186
2187 pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
2188
2189 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",
2190 __func__,pAdapter->device_mode);
2191
Jeff Johnsone7245742012-09-05 17:12:55 -07002192 if ((pScanInfo != NULL) && pScanInfo->mScanPending)
2193 {
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -08002194 INIT_COMPLETION(pScanInfo->abortscan_event_var);
Jeff Johnsone7245742012-09-05 17:12:55 -07002195 hdd_abort_mac_scan(staAdapter->pHddCtx);
2196 status = wait_for_completion_interruptible_timeout(
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -08002197 &pScanInfo->abortscan_event_var,
Jeff Johnsone7245742012-09-05 17:12:55 -07002198 msecs_to_jiffies(WLAN_WAIT_TIME_ABORTSCAN));
2199 if (!status)
2200 {
2201 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Jeff Johnson902c9832012-12-10 14:28:09 -08002202 "%s: Timeout occurred while waiting for abortscan" ,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002203 __func__);
Jeff Johnsone7245742012-09-05 17:12:55 -07002204 VOS_ASSERT(pScanInfo->mScanPending);
2205 return 0;
2206 }
2207 }
2208
Jeff Johnson295189b2012-06-20 16:38:30 -07002209 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07002210 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07002211 )
2212 {
2213 beacon_data_t *old;
2214
2215 old = pAdapter->sessionCtx.ap.beacon;
2216
2217 if (!old)
2218 return -ENOENT;
2219
Jeff Johnson295189b2012-06-20 16:38:30 -07002220 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07002221
2222 mutex_lock(&pHddCtx->sap_lock);
2223 if(test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
2224 {
Jeff Johnson4416a782013-03-25 14:17:50 -07002225 if ( VOS_STATUS_SUCCESS == (status = WLANSAP_StopBss(pHddCtx->pvosContext) ) )
Jeff Johnson295189b2012-06-20 16:38:30 -07002226 {
2227 hdd_hostapd_state_t *pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
2228
2229 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
2230
2231 if (!VOS_IS_STATUS_SUCCESS(status))
2232 {
2233 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2234 ("ERROR: HDD vos wait for single_event failed!!\n"));
2235 VOS_ASSERT(0);
2236 }
2237 }
2238 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
2239 }
2240 mutex_unlock(&pHddCtx->sap_lock);
2241
2242 if(status != VOS_STATUS_SUCCESS)
2243 {
2244 hddLog(VOS_TRACE_LEVEL_FATAL,
2245 "%s:Error!!! Stopping the BSS\n",__func__);
2246 return -EINVAL;
2247 }
2248
Jeff Johnson4416a782013-03-25 14:17:50 -07002249 if (ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -07002250 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 0,NULL, eANI_BOOLEAN_FALSE)
2251 ==eHAL_STATUS_FAILURE)
2252 {
2253 hddLog(LOGE,
2254 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM\n");
2255 }
2256
Jeff Johnson4416a782013-03-25 14:17:50 -07002257 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -07002258 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
2259 eANI_BOOLEAN_FALSE) )
2260 {
2261 hddLog(LOGE,
2262 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM\n");
2263 }
2264
2265 // Reset WNI_CFG_PROBE_RSP Flags
2266 wlan_hdd_reset_prob_rspies(pAdapter);
2267
2268 pAdapter->sessionCtx.ap.beacon = NULL;
2269 kfree(old);
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07002270#ifdef WLAN_FEATURE_P2P_DEBUG
2271 if((pAdapter->device_mode == WLAN_HDD_P2P_GO) &&
2272 (globalP2PConnectionStatus == P2P_GO_COMPLETED_STATE))
2273 {
2274 hddLog(LOGE,"[P2P State] From GO completed to Inactive state "
2275 "GO got removed");
2276 globalP2PConnectionStatus = P2P_NOT_ACTIVE;
2277 }
2278#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07002279 }
2280 EXIT();
2281 return status;
2282}
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002283
2284#if (LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
2285
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302286static int wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
2287 struct net_device *dev,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002288 struct cfg80211_ap_settings *params)
2289{
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302290 hdd_adapter_t *pAdapter;
2291 hdd_context_t *pHddCtx;
2292 int status = 0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002293
2294 ENTER();
2295
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302296 if (NULL == dev)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07002297 {
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302298 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
2299 "%s: Device is Null", __func__);
2300 return -ENODEV;
2301 }
2302
2303 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2304 if (NULL == pAdapter)
2305 {
2306 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
2307 "%s: HDD adapter is Null", __func__);
2308 return -ENODEV;
2309 }
2310
2311 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
2312 {
2313 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
2314 "%s: HDD adapter magic is invalid", __func__);
2315 return -ENODEV;
2316 }
2317
2318 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2319 if (NULL == pHddCtx)
2320 {
2321 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
2322 "%s: HDD context is Null", __func__);
2323 return -ENODEV;
2324 }
2325
2326 if (pHddCtx->isLogpInProgress)
2327 {
2328 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
2329 "%s: LOGP in Progress. Ignore!!!", __func__);
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07002330 return -EAGAIN;
2331 }
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302332
2333 if (pHddCtx->isLoadUnloadInProgress)
2334 {
2335 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
2336 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
2337 return -EAGAIN;
2338 }
2339
2340 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device mode = %d",
2341 __func__, pAdapter->device_mode);
2342
2343 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002344 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002345 )
2346 {
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302347 beacon_data_t *old, *new;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002348
2349 old = pAdapter->sessionCtx.ap.beacon;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302350
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002351 if (old)
2352 return -EALREADY;
2353
2354 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter, &new, &params->beacon, params->dtim_period);
2355
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302356 if (status != 0)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002357 {
2358 hddLog(VOS_TRACE_LEVEL_FATAL,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302359 "%s:Error!!! Allocating the new beacon", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002360 return -EINVAL;
2361 }
2362 pAdapter->sessionCtx.ap.beacon = new;
Viral Modi3a32cc52013-02-08 11:14:52 -08002363#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
2364 wlan_hdd_cfg80211_set_channel(wiphy, dev, params->channel, params->channel_type);
2365#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002366 status = wlan_hdd_cfg80211_start_bss(pAdapter, &params->beacon, params->ssid,
2367 params->ssid_len, params->hidden_ssid);
2368 }
2369
2370 EXIT();
2371 return status;
2372}
2373
2374
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302375static int wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002376 struct net_device *dev,
2377 struct cfg80211_beacon_data *params)
2378{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302379 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002380 int status=VOS_STATUS_SUCCESS;
2381
2382 ENTER();
2383
2384 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",
2385 __func__, pAdapter->device_mode);
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07002386 if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress)
2387 {
2388 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:LOGP in Progress. Ignore!!!",__func__);
2389 return -EAGAIN;
2390 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002391
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302392 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002393 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302394 )
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002395 {
2396 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302397
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002398 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302399
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002400 if (!old)
2401 return -ENOENT;
2402
2403 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter, &new, params, 0);
2404
2405 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302406 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002407 "%s: Error!!! Allocating the new beacon\n",__func__);
2408 return -EINVAL;
2409 }
2410
2411 pAdapter->sessionCtx.ap.beacon = new;
2412
2413 status = wlan_hdd_cfg80211_start_bss(pAdapter, params, NULL, 0, 0);
2414 }
2415
2416 EXIT();
2417 return status;
2418}
2419
2420#endif //(LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
2421
Jeff Johnson295189b2012-06-20 16:38:30 -07002422
2423static int wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
2424 struct net_device *dev,
2425 struct bss_parameters *params)
2426{
2427 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2428
2429 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302430
Jeff Johnson295189b2012-06-20 16:38:30 -07002431 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",
2432 __func__,pAdapter->device_mode);
2433
2434 if((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07002435 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302436 )
Jeff Johnson295189b2012-06-20 16:38:30 -07002437 {
2438 /* ap_isolate == -1 means that in change bss, upper layer doesn't
2439 * want to update this parameter */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302440 if (-1 != params->ap_isolate)
Jeff Johnson295189b2012-06-20 16:38:30 -07002441 {
2442 pAdapter->sessionCtx.ap.apDisableIntraBssFwd = !!params->ap_isolate;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302443 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002444 }
2445
2446 EXIT();
2447 return 0;
2448}
2449
2450/*
2451 * FUNCTION: wlan_hdd_cfg80211_change_iface
2452 * This function is used to set the interface type (INFRASTRUCTURE/ADHOC)
2453 */
2454int wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
2455 struct net_device *ndev,
2456 enum nl80211_iftype type,
2457 u32 *flags,
2458 struct vif_params *params
2459 )
2460{
2461 struct wireless_dev *wdev;
2462 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
2463 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
Mohit Khanna0f232092012-09-11 14:46:08 -07002464 hdd_adapter_t *pP2pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07002465 tCsrRoamProfile *pRoamProfile = NULL;
2466 eCsrRoamBssType LastBSSType;
2467 hdd_config_t *pConfig = pHddCtx->cfg_ini;
2468 eMib_dot11DesiredBssType connectedBssType;
2469 VOS_STATUS status;
2470
2471 ENTER();
2472
2473 if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress)
2474 {
2475 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:LOGP in Progress. Ignore!!!",__func__);
2476 return -EAGAIN;
2477 }
2478
2479 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
2480 __func__, pAdapter->device_mode);
2481
2482 wdev = ndev->ieee80211_ptr;
2483
2484#ifdef WLAN_BTAMP_FEATURE
2485 if((NL80211_IFTYPE_P2P_CLIENT == type)||
2486 (NL80211_IFTYPE_ADHOC == type)||
2487 (NL80211_IFTYPE_AP == type)||
2488 (NL80211_IFTYPE_P2P_GO == type))
2489 {
2490 pHddCtx->isAmpAllowed = VOS_FALSE;
2491 // stop AMP traffic
2492 status = WLANBAP_StopAmp();
2493 if(VOS_STATUS_SUCCESS != status )
2494 {
2495 pHddCtx->isAmpAllowed = VOS_TRUE;
2496 hddLog(VOS_TRACE_LEVEL_FATAL,
2497 "%s: Failed to stop AMP", __func__);
2498 return -EINVAL;
2499 }
2500 }
2501#endif //WLAN_BTAMP_FEATURE
2502 /* Reset the current device mode bit mask*/
2503 wlan_hdd_clear_concurrency_mode(pHddCtx, pAdapter->device_mode);
2504
2505 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -07002506 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnsone7245742012-09-05 17:12:55 -07002507 || (pAdapter->device_mode == WLAN_HDD_P2P_DEVICE)
Jeff Johnson295189b2012-06-20 16:38:30 -07002508 )
2509 {
2510 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
2511 pRoamProfile = &pWextState->roamProfile;
2512 LastBSSType = pRoamProfile->BSSType;
2513
2514 switch (type)
2515 {
2516 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -07002517 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -07002518 hddLog(VOS_TRACE_LEVEL_INFO,
2519 "%s: setting interface Type to INFRASTRUCTURE", __func__);
2520 pRoamProfile->BSSType = eCSR_BSS_TYPE_INFRASTRUCTURE;
Jeff Johnsone7245742012-09-05 17:12:55 -07002521#ifdef WLAN_FEATURE_11AC
2522 if(pConfig->dot11Mode == eHDD_DOT11_MODE_AUTO)
2523 {
2524 pConfig->dot11Mode = eHDD_DOT11_MODE_11ac;
2525 }
2526#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302527 pRoamProfile->phyMode =
Jeff Johnsone7245742012-09-05 17:12:55 -07002528 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07002529 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08002530 //Check for sub-string p2p to confirm its a p2p interface
2531 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302532 {
Gopichand Nakkala864d3552012-12-31 16:08:51 -08002533 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
2534 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
2535 }
2536 else
2537 {
2538 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -07002539 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -08002540 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002541 break;
2542 case NL80211_IFTYPE_ADHOC:
2543 hddLog(VOS_TRACE_LEVEL_INFO,
2544 "%s: setting interface Type to ADHOC", __func__);
2545 pRoamProfile->BSSType = eCSR_BSS_TYPE_START_IBSS;
2546 pRoamProfile->phyMode =
2547 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
2548 wdev->iftype = type;
2549 break;
2550
2551 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -07002552 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07002553 {
2554 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
2555 "%s: setting interface Type to %s", __func__,
2556 (type == NL80211_IFTYPE_AP) ? "SoftAP" : "P2pGo");
2557
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08002558 //Cancel any remain on channel for GO mode
2559 if (NL80211_IFTYPE_P2P_GO == type)
2560 {
2561 wlan_hdd_cancel_existing_remain_on_channel(pAdapter);
2562 }
Mohit Khanna0f232092012-09-11 14:46:08 -07002563 if (NL80211_IFTYPE_AP == type)
2564 {
2565 /* As Loading WLAN Driver one interface being created for p2p device
2566 * address. This will take one HW STA and the max number of clients
2567 * that can connect to softAP will be reduced by one. so while changing
2568 * the interface type to NL80211_IFTYPE_AP (SoftAP) remove p2p0
2569 * interface as it is not required in SoftAP mode.
2570 */
2571
2572 // Get P2P Adapter
2573 pP2pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_DEVICE);
2574
2575 if (pP2pAdapter)
2576 {
2577 hdd_stop_adapter(pHddCtx, pP2pAdapter);
2578 hdd_deinit_adapter(pHddCtx, pP2pAdapter);
2579 hdd_close_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
2580 }
2581 }
2582
Jeff Johnson295189b2012-06-20 16:38:30 -07002583 //De-init the adapter.
2584 hdd_stop_adapter( pHddCtx, pAdapter );
2585 hdd_deinit_adapter( pHddCtx, pAdapter );
2586 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
Jeff Johnson295189b2012-06-20 16:38:30 -07002587 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
2588 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Jeff Johnson32d95a32012-09-10 13:15:23 -07002589
2590 //Disable BMPS and IMPS if enabled
2591 //before starting Go
2592 if(WLAN_HDD_P2P_GO == pAdapter->device_mode)
2593 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302594 if(VOS_STATUS_E_FAILURE ==
Jeff Johnson32d95a32012-09-10 13:15:23 -07002595 hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_P2P_GO))
2596 {
2597 //Fail to Exit BMPS
2598 VOS_ASSERT(0);
2599 }
2600 }
2601
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -07002602 if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) &&
2603 (pConfig->apRandomBssidEnabled))
2604 {
2605 /* To meet Android requirements create a randomized
2606 MAC address of the form 02:1A:11:Fx:xx:xx */
2607 get_random_bytes(&ndev->dev_addr[3], 3);
2608 ndev->dev_addr[0] = 0x02;
2609 ndev->dev_addr[1] = 0x1A;
2610 ndev->dev_addr[2] = 0x11;
2611 ndev->dev_addr[3] |= 0xF0;
2612 memcpy(pAdapter->macAddressCurrent.bytes, ndev->dev_addr,
2613 VOS_MAC_ADDR_SIZE);
2614 pr_info("wlan: Generated HotSpot BSSID "
2615 "%02x:%02x:%02x:%02x:%02x:%02x\n",
2616 ndev->dev_addr[0],
2617 ndev->dev_addr[1],
2618 ndev->dev_addr[2],
2619 ndev->dev_addr[3],
2620 ndev->dev_addr[4],
2621 ndev->dev_addr[5]);
2622 }
2623
Jeff Johnson295189b2012-06-20 16:38:30 -07002624 hdd_set_ap_ops( pAdapter->dev );
2625
2626 status = hdd_init_ap_mode(pAdapter);
2627 if(status != VOS_STATUS_SUCCESS)
2628 {
2629 hddLog(VOS_TRACE_LEVEL_FATAL,
2630 "%s: Error initializing the ap mode", __func__);
2631 return -EINVAL;
2632 }
2633 hdd_set_conparam(1);
2634
Jeff Johnson295189b2012-06-20 16:38:30 -07002635 /*interface type changed update in wiphy structure*/
2636 if(wdev)
2637 {
2638 wdev->iftype = type;
2639 pHddCtx->change_iface = type;
2640 }
2641 else
2642 {
2643 hddLog(VOS_TRACE_LEVEL_ERROR,
2644 "%s: ERROR !!!! Wireless dev is NULL", __func__);
2645 return -EINVAL;
2646 }
2647 goto done;
2648 }
2649
2650 default:
2651 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
2652 __func__);
2653 return -EOPNOTSUPP;
2654 }
2655 }
2656 else if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07002657 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07002658 )
2659 {
2660 switch(type)
2661 {
2662 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -07002663 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -07002664 case NL80211_IFTYPE_ADHOC:
Jeff Johnson32d95a32012-09-10 13:15:23 -07002665 hdd_stop_adapter( pHddCtx, pAdapter );
2666 hdd_deinit_adapter( pHddCtx, pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07002667 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08002668 //Check for sub-string p2p to confirm its a p2p interface
2669 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala864d3552012-12-31 16:08:51 -08002670 {
2671 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
2672 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
2673 }
2674 else
2675 {
2676 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -07002677 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -08002678 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002679 hdd_set_conparam(0);
2680 pHddCtx->change_iface = type;
Jeff Johnson295189b2012-06-20 16:38:30 -07002681 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
2682 hdd_set_station_ops( pAdapter->dev );
2683 status = hdd_init_station_mode( pAdapter );
2684 if( VOS_STATUS_SUCCESS != status )
2685 return -EOPNOTSUPP;
Jeff Johnsone7245742012-09-05 17:12:55 -07002686 /* In case of JB, for P2P-GO, only change interface will be called,
2687 * This is the right place to enable back bmps_imps()
2688 */
2689 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07002690 goto done;
2691 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -07002692 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07002693 wdev->iftype = type;
Jeff Johnson295189b2012-06-20 16:38:30 -07002694 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
2695 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Jeff Johnson295189b2012-06-20 16:38:30 -07002696 goto done;
2697 default:
2698 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
2699 __func__);
2700 return -EOPNOTSUPP;
2701
2702 }
2703
2704 }
2705 else
2706 {
2707 return -EOPNOTSUPP;
2708 }
2709
2710
2711 if(pRoamProfile)
2712 {
2713 if ( LastBSSType != pRoamProfile->BSSType )
2714 {
2715 /*interface type changed update in wiphy structure*/
2716 wdev->iftype = type;
2717
2718 /*the BSS mode changed, We need to issue disconnect
2719 if connected or in IBSS disconnect state*/
2720 if ( hdd_connGetConnectedBssType(
2721 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), &connectedBssType ) ||
2722 ( eCSR_BSS_TYPE_START_IBSS == LastBSSType ) )
2723 {
2724 /*need to issue a disconnect to CSR.*/
2725 INIT_COMPLETION(pAdapter->disconnect_comp_var);
2726 if( eHAL_STATUS_SUCCESS ==
2727 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
2728 pAdapter->sessionId,
2729 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
2730 {
2731 wait_for_completion_interruptible_timeout(
2732 &pAdapter->disconnect_comp_var,
2733 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
2734 }
2735 }
2736 }
2737 }
2738
2739done:
2740 /*set bitmask based on updated value*/
2741 wlan_hdd_set_concurrency_mode(pHddCtx, pAdapter->device_mode);
2742#ifdef WLAN_BTAMP_FEATURE
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302743 if((NL80211_IFTYPE_STATION == type) && (pHddCtx->concurrency_mode <= 1) &&
Jeff Johnson295189b2012-06-20 16:38:30 -07002744 (pHddCtx->no_of_sessions[WLAN_HDD_INFRA_STATION] <=1))
2745 {
2746 //we are ok to do AMP
2747 pHddCtx->isAmpAllowed = VOS_TRUE;
2748 }
2749#endif //WLAN_BTAMP_FEATURE
2750 EXIT();
2751 return 0;
2752}
2753
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002754#ifdef FEATURE_WLAN_TDLS
2755static int wlan_hdd_tdls_add_station(struct wiphy *wiphy,
2756 struct net_device *dev, u8 *mac, bool update, tCsrStaParams *StaParams)
2757{
2758 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2759 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
2760 VOS_STATUS status;
2761
2762 ENTER();
2763
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05302764 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002765 {
2766 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2767 "Invalid arguments");
2768 return -EINVAL;
2769 }
Hoonki Lee27511902013-03-14 18:19:06 -07002770
2771 if ((eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode) ||
2772 (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode))
2773 {
2774 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2775 "%s: TDLS mode is disabled OR not enabled in FW."
2776 MAC_ADDRESS_STR " Request declined.",
2777 __func__, MAC_ADDR_ARRAY(mac));
2778 return -ENOTSUPP;
2779 }
2780
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002781 if (pHddCtx->isLogpInProgress)
2782 {
2783 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2784 "%s:LOGP in Progress. Ignore!!!", __func__);
Gopichand Nakkala05922802013-03-14 12:23:19 -07002785 wlan_hdd_tdls_set_link_status(pAdapter, mac, eTDLS_LINK_IDLE);
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002786 return -EBUSY;
2787 }
2788
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07002789 /* when self is on-going, we dont' want to change link_status */
2790 if ((0 == update) && wlan_hdd_tdls_is_peer_progress(pAdapter, mac))
2791 {
2792 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2793 "%s: " MAC_ADDRESS_STR
2794 " TDLS setup is ongoing. Request declined.",
2795 __func__, MAC_ADDR_ARRAY(mac));
2796 return -EPERM;
2797 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07002798 /* when self is not on-ongoing, we don't want to allow change_station */
2799 if ((1 == update) && !wlan_hdd_tdls_is_peer_progress(pAdapter, mac))
2800 {
2801 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2802 "%s: " MAC_ADDRESS_STR
2803 " TDLS is not connecting. change station declined.",
2804 __func__, MAC_ADDR_ARRAY(mac));
2805 return -EPERM;
2806 }
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07002807
2808 /* when others are on-going, we want to change link_status to idle */
Hoonki Leefb8df672013-04-10 18:20:34 -07002809 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, mac, TRUE, TRUE))
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002810 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07002811 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2812 "%s: " MAC_ADDRESS_STR
2813 " TDLS setup is ongoing. Request declined.",
2814 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala05922802013-03-14 12:23:19 -07002815 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002816 }
2817
2818 /* first to check if we reached to maximum supported TDLS peer.
2819 TODO: for now, return -EPERM looks working fine,
2820 but need to check if any other errno fit into this category.*/
2821 if (HDD_MAX_NUM_TDLS_STA <= wlan_hdd_tdlsConnectedPeers(pAdapter))
2822 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07002823 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2824 "%s: " MAC_ADDRESS_STR
2825 " TDLS Max peer already connected. Request declined.",
2826 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala05922802013-03-14 12:23:19 -07002827 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002828 }
2829 else
2830 {
2831 hddTdlsPeer_t *pTdlsPeer;
2832 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, mac);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07002833 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002834 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07002835 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2836 "%s: " MAC_ADDRESS_STR " already connected. Request declined.",
2837 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002838 return -EPERM;
2839 }
2840 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07002841 if (0 == update)
2842 wlan_hdd_tdls_set_link_status(pAdapter, mac, eTDLS_LINK_CONNECTING);
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002843
Jeff Johnsond75fe012013-04-06 10:53:06 -07002844 /* debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05302845 if (NULL != StaParams)
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07002846 {
2847 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2848 "%s: TDLS Peer Parameters.", __func__);
Hoonki Lee66b75f32013-04-16 18:30:07 -07002849 if(StaParams->htcap_present)
2850 {
2851 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2852 "ht_capa->cap_info: %0x", StaParams->HTCap.capInfo);
2853 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2854 "ht_capa->extended_capabilities: %0x",
2855 StaParams->HTCap.extendedHtCapInfo);
2856 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07002857 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2858 "params->capability: %0x",StaParams->capability);
2859 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2860 "params->ext_capab_len: %0x",StaParams->extn_capability);
Hoonki Lee66b75f32013-04-16 18:30:07 -07002861 if(StaParams->vhtcap_present)
2862 {
2863 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2864 "rxMcsMap %x rxHighest %x txMcsMap %x txHighest %x",
2865 StaParams->VHTCap.suppMcs.rxMcsMap, StaParams->VHTCap.suppMcs.rxHighest,
2866 StaParams->VHTCap.suppMcs.txMcsMap, StaParams->VHTCap.suppMcs.txHighest);
2867 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07002868 {
2869 int i = 0;
2870 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL, "Supported rates:");
2871 for (i = 0; i < sizeof(StaParams->supported_rates); i++)
2872 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2873 "[%d]: %x ", i, StaParams->supported_rates[i]);
2874 }
Jeff Johnsond75fe012013-04-06 10:53:06 -07002875 } /* end debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05302876 else if ((1 == update) && (NULL == StaParams))
2877 {
2878 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2879 "%s : update is true, but staParams is NULL. Error!", __func__);
2880 return -EPERM;
2881 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002882
2883 INIT_COMPLETION(pAdapter->tdls_add_station_comp);
2884
2885 if (!update)
2886 {
2887 status = sme_AddTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
2888 pAdapter->sessionId, mac);
2889 }
2890 else
2891 {
2892 status = sme_ChangeTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
2893 pAdapter->sessionId, mac, StaParams);
2894 }
2895
2896 status = wait_for_completion_interruptible_timeout(&pAdapter->tdls_add_station_comp,
2897 msecs_to_jiffies(WAIT_TIME_TDLS_ADD_STA));
2898
2899 if (!status)
2900 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07002901 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002902 "%s: timeout waiting for tdls add station indication",
2903 __func__);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07002904 return -EPERM;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002905 }
2906 if ( eHAL_STATUS_SUCCESS != pAdapter->tdlsAddStaStatus)
2907 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07002908 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002909 "%s: Add Station is unsucessful", __func__);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07002910 return -EPERM;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002911 }
2912
2913 return 0;
Gopichand Nakkala05922802013-03-14 12:23:19 -07002914
2915error:
2916 wlan_hdd_tdls_set_link_status(pAdapter, mac, eTDLS_LINK_IDLE);
2917 return -EPERM;
2918
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002919}
2920#endif
2921
Jeff Johnson295189b2012-06-20 16:38:30 -07002922static int wlan_hdd_change_station(struct wiphy *wiphy,
2923 struct net_device *dev,
2924 u8 *mac,
2925 struct station_parameters *params)
2926{
2927 VOS_STATUS status = VOS_STATUS_SUCCESS;
2928 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
2929 v_MACADDR_t STAMacAddress;
Gopichand Nakkalab0856222013-03-12 22:39:05 -07002930#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002931 tCsrStaParams StaParams = {0};
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002932 tANI_U8 isBufSta = 0;
Gopichand Nakkalab0856222013-03-12 22:39:05 -07002933#endif
Jeff Johnsone7245742012-09-05 17:12:55 -07002934 ENTER();
2935
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002936 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
2937 {
2938 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2939 "%s:LOGP in Progress. Ignore!!!", __func__);
2940 return -EAGAIN;
2941 }
2942
Jeff Johnson295189b2012-06-20 16:38:30 -07002943 vos_mem_copy(STAMacAddress.bytes, mac, sizeof(v_MACADDR_t));
2944
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002945 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
2946 || (pAdapter->device_mode == WLAN_HDD_P2P_GO))
Jeff Johnson295189b2012-06-20 16:38:30 -07002947 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002948 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED))
Jeff Johnson295189b2012-06-20 16:38:30 -07002949 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302950 status = hdd_softap_change_STA_state( pAdapter, &STAMacAddress,
Jeff Johnson295189b2012-06-20 16:38:30 -07002951 WLANTL_STA_AUTHENTICATED);
2952
2953 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002954 "%s: Station MAC address does not matching", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002955 return -EINVAL;
2956 }
2957 }
Gopichand Nakkalab0856222013-03-12 22:39:05 -07002958#ifdef FEATURE_WLAN_TDLS
Hoonki Leea6d49be2013-04-05 09:43:25 -07002959 else if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
2960 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)) {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07002961 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
2962 StaParams.capability = params->capability;
2963 StaParams.uapsd_queues = params->uapsd_queues;
2964 StaParams.max_sp = params->max_sp;
2965
2966 if (0 != params->ext_capab_len)
2967 vos_mem_copy(StaParams.extn_capability, params->ext_capab,
2968 sizeof(StaParams.extn_capability));
2969
2970 if (NULL != params->ht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -07002971 {
2972 StaParams.htcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07002973 vos_mem_copy(&StaParams.HTCap, params->ht_capa, sizeof(tSirHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -07002974 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07002975
2976 StaParams.supported_rates_len = params->supported_rates_len;
2977
2978 /* Note : The Maximum sizeof supported_rates sent by the Supplicant is 32.
2979 * The supported_rates array , for all the structures propogating till Add Sta
2980 * to the firmware has to be modified , if the supplicant (ieee80211) is
2981 * modified to send more rates.
2982 */
2983
2984 /* To avoid Data Currption , set to max length to SIR_MAC_MAX_SUPP_RATES
2985 */
2986 if (StaParams.supported_rates_len > SIR_MAC_MAX_SUPP_RATES)
2987 StaParams.supported_rates_len = SIR_MAC_MAX_SUPP_RATES;
2988
2989 if (0 != StaParams.supported_rates_len) {
2990 int i = 0;
2991 vos_mem_copy(StaParams.supported_rates, params->supported_rates,
2992 StaParams.supported_rates_len);
2993 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2994 "Supported Rates with Length %d", StaParams.supported_rates_len);
2995 for (i=0; i < StaParams.supported_rates_len; i++)
2996 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2997 "[%d]: %0x", i, StaParams.supported_rates[i]);
2998 }
2999
3000 if (NULL != params->vht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -07003001 {
3002 StaParams.vhtcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003003 vos_mem_copy(&StaParams.VHTCap, params->vht_capa, sizeof(tSirVHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -07003004 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003005
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003006 if (0 != params->ext_capab_len ) {
3007 /*Define A Macro : TODO Sunil*/
3008 if ((1<<4) & StaParams.extn_capability[3]) {
3009 isBufSta = 1;
3010 }
3011 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003012 //status = wlan_hdd_tdls_set_peer_caps( mac, params->uapsd_queues,
3013 // params->max_sp, isBufSta);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003014 //if (VOS_STATUS_SUCCESS != status) {
3015 // VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3016 // "%s: wlan_hdd_tdls_set_peer_caps failed!", __func__);
3017 // return -EINVAL;
3018 //}
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003019 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 1, &StaParams);
3020
3021 if (VOS_STATUS_SUCCESS != status) {
3022 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3023 "%s: sme_ChangeTdlsPeerSta failed!", __func__);
3024 return -EINVAL;
3025 }
3026 }
3027 }
Gopichand Nakkalab0856222013-03-12 22:39:05 -07003028#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303029
Jeff Johnsone7245742012-09-05 17:12:55 -07003030 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07003031 return status;
3032}
3033
3034/*
3035 * FUNCTION: wlan_hdd_cfg80211_get_ibss_peer_staidx
3036 * This function is used to get peer station index in IBSS mode
3037 */
3038static u8 wlan_hdd_cfg80211_get_ibss_peer_staidx(hdd_adapter_t* pAdapter)
3039{
3040 u8 idx = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303041 u8 temp[VOS_MAC_ADDR_SIZE] = {0};
Jeff Johnson295189b2012-06-20 16:38:30 -07003042 ENTER();
3043 memset(temp, 0, VOS_MAC_ADDR_SIZE);
3044 for ( idx = 0; idx < HDD_MAX_NUM_IBSS_STA; idx++ )
3045 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303046 if ( (0 !=
3047 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.staId[idx])
Jeff Johnson295189b2012-06-20 16:38:30 -07003048 && memcmp((u8*)&(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.peerMacAddress[idx],
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303049 temp, VOS_MAC_ADDR_SIZE)
Jeff Johnson295189b2012-06-20 16:38:30 -07003050 )
3051 {
3052 return idx;
3053 }
3054 }
3055 return idx;
3056}
3057
3058
3059/*
3060 * FUNCTION: wlan_hdd_cfg80211_add_key
3061 * This function is used to initialize the key information
3062 */
3063#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003064static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07003065 struct net_device *ndev,
3066 u8 key_index, bool pairwise,
3067 const u8 *mac_addr,
3068 struct key_params *params
3069 )
3070#else
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003071static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07003072 struct net_device *ndev,
3073 u8 key_index, const u8 *mac_addr,
3074 struct key_params *params
3075 )
3076#endif
3077{
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003078 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -07003079 tCsrRoamSetKey setKey;
3080 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
3081 int status = 0;
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003082 v_U32_t roamId= 0xFF;
3083 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07003084 hdd_hostapd_state_t *pHostapdState;
3085 VOS_STATUS vos_status;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07003086 eHalStatus halStatus;
Jeff Johnson295189b2012-06-20 16:38:30 -07003087
3088 ENTER();
3089
Jeff Johnson04dd8a82012-06-29 20:41:40 -07003090 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
3091 {
3092 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3093 "%s:LOGP in Progress. Ignore!!!", __func__);
3094 return -EAGAIN;
3095 }
3096
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003097 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
3098 __func__, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07003099
3100 if (CSR_MAX_NUM_KEY <= key_index)
3101 {
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003102 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07003103 key_index);
3104
3105 return -EINVAL;
3106 }
3107
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003108 if (CSR_MAX_KEY_LEN < params->key_len)
3109 {
3110 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key length %d", __func__,
3111 params->key_len);
3112
3113 return -EINVAL;
3114 }
3115
3116 hddLog(VOS_TRACE_LEVEL_INFO,
3117 "%s: called with key index = %d & key length %d",
3118 __func__, key_index, params->key_len);
Jeff Johnson295189b2012-06-20 16:38:30 -07003119
3120 /*extract key idx, key len and key*/
3121 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
3122 setKey.keyId = key_index;
3123 setKey.keyLength = params->key_len;
3124 vos_mem_copy(&setKey.Key[0],params->key, params->key_len);
3125
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003126 switch (params->cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -07003127 {
3128 case WLAN_CIPHER_SUITE_WEP40:
3129 setKey.encType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
3130 break;
3131
3132 case WLAN_CIPHER_SUITE_WEP104:
3133 setKey.encType = eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
3134 break;
3135
3136 case WLAN_CIPHER_SUITE_TKIP:
3137 {
3138 u8 *pKey = &setKey.Key[0];
3139 setKey.encType = eCSR_ENCRYPT_TYPE_TKIP;
3140
3141 vos_mem_zero(pKey, CSR_MAX_KEY_LEN);
3142
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003143 /*Supplicant sends the 32bytes key in this order
Jeff Johnson295189b2012-06-20 16:38:30 -07003144
3145 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003146 | Tk1 |TX-MIC | RX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -07003147 |--------------|----------|----------|
3148 <---16bytes---><--8bytes--><--8bytes-->
3149
3150 */
3151 /*Sme expects the 32 bytes key to be in the below order
3152
3153 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003154 | Tk1 |RX-MIC | TX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -07003155 |--------------|----------|----------|
3156 <---16bytes---><--8bytes--><--8bytes-->
3157 */
3158 /* Copy the Temporal Key 1 (TK1) */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003159 vos_mem_copy(pKey, params->key, 16);
Jeff Johnson295189b2012-06-20 16:38:30 -07003160
3161 /*Copy the rx mic first*/
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003162 vos_mem_copy(&pKey[16], &params->key[24], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -07003163
3164 /*Copy the tx mic */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003165 vos_mem_copy(&pKey[24], &params->key[16], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -07003166
3167
3168 break;
3169 }
3170
3171 case WLAN_CIPHER_SUITE_CCMP:
3172 setKey.encType = eCSR_ENCRYPT_TYPE_AES;
3173 break;
3174
3175#ifdef FEATURE_WLAN_WAPI
3176 case WLAN_CIPHER_SUITE_SMS4:
3177 {
3178 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
3179 wlan_hdd_cfg80211_set_key_wapi(pAdapter, key_index, mac_addr,
3180 params->key, params->key_len);
3181 return 0;
3182 }
3183#endif
Chet Lanctot186b5732013-03-18 10:26:30 -07003184
Jeff Johnson295189b2012-06-20 16:38:30 -07003185#ifdef FEATURE_WLAN_CCX
3186 case WLAN_CIPHER_SUITE_KRK:
3187 setKey.encType = eCSR_ENCRYPT_TYPE_KRK;
3188 break;
3189#endif
Chet Lanctot186b5732013-03-18 10:26:30 -07003190
3191#ifdef WLAN_FEATURE_11W
3192 case WLAN_CIPHER_SUITE_AES_CMAC:
3193 setKey.encType = eCSR_ENCRYPT_TYPE_AES_CMAC;
Chet Lanctot3b5158a2013-03-31 16:45:21 -07003194 break;
Chet Lanctot186b5732013-03-18 10:26:30 -07003195#endif
3196
Jeff Johnson295189b2012-06-20 16:38:30 -07003197 default:
3198 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unsupported cipher type %lu",
3199 __func__, params->cipher);
3200 return -EOPNOTSUPP;
3201 }
3202
3203 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: encryption type %d",
3204 __func__, setKey.encType);
3205
3206
3207
3208 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07003209 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07003210 )
3211 {
3212
3213
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003214 if (
Jeff Johnson295189b2012-06-20 16:38:30 -07003215#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
3216 (!pairwise)
3217#else
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003218 (!mac_addr || is_broadcast_ether_addr(mac_addr))
Jeff Johnson295189b2012-06-20 16:38:30 -07003219#endif
3220 )
3221 {
3222 /* set group key*/
3223 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnson1250df42012-12-10 14:31:52 -08003224 "%s- %d: setting Broadcast key",
Jeff Johnson295189b2012-06-20 16:38:30 -07003225 __func__, __LINE__);
3226 setKey.keyDirection = eSIR_RX_ONLY;
3227 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
3228 }
3229 else
3230 {
3231 /* set pairwise key*/
3232 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3233 "%s- %d: setting pairwise key",
3234 __func__, __LINE__);
3235 setKey.keyDirection = eSIR_TX_RX;
3236 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
3237 }
3238
3239 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003240 if( pHostapdState->bssState == BSS_START )
3241 {
Jeff Johnson295189b2012-06-20 16:38:30 -07003242 status = WLANSAP_SetKeySta( pVosContext, &setKey);
3243
3244 if ( status != eHAL_STATUS_SUCCESS )
3245 {
3246 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3247 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
3248 __LINE__, status );
3249 }
3250 }
3251
3252 /* Saving WEP keys */
3253 else if( eCSR_ENCRYPT_TYPE_WEP40_STATICKEY == setKey.encType ||
3254 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY == setKey.encType )
3255 {
3256 //Save the wep key in ap context. Issue setkey after the BSS is started.
3257 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
3258 vos_mem_copy(&pAPCtx->wepKey[key_index], &setKey, sizeof(tCsrRoamSetKey));
3259 }
3260 else
3261 {
3262 //Save the key in ap context. Issue setkey after the BSS is started.
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003263 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07003264 vos_mem_copy(&pAPCtx->groupKey, &setKey, sizeof(tCsrRoamSetKey));
3265 }
3266 }
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003267 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION) ||
3268 (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT) )
Jeff Johnson295189b2012-06-20 16:38:30 -07003269 {
3270 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
3271 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3272
3273 pWextState->roamProfile.Keys.KeyLength[key_index] = (u8)params->key_len;
3274
Venkata Prathyusha Kuntupalliee2ce712013-01-17 14:09:24 -08003275 pWextState->roamProfile.Keys.defaultIndex = key_index;
3276
3277
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003278 vos_mem_copy(&pWextState->roamProfile.Keys.KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -07003279 params->key, params->key_len);
3280
3281 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
3282
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303283 if (!( ( IW_AUTH_KEY_MGMT_802_1X
3284 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X))
Jeff Johnson295189b2012-06-20 16:38:30 -07003285 && (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType)
3286 )
3287 &&
3288 ( (WLAN_CIPHER_SUITE_WEP40 == params->cipher)
3289 || (WLAN_CIPHER_SUITE_WEP104 == params->cipher)
3290 )
3291 )
3292 {
3293 /* in case of static WEP, macaddr/bssid is not coming from nl80211
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303294 * interface, copy bssid for pairwise key and group macaddr for
Jeff Johnson295189b2012-06-20 16:38:30 -07003295 * group key initialization*/
3296
3297 tCsrRoamProfile *pRoamProfile = &pWextState->roamProfile;
3298
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303299 pWextState->roamProfile.negotiatedUCEncryptionType =
3300 pHddStaCtx->conn_info.ucEncryptionType =
Jeff Johnson295189b2012-06-20 16:38:30 -07003301 ((WLAN_CIPHER_SUITE_WEP40 == params->cipher) ?
3302 eCSR_ENCRYPT_TYPE_WEP40_STATICKEY :
3303 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY);
3304
3305
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303306 hddLog(VOS_TRACE_LEVEL_INFO_MED,
3307 "%s: Negotiated encryption type %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07003308 pWextState->roamProfile.negotiatedUCEncryptionType);
3309
3310 sme_SetCfgPrivacy((tpAniSirGlobal)WLAN_HDD_GET_HAL_CTX(pAdapter),
3311 &pWextState->roamProfile, true);
3312 setKey.keyLength = 0;
3313 setKey.keyDirection = eSIR_TX_RX;
3314
3315#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303316 if (pairwise)
Jeff Johnson295189b2012-06-20 16:38:30 -07003317 {
3318#endif
3319 if (mac_addr)
3320 {
3321 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
3322 }
3323 else
3324 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303325 /* macaddr is NULL, set the peerMac to bssId in case of BSS,
Jeff Johnson295189b2012-06-20 16:38:30 -07003326 * and peerMacAddress in case of IBSS*/
3327 if (eCSR_BSS_TYPE_START_IBSS == pRoamProfile->BSSType)
3328 {
3329 u8 staidx = wlan_hdd_cfg80211_get_ibss_peer_staidx(pAdapter);
3330 if (HDD_MAX_NUM_IBSS_STA != staidx)
3331 {
3332 vos_mem_copy(setKey.peerMac,
3333 &pHddStaCtx->conn_info.peerMacAddress[staidx],
3334 WNI_CFG_BSSID_LEN);
3335
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303336 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003337 else
3338 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303339 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No peerMac found",
Jeff Johnson295189b2012-06-20 16:38:30 -07003340 __func__);
3341 return -EOPNOTSUPP;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303342 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003343 }
3344 else
3345 {
3346 vos_mem_copy(setKey.peerMac,
3347 &pHddStaCtx->conn_info.bssId[0],
3348 WNI_CFG_BSSID_LEN);
3349 }
3350 }
3351#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
3352 }
3353 else
3354 {
3355 /* set group key*/
3356 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3357 "%s- %d: setting Group key",
3358 __func__, __LINE__);
3359 setKey.keyDirection = eSIR_RX_ONLY;
3360 vos_mem_copy(setKey.peerMac, groupmacaddr, WNI_CFG_BSSID_LEN);
3361 }
3362#endif
3363 }
3364 else if (
3365#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
3366 (!pairwise)
3367#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303368 (!mac_addr || is_broadcast_ether_addr(mac_addr))
Jeff Johnson295189b2012-06-20 16:38:30 -07003369#endif
3370 )
3371 {
3372 /* set group key*/
3373 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3374 "%s- %d: setting Group key",
3375 __func__, __LINE__);
3376 setKey.keyDirection = eSIR_RX_ONLY;
3377 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
3378 }
3379 else
3380 {
3381 /* set pairwise key*/
3382 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3383 "%s- %d: setting pairwise key",
3384 __func__, __LINE__);
3385 setKey.keyDirection = eSIR_TX_RX;
3386 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
3387 }
3388
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303389 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -07003390 "%s: set key for peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303391 __func__, setKey.peerMac[0], setKey.peerMac[1],
3392 setKey.peerMac[2], setKey.peerMac[3],
3393 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -07003394 setKey.keyDirection);
3395
3396 vos_status = wlan_hdd_check_ula_done(pAdapter);
3397
3398 if ( vos_status != VOS_STATUS_SUCCESS )
3399 {
3400 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3401 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
3402 __LINE__, vos_status );
3403
3404 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
3405
3406 return -EINVAL;
3407
3408 }
3409
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07003410#ifdef WLAN_FEATURE_VOWIFI_11R
3411 /* The supplicant may attempt to set the PTK once pre-authentication is done.
3412 Save the key in the UMAC and include it in the ADD BSS request */
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07003413 halStatus = sme_FTUpdateKey( WLAN_HDD_GET_HAL_CTX(pAdapter), &setKey);
Gopichand Nakkalad7d13652013-02-15 01:48:00 +05303414 if( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_WAIT )
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07003415 {
Gopichand Nakkalad7d13652013-02-15 01:48:00 +05303416 return -EINVAL;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07003417 }
3418#endif /* WLAN_FEATURE_VOWIFI_11R */
Jeff Johnson295189b2012-06-20 16:38:30 -07003419
3420 /* issue set key request to SME*/
3421 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
3422 pAdapter->sessionId, &setKey, &roamId );
3423
3424 if ( 0 != status )
3425 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303426 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07003427 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
3428 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
3429 return -EINVAL;
3430 }
3431
3432
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303433 /* in case of IBSS as there was no information available about WEP keys during
3434 * IBSS join, group key intialized with NULL key, so re-initialize group key
Jeff Johnson295189b2012-06-20 16:38:30 -07003435 * with correct value*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303436 if ( (eCSR_BSS_TYPE_START_IBSS == pWextState->roamProfile.BSSType) &&
3437 !( ( IW_AUTH_KEY_MGMT_802_1X
3438 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X))
Jeff Johnson295189b2012-06-20 16:38:30 -07003439 && (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType)
3440 )
3441 &&
3442 ( (WLAN_CIPHER_SUITE_WEP40 == params->cipher)
3443 || (WLAN_CIPHER_SUITE_WEP104 == params->cipher)
3444 )
3445 )
3446 {
3447 setKey.keyDirection = eSIR_RX_ONLY;
3448 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
3449
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303450 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -07003451 "%s: set key peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303452 __func__, setKey.peerMac[0], setKey.peerMac[1],
3453 setKey.peerMac[2], setKey.peerMac[3],
3454 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -07003455 setKey.keyDirection);
3456
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303457 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07003458 pAdapter->sessionId, &setKey, &roamId );
3459
3460 if ( 0 != status )
3461 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303462 hddLog(VOS_TRACE_LEVEL_ERROR,
3463 "%s: sme_RoamSetKey failed for group key (IBSS), returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07003464 __func__, status);
3465 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
3466 return -EINVAL;
3467 }
3468 }
3469 }
3470
3471 return 0;
3472}
3473
3474/*
3475 * FUNCTION: wlan_hdd_cfg80211_get_key
3476 * This function is used to get the key information
3477 */
3478#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303479static int wlan_hdd_cfg80211_get_key(
3480 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07003481 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303482 u8 key_index, bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -07003483 const u8 *mac_addr, void *cookie,
3484 void (*callback)(void *cookie, struct key_params*)
3485 )
3486#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303487static int wlan_hdd_cfg80211_get_key(
3488 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07003489 struct net_device *ndev,
3490 u8 key_index, const u8 *mac_addr, void *cookie,
3491 void (*callback)(void *cookie, struct key_params*)
3492 )
3493#endif
3494{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303495 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -07003496 hdd_wext_state_t *pWextState= WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
3497 tCsrRoamProfile *pRoamProfile = &(pWextState->roamProfile);
3498 struct key_params params;
3499
3500 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303501
Jeff Johnson295189b2012-06-20 16:38:30 -07003502 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",
3503 __func__,pAdapter->device_mode);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303504
Jeff Johnson295189b2012-06-20 16:38:30 -07003505 memset(&params, 0, sizeof(params));
3506
3507 if (CSR_MAX_NUM_KEY <= key_index)
3508 {
3509 return -EINVAL;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303510 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003511
3512 switch(pRoamProfile->EncryptionType.encryptionType[0])
3513 {
3514 case eCSR_ENCRYPT_TYPE_NONE:
3515 params.cipher = IW_AUTH_CIPHER_NONE;
3516 break;
3517
3518 case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY:
3519 case eCSR_ENCRYPT_TYPE_WEP40:
3520 params.cipher = WLAN_CIPHER_SUITE_WEP40;
3521 break;
3522
3523 case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY:
3524 case eCSR_ENCRYPT_TYPE_WEP104:
3525 params.cipher = WLAN_CIPHER_SUITE_WEP104;
3526 break;
3527
3528 case eCSR_ENCRYPT_TYPE_TKIP:
3529 params.cipher = WLAN_CIPHER_SUITE_TKIP;
3530 break;
3531
3532 case eCSR_ENCRYPT_TYPE_AES:
3533 params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
3534 break;
3535
3536 default:
3537 params.cipher = IW_AUTH_CIPHER_NONE;
3538 break;
3539 }
3540
3541 params.key_len = pRoamProfile->Keys.KeyLength[key_index];
3542 params.seq_len = 0;
3543 params.seq = NULL;
3544 params.key = &pRoamProfile->Keys.KeyMaterial[key_index][0];
3545 callback(cookie, &params);
3546 return 0;
3547}
3548
3549/*
3550 * FUNCTION: wlan_hdd_cfg80211_del_key
3551 * This function is used to delete the key information
3552 */
3553#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303554static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07003555 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303556 u8 key_index,
3557 bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -07003558 const u8 *mac_addr
3559 )
3560#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303561static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07003562 struct net_device *ndev,
3563 u8 key_index,
3564 const u8 *mac_addr
3565 )
3566#endif
3567{
3568 int status = 0;
3569
3570 //This code needs to be revisited. There is sme_removeKey API, we should
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303571 //plan to use that. After the change to use correct index in setkey,
Jeff Johnson295189b2012-06-20 16:38:30 -07003572 //it is observed that this is invalidating peer
3573 //key index whenever re-key is done. This is affecting data link.
3574 //It should be ok to ignore del_key.
3575#if 0
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303576 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
3577 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07003578 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
3579 tCsrRoamSetKey setKey;
3580 v_U32_t roamId= 0xFF;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303581
Jeff Johnson295189b2012-06-20 16:38:30 -07003582 ENTER();
3583
3584 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device_mode = %d\n",
3585 __func__,pAdapter->device_mode);
3586
3587 if (CSR_MAX_NUM_KEY <= key_index)
3588 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303589 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07003590 key_index);
3591
3592 return -EINVAL;
3593 }
3594
3595 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
3596 setKey.keyId = key_index;
3597
3598 if (mac_addr)
3599 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
3600 else
3601 vos_mem_copy(setKey.peerMac, groupmacaddr, WNI_CFG_BSSID_LEN);
3602
3603 setKey.encType = eCSR_ENCRYPT_TYPE_NONE;
3604
3605 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07003606 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303607 )
3608 {
3609
3610 hdd_hostapd_state_t *pHostapdState =
Jeff Johnson295189b2012-06-20 16:38:30 -07003611 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
3612 if( pHostapdState->bssState == BSS_START)
3613 {
3614 status = WLANSAP_SetKeySta( pVosContext, &setKey);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303615
Jeff Johnson295189b2012-06-20 16:38:30 -07003616 if ( status != eHAL_STATUS_SUCCESS )
3617 {
3618 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3619 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
3620 __LINE__, status );
3621 }
3622 }
3623 }
3624 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303625 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnson295189b2012-06-20 16:38:30 -07003626 )
3627 {
3628 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3629
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303630 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
3631
3632 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -07003633 "%s: delete key for peerMac %2x:%2x:%2x:%2x:%2x:%2x",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303634 __func__, setKey.peerMac[0], setKey.peerMac[1],
3635 setKey.peerMac[2], setKey.peerMac[3],
Jeff Johnson295189b2012-06-20 16:38:30 -07003636 setKey.peerMac[4], setKey.peerMac[5]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303637 if(pAdapter->sessionCtx.station.conn_info.connState ==
3638 eConnectionState_Associated)
Jeff Johnson295189b2012-06-20 16:38:30 -07003639 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303640 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07003641 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303642
Jeff Johnson295189b2012-06-20 16:38:30 -07003643 if ( 0 != status )
3644 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303645 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07003646 "%s: sme_RoamSetKey failure, returned %d",
3647 __func__, status);
3648 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
3649 return -EINVAL;
3650 }
3651 }
3652 }
3653#endif
Jeff Johnsone7245742012-09-05 17:12:55 -07003654 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07003655 return status;
3656}
3657
3658/*
3659 * FUNCTION: wlan_hdd_cfg80211_set_default_key
3660 * This function is used to set the default tx key index
3661 */
3662#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
3663static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
3664 struct net_device *ndev,
3665 u8 key_index,
3666 bool unicast, bool multicast)
3667#else
3668static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
3669 struct net_device *ndev,
3670 u8 key_index)
3671#endif
3672{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303673 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -07003674 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
3675 int status = 0;
3676 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3677
3678 ENTER();
3679
3680 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d key_index = %d \n",
3681 __func__,pAdapter->device_mode, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303682
Jeff Johnson295189b2012-06-20 16:38:30 -07003683 if (CSR_MAX_NUM_KEY <= key_index)
3684 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303685 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07003686 key_index);
3687
3688 return -EINVAL;
3689 }
3690
Jeff Johnson04dd8a82012-06-29 20:41:40 -07003691 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
3692 {
3693 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3694 "%s:LOGP in Progress. Ignore!!!", __func__);
3695 return -EAGAIN;
3696 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303697
Jeff Johnson295189b2012-06-20 16:38:30 -07003698 if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -07003699 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303700 )
Jeff Johnson295189b2012-06-20 16:38:30 -07003701 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303702 if ( (key_index != pWextState->roamProfile.Keys.defaultIndex) &&
3703 (eCSR_ENCRYPT_TYPE_TKIP !=
Jeff Johnson295189b2012-06-20 16:38:30 -07003704 pWextState->roamProfile.EncryptionType.encryptionType[0]) &&
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303705 (eCSR_ENCRYPT_TYPE_AES !=
Jeff Johnson295189b2012-06-20 16:38:30 -07003706 pWextState->roamProfile.EncryptionType.encryptionType[0])
3707 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303708 {
3709 /* if default key index is not same as previous one,
Jeff Johnson295189b2012-06-20 16:38:30 -07003710 * then update the default key index */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303711
Jeff Johnson295189b2012-06-20 16:38:30 -07003712 tCsrRoamSetKey setKey;
3713 v_U32_t roamId= 0xFF;
3714 tCsrKeys *Keys = &pWextState->roamProfile.Keys;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303715
3716 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: default tx key index %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07003717 __func__, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303718
Jeff Johnson295189b2012-06-20 16:38:30 -07003719 Keys->defaultIndex = (u8)key_index;
3720 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
3721 setKey.keyId = key_index;
3722 setKey.keyLength = Keys->KeyLength[key_index];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303723
3724 vos_mem_copy(&setKey.Key[0],
3725 &Keys->KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -07003726 Keys->KeyLength[key_index]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303727
Jeff Johnson295189b2012-06-20 16:38:30 -07003728 setKey.keyDirection = eSIR_TX_ONLY;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303729
3730 vos_mem_copy(setKey.peerMac,
Jeff Johnson295189b2012-06-20 16:38:30 -07003731 &pHddStaCtx->conn_info.bssId[0],
3732 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303733
3734 setKey.encType =
Jeff Johnson295189b2012-06-20 16:38:30 -07003735 pWextState->roamProfile.EncryptionType.encryptionType[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303736
Jeff Johnson295189b2012-06-20 16:38:30 -07003737 /* issue set key request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303738 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07003739 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303740
Jeff Johnson295189b2012-06-20 16:38:30 -07003741 if ( 0 != status )
3742 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303743 hddLog(VOS_TRACE_LEVEL_ERROR,
3744 "%s: sme_RoamSetKey failed, returned %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07003745 status);
3746 return -EINVAL;
3747 }
3748 }
3749 }
3750
3751 /* In SoftAp mode setting key direction for default mode */
3752 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
3753 {
3754 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
3755 pWextState->roamProfile.EncryptionType.encryptionType[0]) &&
3756 (eCSR_ENCRYPT_TYPE_AES !=
3757 pWextState->roamProfile.EncryptionType.encryptionType[0])
3758 )
3759 {
3760 /* Saving key direction for default key index to TX default */
3761 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
3762 pAPCtx->wepKey[key_index].keyDirection = eSIR_TX_DEFAULT;
3763 }
3764 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303765
Jeff Johnson295189b2012-06-20 16:38:30 -07003766 return status;
3767}
3768
Jeff Johnson295189b2012-06-20 16:38:30 -07003769/*
3770 * FUNCTION: wlan_hdd_cfg80211_inform_bss
3771 * This function is used to inform the BSS details to nl80211 interface.
3772 */
3773static struct cfg80211_bss* wlan_hdd_cfg80211_inform_bss(
3774 hdd_adapter_t *pAdapter, tCsrRoamConnectedProfile *roamProfile)
3775{
3776 struct net_device *dev = pAdapter->dev;
3777 struct wireless_dev *wdev = dev->ieee80211_ptr;
3778 struct wiphy *wiphy = wdev->wiphy;
3779 tSirBssDescription *pBssDesc = roamProfile->pBssDesc;
3780 int chan_no;
3781 int ie_length;
3782 const char *ie;
3783 unsigned int freq;
3784 struct ieee80211_channel *chan;
3785 int rssi = 0;
3786 struct cfg80211_bss *bss = NULL;
3787
3788 ENTER();
3789
3790 if( NULL == pBssDesc )
3791 {
3792 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pBssDesc is NULL\n", __func__);
3793 return bss;
3794 }
3795
3796 chan_no = pBssDesc->channelId;
3797 ie_length = GET_IE_LEN_IN_BSS_DESC( pBssDesc->length );
3798 ie = ((ie_length != 0) ? (const char *)&pBssDesc->ieFields: NULL);
3799
3800 if( NULL == ie )
3801 {
3802 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: IE of BSS descriptor is NULL\n", __func__);
3803 return bss;
3804 }
3805
3806#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
3807 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
3808 {
3809 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
3810 }
3811 else
3812 {
3813 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
3814 }
3815#else
3816 freq = ieee80211_channel_to_frequency(chan_no);
3817#endif
3818
3819 chan = __ieee80211_get_channel(wiphy, freq);
3820
3821 bss = cfg80211_get_bss(wiphy, chan, pBssDesc->bssId,
3822 &roamProfile->SSID.ssId[0], roamProfile->SSID.length,
3823 WLAN_CAPABILITY_ESS, WLAN_CAPABILITY_ESS);
3824 if (bss == NULL)
3825 {
3826 rssi = (VOS_MIN ((pBssDesc->rssi + pBssDesc->sinr), 0))*100;
3827
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303828 return (cfg80211_inform_bss(wiphy, chan, pBssDesc->bssId,
3829 le64_to_cpu(*(__le64 *)pBssDesc->timeStamp),
Jeff Johnson295189b2012-06-20 16:38:30 -07003830 pBssDesc->capabilityInfo,
3831 pBssDesc->beaconInterval, ie, ie_length,
3832 rssi, GFP_KERNEL ));
3833}
3834 else
3835 {
3836 return bss;
3837 }
3838}
3839
3840
3841
3842/*
3843 * FUNCTION: wlan_hdd_cfg80211_inform_bss_frame
3844 * This function is used to inform the BSS details to nl80211 interface.
3845 */
3846struct cfg80211_bss*
3847wlan_hdd_cfg80211_inform_bss_frame( hdd_adapter_t *pAdapter,
3848 tSirBssDescription *bss_desc
3849 )
3850{
3851 /*
3852 cfg80211_inform_bss() is not updating ie field of bss entry, if entry
3853 already exists in bss data base of cfg80211 for that particular BSS ID.
3854 Using cfg80211_inform_bss_frame to update the bss entry instead of
3855 cfg80211_inform_bss, But this call expects mgmt packet as input. As of
3856 now there is no possibility to get the mgmt(probe response) frame from PE,
3857 converting bss_desc to ieee80211_mgmt(probe response) and passing to
3858 cfg80211_inform_bss_frame.
3859 */
3860 struct net_device *dev = pAdapter->dev;
3861 struct wireless_dev *wdev = dev->ieee80211_ptr;
3862 struct wiphy *wiphy = wdev->wiphy;
3863 int chan_no = bss_desc->channelId;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08003864#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
3865 qcom_ie_age *qie_age = NULL;
3866 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length ) + sizeof(qcom_ie_age);
3867#else
Jeff Johnson295189b2012-06-20 16:38:30 -07003868 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length );
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08003869#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07003870 const char *ie =
3871 ((ie_length != 0) ? (const char *)&bss_desc->ieFields: NULL);
3872 unsigned int freq;
3873 struct ieee80211_channel *chan;
3874 struct ieee80211_mgmt *mgmt =
3875 kzalloc((sizeof (struct ieee80211_mgmt) + ie_length), GFP_KERNEL);
3876 struct cfg80211_bss *bss_status = NULL;
3877 size_t frame_len = sizeof (struct ieee80211_mgmt) + ie_length;
3878 int rssi = 0;
Jeff Johnsone7245742012-09-05 17:12:55 -07003879#ifdef WLAN_OPEN_SOURCE
3880 struct timespec ts;
3881#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07003882
3883 ENTER();
3884
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -07003885 if (!mgmt)
3886 return NULL;
3887
Jeff Johnson295189b2012-06-20 16:38:30 -07003888 memcpy(mgmt->bssid, bss_desc->bssId, ETH_ALEN);
Jeff Johnsone7245742012-09-05 17:12:55 -07003889
3890#ifdef WLAN_OPEN_SOURCE
3891 /* Android does not want the timestamp from the frame.
3892 Instead it wants a monotonic increasing value */
3893 get_monotonic_boottime(&ts);
3894 mgmt->u.probe_resp.timestamp =
3895 ((u64)ts.tv_sec * 1000000) + (ts.tv_nsec / 1000);
3896#else
3897 /* keep old behavior for non-open source (for now) */
Jeff Johnson295189b2012-06-20 16:38:30 -07003898 memcpy(&mgmt->u.probe_resp.timestamp, bss_desc->timeStamp,
3899 sizeof (bss_desc->timeStamp));
Jeff Johnsone7245742012-09-05 17:12:55 -07003900
3901#endif
3902
Jeff Johnson295189b2012-06-20 16:38:30 -07003903 mgmt->u.probe_resp.beacon_int = bss_desc->beaconInterval;
3904 mgmt->u.probe_resp.capab_info = bss_desc->capabilityInfo;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08003905
3906#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
3907 /* GPS Requirement: need age ie per entry. Using vendor specific. */
3908 /* Assuming this is the last IE, copy at the end */
3909 ie_length -=sizeof(qcom_ie_age);
3910 qie_age = (qcom_ie_age *)(mgmt->u.probe_resp.variable + ie_length);
3911 qie_age->element_id = QCOM_VENDOR_IE_ID;
3912 qie_age->len = QCOM_VENDOR_IE_AGE_LEN;
3913 qie_age->oui_1 = QCOM_OUI1;
3914 qie_age->oui_2 = QCOM_OUI2;
3915 qie_age->oui_3 = QCOM_OUI3;
3916 qie_age->type = QCOM_VENDOR_IE_AGE_TYPE;
3917 qie_age->age = vos_timer_get_system_ticks() - bss_desc->nReceivedTime;
3918#endif
3919
Jeff Johnson295189b2012-06-20 16:38:30 -07003920 memcpy(mgmt->u.probe_resp.variable, ie, ie_length);
3921
3922 mgmt->frame_control |=
3923 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_RESP);
3924
3925#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303926 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ) &&
Jeff Johnson295189b2012-06-20 16:38:30 -07003927 (wiphy->bands[IEEE80211_BAND_2GHZ] != NULL))
3928 {
3929 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
3930 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303931 else if ((chan_no > ARRAY_SIZE(hdd_channels_2_4_GHZ)) &&
Jeff Johnson295189b2012-06-20 16:38:30 -07003932 (wiphy->bands[IEEE80211_BAND_5GHZ] != NULL))
3933
3934 {
3935 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
3936 }
3937 else
3938 {
3939 kfree(mgmt);
3940 return NULL;
3941 }
3942#else
3943 freq = ieee80211_channel_to_frequency(chan_no);
3944#endif
3945 chan = __ieee80211_get_channel(wiphy, freq);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -08003946 /*when the band is changed on the fly using the GUI, three things are done
3947 * 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)
3948 * as part of the scan abort, message willbe queued to PE and we proceed with flushing and changinh the band.
3949 * pe will stop the scanning further and report back the results what ever it had till now by calling the call back function.
3950 * if the time between update band and scandone call back is sufficent enough the band change reflects in SME, SME validates the channels
3951 * and discards the channels correponding to previous band and calls back with zero bss results.
3952 * 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
3953 * all the channels correponding to previous band.this is due to race condition.but those channels are invalid to the new band and so
3954 * this function __ieee80211_get_channel will return NULL.Each time we report scan result with this pointer null warning kernel trace is printed.
3955 * if the scan results contain large number of APs continuosly kernel warning trace is printed and it will lead to apps watch dog bark.
3956 * So drop the bss and continue to next bss.
3957 */
3958 if(chan == NULL)
3959 {
3960 hddLog(VOS_TRACE_LEVEL_INFO, "%s chan pointer is NULL", __func__);
Chilam Ngc4244af2013-04-01 15:37:32 -07003961 kfree(mgmt);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -08003962 return NULL;
3963 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003964 /*To keep the rssi icon of the connected AP in the scan window
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303965 *and the rssi icon of the wireless networks in sync
Jeff Johnson295189b2012-06-20 16:38:30 -07003966 * */
3967 if (( eConnectionState_Associated ==
3968 pAdapter->sessionCtx.station.conn_info.connState ) &&
3969 ( VOS_TRUE == vos_mem_compare(bss_desc->bssId,
3970 pAdapter->sessionCtx.station.conn_info.bssId,
3971 WNI_CFG_BSSID_LEN)))
3972 {
3973 /* supplicant takes the signal strength in terms of mBm(100*dBm) */
3974 rssi = (pAdapter->rssi * 100);
3975 }
3976 else
3977 {
3978 rssi = (VOS_MIN ((bss_desc->rssi + bss_desc->sinr), 0))*100;
3979 }
3980
3981 bss_status = cfg80211_inform_bss_frame(wiphy, chan, mgmt,
3982 frame_len, rssi, GFP_KERNEL);
3983 kfree(mgmt);
3984 return bss_status;
3985}
3986
3987/*
3988 * FUNCTION: wlan_hdd_cfg80211_update_bss_db
3989 * This function is used to update the BSS data base of CFG8011
3990 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303991struct cfg80211_bss* wlan_hdd_cfg80211_update_bss_db( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07003992 tCsrRoamInfo *pRoamInfo
3993 )
3994{
3995 tCsrRoamConnectedProfile roamProfile;
3996 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
3997 struct cfg80211_bss *bss = NULL;
3998
3999 ENTER();
4000
4001 memset(&roamProfile, 0, sizeof(tCsrRoamConnectedProfile));
4002 sme_RoamGetConnectProfile(hHal, pAdapter->sessionId, &roamProfile);
4003
4004 if (NULL != roamProfile.pBssDesc)
4005 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304006 bss = wlan_hdd_cfg80211_inform_bss(pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07004007 &roamProfile);
4008
4009 if (NULL == bss)
4010 {
4011 hddLog(VOS_TRACE_LEVEL_INFO, "%s: cfg80211_inform_bss return NULL",
4012 __func__);
4013 }
4014
4015 sme_RoamFreeConnectProfile(hHal, &roamProfile);
4016 }
4017 else
4018 {
4019 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: roamProfile.pBssDesc is NULL",
4020 __func__);
4021 }
4022 return bss;
4023}
4024
4025/*
4026 * FUNCTION: wlan_hdd_cfg80211_update_bss
4027 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304028static int wlan_hdd_cfg80211_update_bss( struct wiphy *wiphy,
4029 hdd_adapter_t *pAdapter
Jeff Johnson295189b2012-06-20 16:38:30 -07004030 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304031{
Jeff Johnson295189b2012-06-20 16:38:30 -07004032 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
4033 tCsrScanResultInfo *pScanResult;
4034 eHalStatus status = 0;
4035 tScanResultHandle pResult;
4036 struct cfg80211_bss *bss_status = NULL;
4037
4038 ENTER();
4039
4040 if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress)
4041 {
4042 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:LOGP in Progress. Ignore!!!",__func__);
4043 return -EAGAIN;
4044 }
4045
4046 /*
4047 * start getting scan results and populate cgf80211 BSS database
4048 */
4049 status = sme_ScanGetResult(hHal, pAdapter->sessionId, NULL, &pResult);
4050
4051 /* no scan results */
4052 if (NULL == pResult)
4053 {
4054 hddLog(VOS_TRACE_LEVEL_INFO, "%s: No scan result\n", __func__);
4055 return status;
4056 }
4057
4058 pScanResult = sme_ScanResultGetFirst(hHal, pResult);
4059
4060 while (pScanResult)
4061 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304062 /*
4063 * cfg80211_inform_bss() is not updating ie field of bss entry, if
4064 * entry already exists in bss data base of cfg80211 for that
4065 * particular BSS ID. Using cfg80211_inform_bss_frame to update the
4066 * bss entry instead of cfg80211_inform_bss, But this call expects
4067 * mgmt packet as input. As of now there is no possibility to get
4068 * the mgmt(probe response) frame from PE, converting bss_desc to
Jeff Johnson295189b2012-06-20 16:38:30 -07004069 * ieee80211_mgmt(probe response) and passing to c
4070 * fg80211_inform_bss_frame.
4071 * */
4072
4073 bss_status = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
4074 &pScanResult->BssDescriptor);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304075
Jeff Johnson295189b2012-06-20 16:38:30 -07004076
4077 if (NULL == bss_status)
4078 {
4079 hddLog(VOS_TRACE_LEVEL_INFO,
4080 "%s: NULL returned by cfg80211_inform_bss\n", __func__);
4081 }
4082 else
4083 {
4084 cfg80211_put_bss(bss_status);
4085 }
4086
4087 pScanResult = sme_ScanResultGetNext(hHal, pResult);
4088 }
4089
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304090 sme_ScanResultPurge(hHal, pResult);
Jeff Johnson295189b2012-06-20 16:38:30 -07004091
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304092 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07004093}
4094
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004095void
4096hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel)
4097{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304098 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07004099 "%02X:%02X:%02X:%02X:%02X:%02X\n",
4100 macAddr[0], macAddr[1], macAddr[2], macAddr[3], macAddr[4],
4101 macAddr[5]);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004102} /****** end hddPrintMacAddr() ******/
4103
4104void
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07004105hddPrintPmkId(tANI_U8 *pmkId, tANI_U8 logLevel)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004106{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304107 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07004108 "%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X\n",
4109 pmkId[0], pmkId[1], pmkId[2], pmkId[3], pmkId[4],
4110 pmkId[5], pmkId[6], pmkId[7], pmkId[8], pmkId[9], pmkId[10],
4111 pmkId[11], pmkId[12], pmkId[13], pmkId[14], pmkId[15]);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004112} /****** end hddPrintPmkId() ******/
4113
4114//hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel);
4115//hddPrintMacAddr(macAddr, VOS_TRACE_LEVEL_FATAL);
4116
4117//void sirDumpBuf(tpAniSirGlobal pMac, tANI_U8 modId, tANI_U32 level, tANI_U8 *buf, tANI_U32 size);
4118//sirDumpBuf(pMac, VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, pmkid, 16);
4119
4120#define dump_bssid(bssid) \
4121 { \
Jeff Johnsone7245742012-09-05 17:12:55 -07004122 hddLog(VOS_TRACE_LEVEL_INFO, "BSSID (MAC) address:\t"); \
4123 hddPrintMacAddr(bssid, VOS_TRACE_LEVEL_INFO);\
4124 hddLog(VOS_TRACE_LEVEL_INFO, "\n"); \
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004125 }
4126
4127#define dump_pmkid(pMac, pmkid) \
4128 { \
Jeff Johnsone7245742012-09-05 17:12:55 -07004129 hddLog(VOS_TRACE_LEVEL_INFO, "PMKSA-ID:\t"); \
4130 hddPrintPmkId(pmkid, VOS_TRACE_LEVEL_INFO);\
4131 hddLog(VOS_TRACE_LEVEL_INFO, "\n"); \
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004132 }
4133
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -07004134#if defined(FEATURE_WLAN_LFR) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004135/*
4136 * FUNCTION: wlan_hdd_cfg80211_pmksa_candidate_notify
4137 * This function is used to notify the supplicant of a new PMKSA candidate.
4138 */
4139int wlan_hdd_cfg80211_pmksa_candidate_notify(
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304140 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004141 int index, bool preauth )
4142{
Jeff Johnsone7245742012-09-05 17:12:55 -07004143#ifdef FEATURE_WLAN_OKC
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004144 struct net_device *dev = pAdapter->dev;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004145 hdd_context_t *pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004146
4147 ENTER();
Jeff Johnsone7245742012-09-05 17:12:55 -07004148 hddLog(VOS_TRACE_LEVEL_INFO, "%s is going to notify supplicant of:", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004149
4150 if( NULL == pRoamInfo )
4151 {
4152 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pRoamInfo is NULL\n", __func__);
4153 return -EINVAL;
4154 }
4155
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004156 if (eANI_BOOLEAN_TRUE == hdd_is_okc_mode_enabled(pHddCtx))
4157 {
4158 dump_bssid(pRoamInfo->bssid);
4159 cfg80211_pmksa_candidate_notify(dev, index,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004160 pRoamInfo->bssid, preauth, GFP_KERNEL);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004161 }
Jeff Johnsone7245742012-09-05 17:12:55 -07004162#endif /* FEATURE_WLAN_OKC */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304163 return 0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004164}
4165#endif //FEATURE_WLAN_LFR
4166
Jeff Johnson295189b2012-06-20 16:38:30 -07004167/*
4168 * FUNCTION: hdd_cfg80211_scan_done_callback
4169 * scanning callback function, called after finishing scan
4170 *
4171 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304172static eHalStatus hdd_cfg80211_scan_done_callback(tHalHandle halHandle,
Jeff Johnson295189b2012-06-20 16:38:30 -07004173 void *pContext, tANI_U32 scanId, eCsrScanStatus status)
4174{
4175 struct net_device *dev = (struct net_device *) pContext;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304176 //struct wireless_dev *wdev = dev->ieee80211_ptr;
Jeff Johnson295189b2012-06-20 16:38:30 -07004177 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07004178 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
4179 hdd_scaninfo_t *pScanInfo = &pHddCtx->scan_info;
Jeff Johnson295189b2012-06-20 16:38:30 -07004180 struct cfg80211_scan_request *req = NULL;
4181 int ret = 0;
4182
4183 ENTER();
4184
4185 hddLog(VOS_TRACE_LEVEL_INFO,
4186 "%s called with halHandle = %p, pContext = %p,"
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304187 "scanID = %d, returned status = %d\n",
Jeff Johnson295189b2012-06-20 16:38:30 -07004188 __func__, halHandle, pContext, (int) scanId, (int) status);
4189
4190 //Block on scan req completion variable. Can't wait forever though.
4191 ret = wait_for_completion_interruptible_timeout(
4192 &pScanInfo->scan_req_completion_event,
4193 msecs_to_jiffies(WLAN_WAIT_TIME_SCAN_REQ));
4194 if (!ret)
4195 {
4196 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -07004197 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -07004198 }
4199
4200 if(pScanInfo->mScanPending != VOS_TRUE)
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 /* Check the scanId */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304207 if (pScanInfo->scanId != scanId)
Jeff Johnson295189b2012-06-20 16:38:30 -07004208 {
4209 hddLog(VOS_TRACE_LEVEL_INFO,
4210 "%s called with mismatched scanId pScanInfo->scanId = %d "
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304211 "scanId = %d \n", __func__, (int) pScanInfo->scanId,
Jeff Johnson295189b2012-06-20 16:38:30 -07004212 (int) scanId);
4213 }
4214
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304215 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07004216 pAdapter);
4217
4218 if (0 > ret)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304219 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004220
4221
4222 /* If any client wait scan result through WEXT
4223 * send scan done event to client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07004224 if (pHddCtx->scan_info.waitScanResult)
Jeff Johnson295189b2012-06-20 16:38:30 -07004225 {
4226 /* The other scan request waiting for current scan finish
4227 * Send event to notify current scan finished */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07004228 if(WEXT_SCAN_PENDING_DELAY == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -07004229 {
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07004230 vos_event_set(&pHddCtx->scan_info.scan_finished_event);
Jeff Johnson295189b2012-06-20 16:38:30 -07004231 }
4232 /* Send notify to WEXT client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07004233 else if(WEXT_SCAN_PENDING_PIGGYBACK == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -07004234 {
4235 struct net_device *dev = pAdapter->dev;
4236 union iwreq_data wrqu;
4237 int we_event;
4238 char *msg;
4239
4240 memset(&wrqu, '\0', sizeof(wrqu));
4241 we_event = SIOCGIWSCAN;
4242 msg = NULL;
4243 wireless_send_event(dev, we_event, &wrqu, msg);
4244 }
4245 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07004246 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07004247
4248 /* Get the Scan Req */
4249 req = pAdapter->request;
4250
4251 if (!req)
4252 {
4253 hddLog(VOS_TRACE_LEVEL_ERROR, "request is became NULL\n");
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07004254 pScanInfo->mScanPending = VOS_FALSE;
Jeff Johnsone7245742012-09-05 17:12:55 -07004255 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -07004256 }
4257
4258 /*
4259 * setting up 0, just in case.
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304260 */
Jeff Johnson295189b2012-06-20 16:38:30 -07004261 req->n_ssids = 0;
4262 req->n_channels = 0;
4263 req->ie = 0;
4264
Jeff Johnson295189b2012-06-20 16:38:30 -07004265 pAdapter->request = NULL;
Jeff Johnsone7245742012-09-05 17:12:55 -07004266 /* Scan is no longer pending */
4267 pScanInfo->mScanPending = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07004268
Madan Mohan Koyyalamudib764bf82012-10-11 16:38:51 -07004269 /*
4270 * cfg80211_scan_done informing NL80211 about completion
4271 * of scanning
4272 */
4273 cfg80211_scan_done(req, false);
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -08004274 complete(&pScanInfo->abortscan_event_var);
Jeff Johnson295189b2012-06-20 16:38:30 -07004275
Jeff Johnsone7245742012-09-05 17:12:55 -07004276allow_suspend:
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07004277 /* release the wake lock at the end of the scan*/
4278 hdd_allow_suspend();
Jeff Johnsone7245742012-09-05 17:12:55 -07004279
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -07004280 /* Acquire wakelock to handle the case where APP's tries to suspend
4281 * immediatly after the driver gets connect request(i.e after scan)
4282 * from supplicant, this result in app's is suspending and not able
4283 * to process the connect request to AP */
4284 hdd_allow_suspend_timeout(100);
4285
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07004286#ifdef FEATURE_WLAN_TDLS
4287 wlan_hdd_tdls_scan_done_callback(pAdapter);
4288#endif
4289
Jeff Johnson295189b2012-06-20 16:38:30 -07004290 EXIT();
4291 return 0;
4292}
4293
4294/*
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08004295 * FUNCTION: hdd_isScanAllowed
4296 * Go through each adapter and check if scan allowed
4297 *
4298 */
4299v_BOOL_t hdd_isScanAllowed( hdd_context_t *pHddCtx )
4300{
4301 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
4302 hdd_station_ctx_t *pHddStaCtx = NULL;
4303 hdd_adapter_t *pAdapter = NULL;
4304 VOS_STATUS status = 0;
4305 v_U8_t staId = 0;
4306 v_U8_t *staMac = NULL;
4307
4308 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
4309
4310 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
4311 {
4312 pAdapter = pAdapterNode->pAdapter;
4313
4314 if( pAdapter )
4315 {
4316 hddLog(VOS_TRACE_LEVEL_INFO,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304317 "%s: Adapter with device mode %d exists",
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08004318 __func__, pAdapter->device_mode);
4319 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
4320 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
4321 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
4322 {
4323 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4324 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
4325 (VOS_FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
4326 {
4327 staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]);
4328 hddLog(VOS_TRACE_LEVEL_ERROR,
4329 "%s: client %02x:%02x:%02x:%02x:%02x:%02x is in the "
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304330 "middle of WPS/EAPOL exchange.", __func__,
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08004331 staMac[0], staMac[1], staMac[2],
4332 staMac[3], staMac[4], staMac[5]);
4333 return VOS_FALSE;
4334 }
4335 }
4336 else if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) ||
4337 (WLAN_HDD_P2P_GO == pAdapter->device_mode))
4338 {
4339 for (staId = 0; staId < WLAN_MAX_STA_COUNT; staId++)
4340 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304341 if ((pAdapter->aStaInfo[staId].isUsed) &&
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08004342 (WLANTL_STA_CONNECTED == pAdapter->aStaInfo[staId].tlSTAState))
4343 {
4344 staMac = (v_U8_t *) &(pAdapter->aStaInfo[staId].macAddrSTA.bytes[0]);
4345
4346 hddLog(VOS_TRACE_LEVEL_ERROR,
4347 "%s: client %02x:%02x:%02x:%02x:%02x:%02x of SoftAP/P2P-GO is in the "
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304348 "middle of WPS/EAPOL exchange.", __func__,
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08004349 staMac[0], staMac[1], staMac[2],
4350 staMac[3], staMac[4], staMac[5]);
4351 return VOS_FALSE;
4352 }
4353 }
4354 }
4355 }
4356 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
4357 pAdapterNode = pNext;
4358 }
4359 hddLog(VOS_TRACE_LEVEL_INFO,
4360 "%s: Scan allowed", __func__);
4361 return VOS_TRUE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304362}
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08004363
4364/*
Jeff Johnson295189b2012-06-20 16:38:30 -07004365 * FUNCTION: wlan_hdd_cfg80211_scan
4366 * this scan respond to scan trigger and update cfg80211 scan database
4367 * later, scan dump command can be used to recieve scan results
4368 */
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -08004369int wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
4370#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
4371 struct net_device *dev,
4372#endif
4373 struct cfg80211_scan_request *request)
4374{
4375#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
4376 struct net_device *dev = request->wdev->netdev;
4377#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304378 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Jeff Johnson295189b2012-06-20 16:38:30 -07004379 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
4380 hdd_wext_state_t *pwextBuf = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
4381 hdd_config_t *cfg_param = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
4382 tCsrScanRequest scanRequest;
4383 tANI_U8 *channelList = NULL, i;
4384 v_U32_t scanId = 0;
4385 int status = 0;
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07004386 hdd_scaninfo_t *pScanInfo = &pHddCtx->scan_info;
Jeff Johnson295189b2012-06-20 16:38:30 -07004387 v_U8_t* pP2pIe = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07004388
4389 ENTER();
4390
4391 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",
4392 __func__,pAdapter->device_mode);
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08004393
Gopichand Nakkala681989c2013-03-06 22:27:48 -08004394 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08004395 (eConnectionState_Connecting ==
Gopichand Nakkala681989c2013-03-06 22:27:48 -08004396 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08004397 {
4398 hddLog(VOS_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08004399 "%s: %p(%d) Connection in progress: Scan request denied (EBUSY)", __func__, \
4400 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08004401 return -EBUSY;
4402 }
4403
Jeff Johnson295189b2012-06-20 16:38:30 -07004404#ifdef WLAN_BTAMP_FEATURE
4405 //Scan not supported when AMP traffic is on.
Gopichand Nakkala681989c2013-03-06 22:27:48 -08004406 if (VOS_TRUE == WLANBAP_AmpSessionOn())
Jeff Johnson295189b2012-06-20 16:38:30 -07004407 {
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08004408 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07004409 "%s: No scanning when AMP is on", __func__);
4410 return -EOPNOTSUPP;
4411 }
4412#endif
4413 //Scan on any other interface is not supported.
Gopichand Nakkala681989c2013-03-06 22:27:48 -08004414 if (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07004415 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -08004416 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07004417 "%s: Not scanning on device_mode = %d",
4418 __func__, pAdapter->device_mode);
4419 return -EOPNOTSUPP;
4420 }
4421
4422 if (TRUE == pScanInfo->mScanPending)
4423 {
4424 hddLog(VOS_TRACE_LEVEL_INFO, "%s: mScanPending is TRUE", __func__);
Gopichand Nakkala681989c2013-03-06 22:27:48 -08004425 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -07004426 }
4427
4428 if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress)
4429 {
4430 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
4431 "%s:LOGP in Progress. Ignore!!!", __func__);
4432 return -EAGAIN;
4433 }
4434
Mohit Khanna6c52bbf2012-09-11 15:10:12 -07004435 if ((WLAN_HDD_GET_CTX(pAdapter))->isLoadUnloadInProgress)
4436 {
4437 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
4438 "%s:Unloading/Loading in Progress. Ignore!!!", __func__);
4439 return -EAGAIN;
4440 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304441 //Don't Allow Scan and return busy if Remain On
Jeff Johnson32d95a32012-09-10 13:15:23 -07004442 //Channel and action frame is pending
4443 //Otherwise Cancel Remain On Channel and allow Scan
4444 //If no action frame pending
Gopichand Nakkala681989c2013-03-06 22:27:48 -08004445 if (0 != wlan_hdd_check_remain_on_channel(pAdapter))
Jeff Johnson32d95a32012-09-10 13:15:23 -07004446 {
4447 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Remain On Channel Pending", __func__);
4448 return -EBUSY;
4449 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08004450#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07004451 /* if tdls disagree scan right now, return immediately.
4452 tdls will schedule the scan when scan is allowed. (return SUCCESS)
4453 or will reject the scan if any TDLS is in progress. (return -EBUSY)
4454 */
4455 status = wlan_hdd_tdls_scan_callback (pAdapter,
4456 wiphy,
4457#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
4458 dev,
Gopichand Nakkalac3c42b92013-03-20 19:42:34 -07004459#endif
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07004460 request);
4461 if(status <= 0)
4462 {
4463 hddLog(VOS_TRACE_LEVEL_INFO, "%s: TDLS Pending %d", __func__, status);
4464 return status;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08004465 }
4466#endif
Jeff Johnson32d95a32012-09-10 13:15:23 -07004467
Jeff Johnson295189b2012-06-20 16:38:30 -07004468 if (mutex_lock_interruptible(&pHddCtx->tmInfo.tmOperationLock))
4469 {
4470 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_ERROR,
Jeff Johnson1250df42012-12-10 14:31:52 -08004471 "%s: Acquire lock fail", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004472 return -EAGAIN;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304473 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004474 if (TRUE == pHddCtx->tmInfo.tmAction.enterImps)
4475 {
4476 hddLog(VOS_TRACE_LEVEL_WARN,
4477 "%s: MAX TM Level Scan not allowed", __func__);
4478 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304479 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -07004480 }
4481 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
4482
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08004483 /* Check if scan is allowed at this point of time.
4484 */
4485 if (!hdd_isScanAllowed(pHddCtx))
4486 {
4487 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Scan not allowed", __func__);
4488 return -EBUSY;
4489 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304490
Jeff Johnson295189b2012-06-20 16:38:30 -07004491 vos_mem_zero( &scanRequest, sizeof(scanRequest));
4492
4493 if (NULL != request)
4494 {
4495 hddLog(VOS_TRACE_LEVEL_INFO, "scan request for ssid = %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304496 (int)request->n_ssids);
Jeff Johnson295189b2012-06-20 16:38:30 -07004497
4498 /* Even though supplicant doesn't provide any SSIDs, n_ssids is set to 1.
4499 * Becasue of this, driver is assuming that this is not wildcard scan and so
4500 * is not aging out the scan results.
4501 */
Jeff Johnson32d95a32012-09-10 13:15:23 -07004502 if (request->ssids && '\0' == request->ssids->ssid[0])
Jeff Johnson295189b2012-06-20 16:38:30 -07004503 {
4504 request->n_ssids = 0;
4505 }
4506
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07004507 if ((request->ssids) && (0 < request->n_ssids))
Jeff Johnson295189b2012-06-20 16:38:30 -07004508 {
4509 tCsrSSIDInfo *SsidInfo;
4510 int j;
4511 scanRequest.SSIDs.numOfSSIDs = request->n_ssids;
4512 /* Allocate num_ssid tCsrSSIDInfo structure */
4513 SsidInfo = scanRequest.SSIDs.SSIDList =
4514 ( tCsrSSIDInfo *)vos_mem_malloc(
4515 request->n_ssids*sizeof(tCsrSSIDInfo));
4516
4517 if(NULL == scanRequest.SSIDs.SSIDList)
4518 {
4519 hddLog(VOS_TRACE_LEVEL_ERROR,
4520 "memory alloc failed SSIDInfo buffer");
4521 return -ENOMEM;
4522 }
4523
4524 /* copy all the ssid's and their length */
4525 for(j = 0; j < request->n_ssids; j++, SsidInfo++)
4526 {
4527 /* get the ssid length */
4528 SsidInfo->SSID.length = request->ssids[j].ssid_len;
4529 vos_mem_copy(SsidInfo->SSID.ssId, &request->ssids[j].ssid[0],
4530 SsidInfo->SSID.length);
4531 SsidInfo->SSID.ssId[SsidInfo->SSID.length] = '\0';
4532 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "SSID number %d: %s",
4533 j, SsidInfo->SSID.ssId);
4534 }
4535 /* set the scan type to active */
4536 scanRequest.scanType = eSIR_ACTIVE_SCAN;
4537 }
4538 else if(WLAN_HDD_P2P_GO == pAdapter->device_mode)
4539 {
4540 /* set the scan type to active */
4541 scanRequest.scanType = eSIR_ACTIVE_SCAN;
4542 }
4543 else
4544 {
4545 /*Set the scan type to default type, in this case it is ACTIVE*/
4546 scanRequest.scanType = pScanInfo->scan_mode;
4547 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304548 scanRequest.minChnTime = cfg_param->nActiveMinChnTime;
Jeff Johnson295189b2012-06-20 16:38:30 -07004549 scanRequest.maxChnTime = cfg_param->nActiveMaxChnTime;
4550 }
4551 else
4552 {
4553 /* set the scan type to active */
4554 scanRequest.scanType = eSIR_ACTIVE_SCAN;
4555 vos_mem_set( scanRequest.bssid, sizeof( tCsrBssid ), 0xff );
4556
4557 /* set min and max channel time to zero */
4558 scanRequest.minChnTime = 0;
4559 scanRequest.maxChnTime = 0;
4560 }
4561
4562 /* set BSSType to default type */
4563 scanRequest.BSSType = eCSR_BSS_TYPE_ANY;
4564
4565 /*TODO: scan the requested channels only*/
4566
4567 /*Right now scanning all the channels */
4568 if( request )
4569 {
4570 if( request->n_channels )
4571 {
4572 channelList = vos_mem_malloc( request->n_channels );
4573 if( NULL == channelList )
4574 {
4575 status = -ENOMEM;
4576 goto free_mem;
4577 }
4578
4579 for( i = 0 ; i < request->n_channels ; i++ )
4580 channelList[i] = request->channels[i]->hw_value;
4581 }
4582
4583 scanRequest.ChannelInfo.numOfChannels = request->n_channels;
4584 scanRequest.ChannelInfo.ChannelList = channelList;
4585
4586 /* set requestType to full scan */
4587 scanRequest.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304588
4589 /* Flush the scan results(only p2p beacons) for STA scan and P2P
Madan Mohan Koyyalamudi8d50f312012-11-27 15:48:57 -08004590 * search (Flush on both full scan and social scan but not on single
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304591 * channel scan).P2P search happens on 3 social channels (1, 6, 11)
Madan Mohan Koyyalamudi8d50f312012-11-27 15:48:57 -08004592 */
4593
4594 /* Supplicant does single channel scan after 8-way handshake
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304595 * and in that case driver shoudnt flush scan results. If
4596 * driver flushes the scan results here and unfortunately if
4597 * the AP doesnt respond to our probe req then association
Madan Mohan Koyyalamudi8d50f312012-11-27 15:48:57 -08004598 * fails which is not desired
4599 */
4600
4601 if( request->n_channels != WLAN_HDD_P2P_SINGLE_CHANNEL_SCAN )
4602 {
4603 sme_ScanFlushP2PResult( WLAN_HDD_GET_HAL_CTX(pAdapter),
4604 pAdapter->sessionId );
4605 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004606
4607 if( request->ie_len )
4608 {
4609 /* save this for future association (join requires this) */
4610 memset( &pScanInfo->scanAddIE, 0, sizeof(pScanInfo->scanAddIE) );
4611 memcpy( pScanInfo->scanAddIE.addIEdata, request->ie, request->ie_len);
4612 pScanInfo->scanAddIE.length = request->ie_len;
4613
4614 if((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Jeff Johnsone7245742012-09-05 17:12:55 -07004615 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
4616 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -07004617 )
4618 {
4619 pwextBuf->roamProfile.pAddIEScan = pScanInfo->scanAddIE.addIEdata;
4620 pwextBuf->roamProfile.nAddIEScanLength = pScanInfo->scanAddIE.length;
4621 }
4622
4623 scanRequest.uIEFieldLen = pScanInfo->scanAddIE.length;
4624 scanRequest.pIEField = pScanInfo->scanAddIE.addIEdata;
4625
Jeff Johnson295189b2012-06-20 16:38:30 -07004626 pP2pIe = wlan_hdd_get_p2p_ie_ptr((v_U8_t*)request->ie,
4627 request->ie_len);
4628 if (pP2pIe != NULL)
4629 {
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07004630#ifdef WLAN_FEATURE_P2P_DEBUG
4631 if (((globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED) ||
4632 (globalP2PConnectionStatus == P2P_GO_NEG_PROCESS)) &&
4633 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
4634 {
4635 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_1;
4636 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
4637 "Go nego completed to Connection is started");
4638 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
4639 "for 8way Handshake");
4640 }
4641 else if((globalP2PConnectionStatus == P2P_CLIENT_DISCONNECTED_STATE) &&
4642 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
4643 {
4644 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_2;
4645 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
4646 "Disconnected state to Connection is started");
4647 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
4648 "for 4way Handshake");
4649 }
4650#endif
4651
Jeff Johnsone7245742012-09-05 17:12:55 -07004652 /* no_cck will be set during p2p find to disable 11b rates */
4653 if(TRUE == request->no_cck)
Jeff Johnson295189b2012-06-20 16:38:30 -07004654 {
Jeff Johnson295189b2012-06-20 16:38:30 -07004655 hddLog(VOS_TRACE_LEVEL_INFO,
4656 "%s: This is a P2P Search", __func__);
4657 scanRequest.p2pSearch = 1;
Jeff Johnsone7245742012-09-05 17:12:55 -07004658
Jeff Johnsone7245742012-09-05 17:12:55 -07004659 if( request->n_channels == WLAN_HDD_P2P_SOCIAL_CHANNELS )
4660 {
Madan Mohan Koyyalamudi1b1d9e82012-10-21 11:38:33 -07004661 /* set requestType to P2P Discovery */
4662 scanRequest.requestType = eCSR_SCAN_P2P_DISCOVERY;
Jeff Johnsone7245742012-09-05 17:12:55 -07004663 }
4664
4665 /*
4666 Skip Dfs Channel in case of P2P Search
4667 if it is set in ini file
4668 */
4669 if(cfg_param->skipDfsChnlInP2pSearch)
4670 {
4671 scanRequest.skipDfsChnlInP2pSearch = 1;
4672 }
4673 else
4674 {
4675 scanRequest.skipDfsChnlInP2pSearch = 0;
4676 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004677
Jeff Johnson295189b2012-06-20 16:38:30 -07004678 }
4679 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004680 }
4681 }
4682
4683 INIT_COMPLETION(pScanInfo->scan_req_completion_event);
4684
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07004685 /* acquire the wakelock to avoid the apps suspend during the scan. To
4686 * address the following issues.
4687 * 1) Disconnected scenario: we are not allowing the suspend as WLAN is not in
4688 * BMPS/IMPS this result in android trying to suspend aggressively and backing off
4689 * for long time, this result in apps running at full power for long time.
4690 * 2) Connected scenario: If we allow the suspend during the scan, RIVA will
4691 * be stuck in full power because of resume BMPS
4692 */
4693 hdd_prevent_suspend();
Jeff Johnsone7245742012-09-05 17:12:55 -07004694
4695 status = sme_ScanRequest( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07004696 pAdapter->sessionId, &scanRequest, &scanId,
4697 &hdd_cfg80211_scan_done_callback, dev );
Jeff Johnsone7245742012-09-05 17:12:55 -07004698
Jeff Johnson295189b2012-06-20 16:38:30 -07004699 if (eHAL_STATUS_SUCCESS != status)
4700 {
4701 hddLog(VOS_TRACE_LEVEL_ERROR,
4702 "%s: sme_ScanRequest returned error %d", __func__, status);
4703 complete(&pScanInfo->scan_req_completion_event);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -07004704 if(eHAL_STATUS_RESOURCES == status)
4705 {
Madan Mohan Koyyalamudia3fcf142012-10-18 15:01:20 -07004706 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 -07004707 status = -EBUSY;
4708 } else {
4709 status = -EIO;
4710 }
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07004711 hdd_allow_suspend();
Jeff Johnson295189b2012-06-20 16:38:30 -07004712 goto free_mem;
4713 }
4714
4715 pScanInfo->mScanPending = TRUE;
4716 pAdapter->request = request;
4717 pScanInfo->scanId = scanId;
4718
4719 complete(&pScanInfo->scan_req_completion_event);
4720
4721free_mem:
4722 if( scanRequest.SSIDs.SSIDList )
4723 {
4724 vos_mem_free(scanRequest.SSIDs.SSIDList);
4725 }
4726
4727 if( channelList )
4728 vos_mem_free( channelList );
4729
4730 EXIT();
4731
4732 return status;
4733}
4734
4735/*
4736 * FUNCTION: wlan_hdd_cfg80211_connect_start
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304737 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -07004738 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304739int wlan_hdd_cfg80211_connect_start( hdd_adapter_t *pAdapter,
Jeff Johnson32d95a32012-09-10 13:15:23 -07004740 const u8 *ssid, size_t ssid_len, const u8 *bssid, u8 operatingChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -07004741{
4742 int status = 0;
4743 hdd_wext_state_t *pWextState;
4744 v_U32_t roamId;
4745 tCsrRoamProfile *pRoamProfile;
4746 eMib_dot11DesiredBssType connectedBssType;
4747 eCsrAuthType RSNAuthType;
4748
4749 ENTER();
4750
4751 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304752
Jeff Johnson295189b2012-06-20 16:38:30 -07004753 if (SIR_MAC_MAX_SSID_LENGTH < ssid_len)
4754 {
4755 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wrong SSID len", __func__);
4756 return -EINVAL;
4757 }
4758
4759 pRoamProfile = &pWextState->roamProfile;
4760
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304761 if (pRoamProfile)
Jeff Johnson295189b2012-06-20 16:38:30 -07004762 {
Jeff Johnsone7245742012-09-05 17:12:55 -07004763 int ret = 0;
4764 hdd_station_ctx_t *pHddStaCtx;
4765 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4766 hdd_connGetConnectedBssType(pHddStaCtx,&connectedBssType );
4767
4768 if((eMib_dot11DesiredBssType_independent == connectedBssType) ||
4769 (eConnectionState_Associated == pHddStaCtx->conn_info.connState) ||
4770 (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState))
Jeff Johnson295189b2012-06-20 16:38:30 -07004771 {
4772 /* Issue disconnect to CSR */
4773 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304774 if( eHAL_STATUS_SUCCESS ==
Jeff Johnson295189b2012-06-20 16:38:30 -07004775 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
4776 pAdapter->sessionId,
4777 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
4778 {
Jeff Johnsone7245742012-09-05 17:12:55 -07004779 ret = wait_for_completion_interruptible_timeout(
4780 &pAdapter->disconnect_comp_var,
4781 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
4782 if (0 == ret)
4783 {
4784 VOS_ASSERT(0);
4785 }
4786 }
4787 }
4788 else if(eConnectionState_Disconnecting == pHddStaCtx->conn_info.connState)
4789 {
4790 ret = wait_for_completion_interruptible_timeout(
4791 &pAdapter->disconnect_comp_var,
4792 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
4793 if (0 == ret)
4794 {
4795 VOS_ASSERT(0);
Jeff Johnson295189b2012-06-20 16:38:30 -07004796 }
4797 }
4798
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304799 if (HDD_WMM_USER_MODE_NO_QOS ==
Jeff Johnson295189b2012-06-20 16:38:30 -07004800 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->WmmMode)
4801 {
4802 /*QoS not enabled in cfg file*/
4803 pRoamProfile->uapsd_mask = 0;
4804 }
4805 else
4806 {
4807 /*QoS enabled, update uapsd mask from cfg file*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304808 pRoamProfile->uapsd_mask =
Jeff Johnson295189b2012-06-20 16:38:30 -07004809 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask;
4810 }
4811
4812 pRoamProfile->SSIDs.numOfSSIDs = 1;
4813 pRoamProfile->SSIDs.SSIDList->SSID.length = ssid_len;
4814 vos_mem_zero(pRoamProfile->SSIDs.SSIDList->SSID.ssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304815 sizeof(pRoamProfile->SSIDs.SSIDList->SSID.ssId));
Jeff Johnson295189b2012-06-20 16:38:30 -07004816 vos_mem_copy((void *)(pRoamProfile->SSIDs.SSIDList->SSID.ssId),
4817 ssid, ssid_len);
4818
4819 if (bssid)
4820 {
4821 pRoamProfile->BSSIDs.numOfBSSIDs = 1;
4822 vos_mem_copy((void *)(pRoamProfile->BSSIDs.bssid), bssid,
4823 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304824 /* Save BSSID in seperate variable as well, as RoamProfile
4825 BSSID is getting zeroed out in the association process. And in
Jeff Johnson295189b2012-06-20 16:38:30 -07004826 case of join failure we should send valid BSSID to supplicant
4827 */
4828 vos_mem_copy((void *)(pWextState->req_bssId), bssid,
4829 WNI_CFG_BSSID_LEN);
4830 }
4831
4832 if ((IW_AUTH_WPA_VERSION_WPA == pWextState->wpaVersion) ||
4833 (IW_AUTH_WPA_VERSION_WPA2 == pWextState->wpaVersion))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304834 {
Jeff Johnson295189b2012-06-20 16:38:30 -07004835 /*set gen ie*/
4836 hdd_SetGENIEToCsr(pAdapter, &RSNAuthType);
4837 /*set auth*/
4838 hdd_set_csr_auth_type(pAdapter, RSNAuthType);
4839 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304840 else if ( (pWextState->roamProfile.AuthType.authType[0] ==
Jeff Johnson295189b2012-06-20 16:38:30 -07004841 eCSR_AUTH_TYPE_OPEN_SYSTEM)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304842 && ((pWextState->roamProfile.EncryptionType.encryptionType[0] ==
4843 eCSR_ENCRYPT_TYPE_WEP40_STATICKEY)
4844 || (pWextState->roamProfile.EncryptionType.encryptionType[0] ==
Jeff Johnson295189b2012-06-20 16:38:30 -07004845 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY))
4846 )
4847 {
4848 /*Android UI not having any option to configure the Authentication type to OPEN/SHARED;
4849 * The authentication type will be always eCSR_AUTH_TYPE_OPEN_SYSTEM when WEP is used
4850 * Use eCSR_AUTH_TYPE_AUTOSWITCH when WEP encryption used*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304851 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.authType =
Jeff Johnson295189b2012-06-20 16:38:30 -07004852 eCSR_AUTH_TYPE_AUTOSWITCH;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304853 pWextState->roamProfile.AuthType.authType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -07004854 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.authType;
4855 }
4856#ifdef FEATURE_WLAN_WAPI
4857 if (pAdapter->wapi_info.nWapiMode)
4858 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004859 hddLog(LOG1, "%s: Setting WAPI AUTH Type and Encryption Mode values", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004860 switch (pAdapter->wapi_info.wapiAuthMode)
4861 {
4862 case WAPI_AUTH_MODE_PSK:
4863 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004864 hddLog(LOG1, "%s: WAPI AUTH TYPE: PSK: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07004865 pAdapter->wapi_info.wapiAuthMode);
4866 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_PSK;
4867 break;
4868 }
4869 case WAPI_AUTH_MODE_CERT:
4870 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004871 hddLog(LOG1, "%s: WAPI AUTH TYPE: CERT: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07004872 pAdapter->wapi_info.wapiAuthMode);
4873 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE;
4874 break;
4875 }
4876 } // End of switch
4877 if ( pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_PSK ||
4878 pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_CERT)
4879 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004880 hddLog(LOG1, "%s: WAPI PAIRWISE/GROUP ENCRYPTION: WPI", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004881 pRoamProfile->AuthType.numEntries = 1;
4882 pRoamProfile->EncryptionType.numEntries = 1;
4883 pRoamProfile->EncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
4884 pRoamProfile->mcEncryptionType.numEntries = 1;
4885 pRoamProfile->mcEncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
4886 }
4887 }
4888#endif /* FEATURE_WLAN_WAPI */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05304889#ifdef WLAN_FEATURE_GTK_OFFLOAD
4890 /* Initializing gtkOffloadRequestParams */
4891 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
4892 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
4893 {
4894 pHddStaCtx->gtkOffloadRequestParams.requested = FALSE;
4895 memset(&pHddStaCtx->gtkOffloadRequestParams.gtkOffloadReqParams,
4896 0, sizeof (tSirGtkOffloadParams));
4897 }
4898#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07004899 pRoamProfile->csrPersona = pAdapter->device_mode;
4900
Jeff Johnson32d95a32012-09-10 13:15:23 -07004901 if( operatingChannel )
4902 {
4903 pRoamProfile->ChannelInfo.ChannelList = &operatingChannel;
4904 pRoamProfile->ChannelInfo.numOfChannels = 1;
4905 }
Chet Lanctot186b5732013-03-18 10:26:30 -07004906 else
4907 {
4908 pRoamProfile->ChannelInfo.ChannelList = NULL;
4909 pRoamProfile->ChannelInfo.numOfChannels = 0;
4910 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07004911
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08004912 /* change conn_state to connecting before sme_RoamConnect(), because sme_RoamConnect()
4913 * has a direct path to call hdd_smeRoamCallback(), which will change the conn_state
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304914 * If direct path, conn_state will be accordingly changed to NotConnected or Associated
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08004915 * by either hdd_AssociationCompletionHandler() or hdd_DisConnectHandler() in sme_RoamCallback()
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -08004916 * if sme_RomConnect is to be queued, Connecting state will remain until it is completed.
4917 */
4918 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode)
4919 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
4920 eConnectionState_Connecting);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304921
4922 status = sme_RoamConnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07004923 pAdapter->sessionId, pRoamProfile, &roamId);
4924
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08004925 if( (eHAL_STATUS_SUCCESS != status) &&
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +05304926 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) )
4927
4928 {
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08004929 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: sme_RoamConnect (session %d) failed with "
4930 "status %d. -> NotConnected", __func__, pAdapter->sessionId, status);
4931 /* change back to NotAssociated */
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +05304932 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08004933 eConnectionState_NotConnected);
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +05304934 }
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -08004935
4936 pRoamProfile->ChannelInfo.ChannelList = NULL;
4937 pRoamProfile->ChannelInfo.numOfChannels = 0;
4938
Jeff Johnson295189b2012-06-20 16:38:30 -07004939 }
4940 else
4941 {
4942 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid Roam profile", __func__);
4943 return -EINVAL;
4944 }
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08004945 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07004946 return status;
4947}
4948
4949/*
4950 * FUNCTION: wlan_hdd_set_cfg80211_auth_type
4951 * This function is used to set the authentication type (OPEN/SHARED).
4952 *
4953 */
4954static int wlan_hdd_cfg80211_set_auth_type(hdd_adapter_t *pAdapter,
4955 enum nl80211_auth_type auth_type)
4956{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304957 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07004958 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4959
4960 ENTER();
4961
4962 /*set authentication type*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304963 switch (auth_type)
Jeff Johnson295189b2012-06-20 16:38:30 -07004964 {
4965 case NL80211_AUTHTYPE_OPEN_SYSTEM:
4966 case NL80211_AUTHTYPE_AUTOMATIC:
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07004967#ifdef WLAN_FEATURE_VOWIFI_11R
4968 case NL80211_AUTHTYPE_FT:
4969#endif /* WLAN_FEATURE_VOWIFI_11R */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304970 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -07004971 "%s: set authentication type to OPEN", __func__);
4972 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
4973 break;
4974
4975 case NL80211_AUTHTYPE_SHARED_KEY:
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 SHARED", __func__);
4978 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_SHARED_KEY;
4979 break;
4980#ifdef FEATURE_WLAN_CCX
4981 case NL80211_AUTHTYPE_NETWORK_EAP:
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 CCKM WPA", __func__);
4984 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_CCKM_WPA;//eCSR_AUTH_TYPE_CCKM_RSN needs to be handled as well if required.
4985 break;
4986#endif
4987
4988
4989 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304990 hddLog(VOS_TRACE_LEVEL_ERROR,
4991 "%s: Unsupported authentication type %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07004992 auth_type);
4993 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_UNKNOWN;
4994 return -EINVAL;
4995 }
4996
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304997 pWextState->roamProfile.AuthType.authType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -07004998 pHddStaCtx->conn_info.authType;
4999 return 0;
5000}
5001
5002/*
5003 * FUNCTION: wlan_hdd_set_akm_suite
5004 * This function is used to set the key mgmt type(PSK/8021x).
5005 *
5006 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305007static int wlan_hdd_set_akm_suite( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07005008 u32 key_mgmt
5009 )
5010{
5011 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
5012 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305013
Jeff Johnson295189b2012-06-20 16:38:30 -07005014 /*set key mgmt type*/
5015 switch(key_mgmt)
5016 {
5017 case WLAN_AKM_SUITE_PSK:
Gopichand Nakkala356fb102013-03-06 12:34:04 +05305018#ifdef WLAN_FEATURE_VOWIFI_11R
5019 case WLAN_AKM_SUITE_FT_PSK:
5020#endif
5021 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to PSK",
Jeff Johnson295189b2012-06-20 16:38:30 -07005022 __func__);
5023 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_PSK;
5024 break;
5025
5026 case WLAN_AKM_SUITE_8021X:
Gopichand Nakkala356fb102013-03-06 12:34:04 +05305027#ifdef WLAN_FEATURE_VOWIFI_11R
5028 case WLAN_AKM_SUITE_FT_8021X:
5029#endif
5030 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to 8021x",
Jeff Johnson295189b2012-06-20 16:38:30 -07005031 __func__);
5032 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
5033 break;
5034#ifdef FEATURE_WLAN_CCX
5035#define WLAN_AKM_SUITE_CCKM 0x00409600 /* Should be in ieee802_11_defs.h */
5036#define IW_AUTH_KEY_MGMT_CCKM 8 /* Should be in linux/wireless.h */
5037 case WLAN_AKM_SUITE_CCKM:
5038 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to CCKM",
5039 __func__);
5040 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_CCKM;
5041 break;
5042#endif
5043
5044 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305045 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported key mgmt type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07005046 __func__, key_mgmt);
5047 return -EINVAL;
5048
5049 }
5050 return 0;
5051}
5052
5053/*
5054 * FUNCTION: wlan_hdd_cfg80211_set_cipher
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305055 * This function is used to set the encryption type
Jeff Johnson295189b2012-06-20 16:38:30 -07005056 * (NONE/WEP40/WEP104/TKIP/CCMP).
5057 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305058static int wlan_hdd_cfg80211_set_cipher( hdd_adapter_t *pAdapter,
5059 u32 cipher,
Jeff Johnson295189b2012-06-20 16:38:30 -07005060 bool ucast
5061 )
5062{
5063 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305064 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07005065 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
5066
5067 ENTER();
5068
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305069 if (!cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -07005070 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305071 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: received cipher %d - considering none",
Jeff Johnson295189b2012-06-20 16:38:30 -07005072 __func__, cipher);
5073 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
5074 }
5075 else
5076 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305077
Jeff Johnson295189b2012-06-20 16:38:30 -07005078 /*set encryption method*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305079 switch (cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -07005080 {
5081 case IW_AUTH_CIPHER_NONE:
5082 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
5083 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305084
Jeff Johnson295189b2012-06-20 16:38:30 -07005085 case WLAN_CIPHER_SUITE_WEP40:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305086 if ((IW_AUTH_KEY_MGMT_802_1X == pWextState->authKeyMgmt) &&
Jeff Johnson295189b2012-06-20 16:38:30 -07005087 (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType))
5088 encryptionType = eCSR_ENCRYPT_TYPE_WEP40;
5089 else
5090 encryptionType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
5091 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305092
Jeff Johnson295189b2012-06-20 16:38:30 -07005093 case WLAN_CIPHER_SUITE_WEP104:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305094 if ((IW_AUTH_KEY_MGMT_802_1X == pWextState->authKeyMgmt) &&
Jeff Johnson295189b2012-06-20 16:38:30 -07005095 (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType))
5096 encryptionType = eCSR_ENCRYPT_TYPE_WEP104;
5097 else
5098 encryptionType = eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
5099 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305100
Jeff Johnson295189b2012-06-20 16:38:30 -07005101 case WLAN_CIPHER_SUITE_TKIP:
5102 encryptionType = eCSR_ENCRYPT_TYPE_TKIP;
5103 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305104
Jeff Johnson295189b2012-06-20 16:38:30 -07005105 case WLAN_CIPHER_SUITE_CCMP:
5106 encryptionType = eCSR_ENCRYPT_TYPE_AES;
5107 break;
5108#ifdef FEATURE_WLAN_WAPI
5109 case WLAN_CIPHER_SUITE_SMS4:
5110 encryptionType = eCSR_ENCRYPT_TYPE_WPI;
5111 break;
5112#endif
5113
5114#ifdef FEATURE_WLAN_CCX
5115 case WLAN_CIPHER_SUITE_KRK:
5116 encryptionType = eCSR_ENCRYPT_TYPE_KRK;
5117 break;
5118#endif
5119 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305120 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported cipher type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07005121 __func__, cipher);
5122 return -EOPNOTSUPP;
5123 }
5124 }
5125
5126 if (ucast)
5127 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305128 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting unicast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07005129 __func__, encryptionType);
5130 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
5131 pWextState->roamProfile.EncryptionType.numEntries = 1;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305132 pWextState->roamProfile.EncryptionType.encryptionType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -07005133 encryptionType;
5134 }
5135 else
5136 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305137 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting mcast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07005138 __func__, encryptionType);
5139 pHddStaCtx->conn_info.mcEncryptionType = encryptionType;
5140 pWextState->roamProfile.mcEncryptionType.numEntries = 1;
5141 pWextState->roamProfile.mcEncryptionType.encryptionType[0] = encryptionType;
5142 }
5143
5144 return 0;
5145}
5146
5147
5148/*
5149 * FUNCTION: wlan_hdd_cfg80211_set_ie
5150 * This function is used to parse WPA/RSN IE's.
5151 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305152int wlan_hdd_cfg80211_set_ie( hdd_adapter_t *pAdapter,
5153 u8 *ie,
Jeff Johnson295189b2012-06-20 16:38:30 -07005154 size_t ie_len
5155 )
5156{
5157 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
5158 u8 *genie = ie;
5159 v_U16_t remLen = ie_len;
5160#ifdef FEATURE_WLAN_WAPI
5161 v_U32_t akmsuite[MAX_NUM_AKM_SUITES];
5162 u16 *tmp;
5163 v_U16_t akmsuiteCount;
5164 int *akmlist;
5165#endif
5166 ENTER();
5167
5168 /* clear previous assocAddIE */
5169 pWextState->assocAddIE.length = 0;
5170 pWextState->roamProfile.bWPSAssociation = VOS_FALSE;
5171
5172 while (remLen >= 2)
5173 {
5174 v_U16_t eLen = 0;
5175 v_U8_t elementId;
5176 elementId = *genie++;
5177 eLen = *genie++;
5178 remLen -= 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305179
5180 hddLog(VOS_TRACE_LEVEL_INFO, "%s: IE[0x%X], LEN[%d]\n",
Jeff Johnson295189b2012-06-20 16:38:30 -07005181 __func__, elementId, eLen);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305182
5183 switch ( elementId )
Jeff Johnson295189b2012-06-20 16:38:30 -07005184 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305185 case DOT11F_EID_WPA:
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005186 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 -07005187 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305188 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07005189 "%s: Invalid WPA IE", __func__);
5190 return -EINVAL;
5191 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305192 else if (0 == memcmp(&genie[0], "\x00\x50\xf2\x04", 4))
Jeff Johnson295189b2012-06-20 16:38:30 -07005193 {
5194 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305195 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPS IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -07005196 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305197
Jeff Johnson295189b2012-06-20 16:38:30 -07005198 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
5199 {
Jeff Johnson902c9832012-12-10 14:28:09 -08005200 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE. "
5201 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -07005202 VOS_ASSERT(0);
5203 return -ENOMEM;
5204 }
5205 // WSC IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
5206 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
5207 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305208
Jeff Johnson295189b2012-06-20 16:38:30 -07005209 pWextState->roamProfile.bWPSAssociation = VOS_TRUE;
5210 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
5211 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
5212 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305213 else if (0 == memcmp(&genie[0], "\x00\x50\xf2", 3))
5214 {
Jeff Johnson295189b2012-06-20 16:38:30 -07005215 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPA IE (len %d)",__func__, eLen + 2);
5216 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
5217 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2) /*ie_len*/);
5218 pWextState->roamProfile.pWPAReqIE = pWextState->WPARSNIE;
5219 pWextState->roamProfile.nWPAReqIELength = eLen + 2;//ie_len;
5220 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305221 else if ( (0 == memcmp(&genie[0], P2P_OUI_TYPE,
5222 P2P_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07005223 /*Consider P2P IE, only for P2P Client */
5224 && (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
5225 {
5226 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305227 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set P2P IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -07005228 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305229
Jeff Johnson295189b2012-06-20 16:38:30 -07005230 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
5231 {
Jeff Johnson902c9832012-12-10 14:28:09 -08005232 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
5233 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -07005234 VOS_ASSERT(0);
5235 return -ENOMEM;
5236 }
5237 // P2P IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
5238 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
5239 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305240
Jeff Johnson295189b2012-06-20 16:38:30 -07005241 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
5242 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
5243 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005244#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305245 else if ( (0 == memcmp(&genie[0], WFD_OUI_TYPE,
5246 WFD_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07005247 /*Consider WFD IE, only for P2P Client */
5248 && (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
5249 {
5250 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305251 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WFD IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -07005252 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305253
Jeff Johnson295189b2012-06-20 16:38:30 -07005254 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
5255 {
Jeff Johnson902c9832012-12-10 14:28:09 -08005256 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
5257 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -07005258 VOS_ASSERT(0);
5259 return -ENOMEM;
5260 }
5261 // WFD IE is saved to Additional IE ; it should be accumulated to handle
5262 // WPS IE + P2P IE + WFD IE
5263 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
5264 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305265
Jeff Johnson295189b2012-06-20 16:38:30 -07005266 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
5267 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
5268 }
5269#endif
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005270 /* Appending HS 2.0 Indication Element in Assiciation Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305271 else if ( (0 == memcmp(&genie[0], HS20_OUI_TYPE,
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07005272 HS20_OUI_TYPE_SIZE)) )
5273 {
5274 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305275 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set HS20 IE(len %d)",
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07005276 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005277
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07005278 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
5279 {
Jeff Johnson902c9832012-12-10 14:28:09 -08005280 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
5281 "Need bigger buffer space");
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07005282 VOS_ASSERT(0);
5283 return -ENOMEM;
5284 }
5285 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
5286 pWextState->assocAddIE.length += eLen + 2;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005287
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07005288 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
5289 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
5290 }
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005291
Jeff Johnson295189b2012-06-20 16:38:30 -07005292 break;
5293 case DOT11F_EID_RSN:
5294 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set RSN IE(len %d)",__func__, eLen + 2);
5295 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
5296 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2)/*ie_len*/);
5297 pWextState->roamProfile.pRSNReqIE = pWextState->WPARSNIE;
5298 pWextState->roamProfile.nRSNReqIELength = eLen + 2; //ie_len;
5299 break;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005300 /* Appending Extended Capabilities with Interworking bit set in Assoc Req */
5301 case DOT11F_EID_EXTCAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305302 {
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005303 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305304 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set Extended CAPS IE(len %d)",
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005305 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305306
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005307 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
5308 {
Jeff Johnson902c9832012-12-10 14:28:09 -08005309 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
5310 "Need bigger buffer space");
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005311 VOS_ASSERT(0);
5312 return -ENOMEM;
5313 }
5314 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
5315 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305316
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005317 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
5318 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
5319 break;
5320 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005321#ifdef FEATURE_WLAN_WAPI
5322 case WLAN_EID_WAPI:
5323 pAdapter->wapi_info.nWapiMode = 1; //Setting WAPI Mode to ON=1
5324 hddLog(VOS_TRACE_LEVEL_INFO,"WAPI MODE IS %lu \n",
5325 pAdapter->wapi_info.nWapiMode);
5326 tmp = (u16 *)ie;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305327 tmp = tmp + 2; // Skip element Id and Len, Version
Jeff Johnson295189b2012-06-20 16:38:30 -07005328 akmsuiteCount = WPA_GET_LE16(tmp);
5329 tmp = tmp + 1;
5330 akmlist = (int *)(tmp);
5331 if(akmsuiteCount <= MAX_NUM_AKM_SUITES)
5332 {
5333 memcpy(akmsuite, akmlist, (4*akmsuiteCount));
5334 }
5335 else
5336 {
5337 hddLog(VOS_TRACE_LEVEL_FATAL, "Invalid akmSuite count\n");
5338 VOS_ASSERT(0);
5339 return -EINVAL;
5340 }
5341
5342 if (WAPI_PSK_AKM_SUITE == akmsuite[0])
5343 {
5344 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO PSK",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005345 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005346 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_PSK;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305347 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005348 if (WAPI_CERT_AKM_SUITE == akmsuite[0])
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305349 {
Jeff Johnson295189b2012-06-20 16:38:30 -07005350 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO CERTIFICATE",
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_CERT;
5353 }
5354 break;
5355#endif
5356 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305357 hddLog (VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07005358 "%s Set UNKNOWN IE %X", __func__, elementId);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005359 /* when Unknown IE is received we should break and continue
5360 * to the next IE in the buffer instead we were returning
5361 * so changing this to break */
5362 break;
Jeff Johnson295189b2012-06-20 16:38:30 -07005363 }
5364 genie += eLen;
5365 remLen -= eLen;
5366 }
5367 EXIT();
5368 return 0;
5369}
5370
5371/*
5372 * FUNCTION: wlan_hdd_cfg80211_set_privacy
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305373 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -07005374 * parameters during connect operation.
5375 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305376int wlan_hdd_cfg80211_set_privacy( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07005377 struct cfg80211_connect_params *req
5378 )
5379{
5380 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305381 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07005382 ENTER();
5383
5384 /*set wpa version*/
5385 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
5386
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305387 if (req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -07005388 {
5389 if ( (NL80211_WPA_VERSION_1 == req->crypto.wpa_versions)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305390 && ( (req->ie_len)
5391 && (0 == memcmp( &req->ie[2], "\x00\x50\xf2",3) ) ) )
Jeff Johnson295189b2012-06-20 16:38:30 -07005392 // Make sure that it is including a WPA IE.
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305393 /* Currently NL is putting WPA version 1 even for open,
Jeff Johnson295189b2012-06-20 16:38:30 -07005394 * since p2p ie is also put in same buffer.
5395 * */
5396 {
5397 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
5398 }
5399 else if (NL80211_WPA_VERSION_2 == req->crypto.wpa_versions)
5400 {
5401 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
5402 }
5403 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305404
5405 hddLog(VOS_TRACE_LEVEL_INFO, "%s: set wpa version to %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07005406 pWextState->wpaVersion);
5407
5408 /*set authentication type*/
5409 status = wlan_hdd_cfg80211_set_auth_type(pAdapter, req->auth_type);
5410
5411 if (0 > status)
5412 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305413 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07005414 "%s: failed to set authentication type ", __func__);
5415 return status;
5416 }
5417
5418 /*set key mgmt type*/
5419 if (req->crypto.n_akm_suites)
5420 {
5421 status = wlan_hdd_set_akm_suite(pAdapter, req->crypto.akm_suites[0]);
5422 if (0 > status)
5423 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305424 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set akm suite",
Jeff Johnson295189b2012-06-20 16:38:30 -07005425 __func__);
5426 return status;
5427 }
5428 }
5429
5430 /*set pairwise cipher type*/
5431 if (req->crypto.n_ciphers_pairwise)
5432 {
5433 status = wlan_hdd_cfg80211_set_cipher(pAdapter,
5434 req->crypto.ciphers_pairwise[0], true);
5435 if (0 > status)
5436 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305437 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07005438 "%s: failed to set unicast cipher type", __func__);
5439 return status;
5440 }
5441 }
5442 else
5443 {
5444 /*Reset previous cipher suite to none*/
5445 status = wlan_hdd_cfg80211_set_cipher(pAdapter, 0, true);
5446 if (0 > status)
5447 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305448 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07005449 "%s: failed to set unicast cipher type", __func__);
5450 return status;
5451 }
5452 }
5453
5454 /*set group cipher type*/
5455 status = wlan_hdd_cfg80211_set_cipher(pAdapter, req->crypto.cipher_group,
5456 false);
5457
5458 if (0 > status)
5459 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305460 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set mcast cipher type",
Jeff Johnson295189b2012-06-20 16:38:30 -07005461 __func__);
5462 return status;
5463 }
5464
Chet Lanctot186b5732013-03-18 10:26:30 -07005465#ifdef WLAN_FEATURE_11W
5466 pWextState->roamProfile.MFPEnabled = (req->mfp == NL80211_MFP_REQUIRED);
5467#endif
5468
Jeff Johnson295189b2012-06-20 16:38:30 -07005469 /*parse WPA/RSN IE, and set the correspoing fileds in Roam profile*/
5470 if (req->ie_len)
5471 {
5472 status = wlan_hdd_cfg80211_set_ie(pAdapter, req->ie, req->ie_len);
5473 if ( 0 > status)
5474 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305475 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse the WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -07005476 __func__);
5477 return status;
5478 }
5479 }
5480
5481 /*incase of WEP set default key information*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305482 if (req->key && req->key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -07005483 {
5484 if ( (WLAN_CIPHER_SUITE_WEP40 == req->crypto.ciphers_pairwise[0])
5485 || (WLAN_CIPHER_SUITE_WEP104 == req->crypto.ciphers_pairwise[0])
5486 )
5487 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305488 if ( IW_AUTH_KEY_MGMT_802_1X
Jeff Johnson295189b2012-06-20 16:38:30 -07005489 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X ))
5490 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305491 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Dynamic WEP not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -07005492 __func__);
5493 return -EOPNOTSUPP;
5494 }
5495 else
5496 {
5497 u8 key_len = req->key_len;
5498 u8 key_idx = req->key_idx;
5499
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305500 if ((eCSR_SECURITY_WEP_KEYSIZE_MAX_BYTES >= key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -07005501 && (CSR_MAX_NUM_KEY > key_idx)
5502 )
5503 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305504 hddLog(VOS_TRACE_LEVEL_INFO,
5505 "%s: setting default wep key, key_idx = %hu key_len %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07005506 __func__, key_idx, key_len);
5507 vos_mem_copy(
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305508 &pWextState->roamProfile.Keys.KeyMaterial[key_idx][0],
Jeff Johnson295189b2012-06-20 16:38:30 -07005509 req->key, key_len);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305510 pWextState->roamProfile.Keys.KeyLength[key_idx] =
Jeff Johnson295189b2012-06-20 16:38:30 -07005511 (u8)key_len;
5512 pWextState->roamProfile.Keys.defaultIndex = (u8)key_idx;
5513 }
5514 }
5515 }
5516 }
5517
5518 return status;
5519}
5520
5521/*
5522 * FUNCTION: wlan_hdd_cfg80211_set_privacy
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305523 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -07005524 * parameters during connect operation.
5525 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305526static int wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07005527 struct net_device *ndev,
5528 struct cfg80211_connect_params *req
5529 )
5530{
5531 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305532 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -07005533 VOS_STATUS exitbmpsStatus = VOS_STATUS_E_INVAL;
5534 hdd_context_t *pHddCtx = NULL;
5535
5536 ENTER();
5537
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305538 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -07005539 "%s: device_mode = %d\n",__func__,pAdapter->device_mode);
5540
5541 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
5542 {
5543 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5544 "%s:LOGP in Progress. Ignore!!!", __func__);
5545 return -EAGAIN;
5546 }
5547
5548#ifdef WLAN_BTAMP_FEATURE
5549 //Infra connect not supported when AMP traffic is on.
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305550 if( VOS_TRUE == WLANBAP_AmpSessionOn() )
Jeff Johnson295189b2012-06-20 16:38:30 -07005551 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305552 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07005553 "%s: No connection when AMP is on", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08005554 return -ECONNREFUSED;
Jeff Johnson295189b2012-06-20 16:38:30 -07005555 }
5556#endif
5557 /*initialise security parameters*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305558 status = wlan_hdd_cfg80211_set_privacy(pAdapter, req);
Jeff Johnson295189b2012-06-20 16:38:30 -07005559
5560 if ( 0 > status)
5561 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305562 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security params",
Jeff Johnson295189b2012-06-20 16:38:30 -07005563 __func__);
5564 return status;
5565 }
5566
5567 //If Device Mode is Station Concurrent Sessions Exit BMps
Jeff Johnsona8a1a482012-12-12 16:49:33 -08005568 //P2P Mode will be taken care in Open/close adapter
Jeff Johnson295189b2012-06-20 16:38:30 -07005569 if((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
5570 (vos_concurrent_sessions_running()))
5571 {
5572 v_CONTEXT_t pVosContext = vos_get_global_context( VOS_MODULE_ID_HDD, NULL );
5573
5574 if (NULL != pVosContext)
5575 {
5576 pHddCtx = vos_get_context( VOS_MODULE_ID_HDD, pVosContext);
5577 if(NULL != pHddCtx)
5578 {
5579 exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
5580 }
5581 }
5582 }
5583
Mohit Khanna765234a2012-09-11 15:08:35 -07005584 if ( req->channel )
5585 {
5586 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
5587 req->ssid_len, req->bssid,
5588 req->channel->hw_value);
5589 }
5590 else
5591 {
5592 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
5593 req->ssid_len, req->bssid,
5594 0);
5595 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005596
5597 if (0 > status)
5598 {
5599 //ReEnable BMPS if disabled
5600 if((VOS_STATUS_SUCCESS == exitbmpsStatus) &&
5601 (NULL != pHddCtx))
5602 {
5603 //ReEnable Bmps and Imps back
5604 hdd_enable_bmps_imps(pHddCtx);
5605 }
5606
5607 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: connect failed", __func__);
5608 return status;
5609 }
5610 (WLAN_HDD_GET_CTX(pAdapter))->isAmpAllowed = VOS_FALSE;
5611 EXIT();
5612 return status;
5613}
5614
5615
5616/*
5617 * FUNCTION: wlan_hdd_cfg80211_disconnect
5618 * This function is used to issue a disconnect request to SME
5619 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305620static int wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07005621 struct net_device *dev,
5622 u16 reason
5623 )
5624{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305625 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
5626 tCsrRoamProfile *pRoamProfile =
Jeff Johnson295189b2012-06-20 16:38:30 -07005627 &(WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter))->roamProfile;
5628 int status = 0;
5629 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08005630#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala4327a152013-03-04 23:22:42 -08005631 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08005632 tANI_U8 staIdx;
5633#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305634
Jeff Johnson295189b2012-06-20 16:38:30 -07005635 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305636
5637 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",
Jeff Johnson295189b2012-06-20 16:38:30 -07005638 __func__,pAdapter->device_mode);
5639
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305640 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Disconnect called with reason code %d",
5641 __func__, reason);
Jeff Johnson295189b2012-06-20 16:38:30 -07005642
5643 if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress)
5644 {
5645 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5646 "%s:LOGP in Progress. Ignore!!!",__func__);
5647 return -EAGAIN;
5648 }
5649 if (NULL != pRoamProfile)
5650 {
5651 /*issue disconnect request to SME, if station is in connected state*/
5652 if (pHddStaCtx->conn_info.connState == eConnectionState_Associated)
5653 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305654 eCsrRoamDisconnectReason reasonCode =
Jeff Johnson295189b2012-06-20 16:38:30 -07005655 eCSR_DISCONNECT_REASON_UNSPECIFIED;
5656 switch(reason)
5657 {
5658 case WLAN_REASON_MIC_FAILURE:
5659 reasonCode = eCSR_DISCONNECT_REASON_MIC_ERROR;
5660 break;
5661
5662 case WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY:
5663 case WLAN_REASON_DISASSOC_AP_BUSY:
5664 case WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA:
5665 reasonCode = eCSR_DISCONNECT_REASON_DISASSOC;
5666 break;
5667
5668 case WLAN_REASON_PREV_AUTH_NOT_VALID:
5669 case WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA:
5670 reasonCode = eCSR_DISCONNECT_REASON_DEAUTH;
5671 break;
5672
5673 case WLAN_REASON_DEAUTH_LEAVING:
5674 default:
5675 reasonCode = eCSR_DISCONNECT_REASON_UNSPECIFIED;
5676 break;
5677 }
5678 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
5679 (WLAN_HDD_GET_CTX(pAdapter))->isAmpAllowed = VOS_TRUE;
5680 INIT_COMPLETION(pAdapter->disconnect_comp_var);
5681
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08005682#ifdef FEATURE_WLAN_TDLS
5683 /* First clean up the tdls peers if any */
Gopichand Nakkala4327a152013-03-04 23:22:42 -08005684 for (staIdx = 0 ; staIdx < HDD_MAX_NUM_TDLS_STA; staIdx++)
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08005685 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -08005686 if ((pHddCtx->tdlsConnInfo[staIdx].sessionId == pAdapter->sessionId) &&
5687 (pHddCtx->tdlsConnInfo[staIdx].staId))
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08005688 {
Hoonki Lee11f7dda2013-02-14 16:55:44 -08005689 uint8 *mac;
Gopichand Nakkala4327a152013-03-04 23:22:42 -08005690 mac = pHddCtx->tdlsConnInfo[staIdx].peerMac.bytes;
Hoonki Lee11f7dda2013-02-14 16:55:44 -08005691 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07005692 "%s: call sme_DeleteTdlsPeerSta staId %d sessionId %d " MAC_ADDRESS_STR,
Gopichand Nakkala4327a152013-03-04 23:22:42 -08005693 __func__, pHddCtx->tdlsConnInfo[staIdx].staId, pAdapter->sessionId,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07005694 MAC_ADDR_ARRAY(mac));
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08005695 sme_DeleteTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala4327a152013-03-04 23:22:42 -08005696 pAdapter->sessionId,
5697 mac);
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08005698 }
5699 }
5700#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005701 /*issue disconnect*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305702 status = sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07005703 pAdapter->sessionId, reasonCode);
5704
5705 if ( 0 != status)
5706 {
5707 hddLog(VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305708 "%s csrRoamDisconnect failure, returned %d \n",
Jeff Johnson295189b2012-06-20 16:38:30 -07005709 __func__, (int)status );
5710 return -EINVAL;
5711 }
5712
5713 wait_for_completion_interruptible_timeout(
5714 &pAdapter->disconnect_comp_var,
5715 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
5716
5717
5718 /*stop tx queues*/
5719 netif_tx_disable(dev);
5720 netif_carrier_off(dev);
5721 }
5722 }
5723 else
5724 {
5725 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid roam profile", __func__);
5726 }
5727
5728 return status;
5729}
5730
5731/*
5732 * FUNCTION: wlan_hdd_cfg80211_set_privacy_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305733 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -07005734 * settings in IBSS mode.
5735 */
5736static int wlan_hdd_cfg80211_set_privacy_ibss(
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305737 hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07005738 struct cfg80211_ibss_params *params
5739 )
5740{
5741 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305742 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07005743 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
5744 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305745
Jeff Johnson295189b2012-06-20 16:38:30 -07005746 ENTER();
5747
5748 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
5749
5750 if (params->ie_len && ( NULL != params->ie) )
5751 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305752 if (WLAN_EID_RSN == params->ie[0])
Jeff Johnson295189b2012-06-20 16:38:30 -07005753 {
5754 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
5755 encryptionType = eCSR_ENCRYPT_TYPE_AES;
5756 }
5757 else
5758 {
5759 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
5760 encryptionType = eCSR_ENCRYPT_TYPE_TKIP;
5761 }
5762 status = wlan_hdd_cfg80211_set_ie(pAdapter, params->ie, params->ie_len);
5763
5764 if (0 > status)
5765 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305766 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -07005767 __func__);
5768 return status;
5769 }
5770 }
5771
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305772 pWextState->roamProfile.AuthType.authType[0] =
5773 pHddStaCtx->conn_info.authType =
Jeff Johnson295189b2012-06-20 16:38:30 -07005774 eCSR_AUTH_TYPE_OPEN_SYSTEM;
5775
5776 if (params->privacy)
5777 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305778 /* Security enabled IBSS, At this time there is no information available
5779 * about the security paramters, so initialise the encryption type to
Jeff Johnson295189b2012-06-20 16:38:30 -07005780 * eCSR_ENCRYPT_TYPE_WEP40_STATICKEY.
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305781 * The correct security parameters will be updated later in
Jeff Johnson295189b2012-06-20 16:38:30 -07005782 * wlan_hdd_cfg80211_add_key */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305783 /* Hal expects encryption type to be set inorder
Jeff Johnson295189b2012-06-20 16:38:30 -07005784 *enable privacy bit in beacons */
5785
5786 encryptionType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
5787 }
5788
5789 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
5790 pWextState->roamProfile.EncryptionType.numEntries = 1;
5791 pWextState->roamProfile.EncryptionType.encryptionType[0] = encryptionType;
5792
5793 return status;
5794}
5795
5796/*
5797 * FUNCTION: wlan_hdd_cfg80211_join_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305798 * This function is used to create/join an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -07005799 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305800static int wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07005801 struct net_device *dev,
5802 struct cfg80211_ibss_params *params
5803 )
5804{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305805 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Jeff Johnson295189b2012-06-20 16:38:30 -07005806 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
5807 tCsrRoamProfile *pRoamProfile;
5808 int status;
5809 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
5810
5811 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305812
5813 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -07005814 "%s: device_mode = %d\n",__func__,pAdapter->device_mode);
5815
5816 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
5817 {
5818 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5819 "%s:LOGP in Progress. Ignore!!!", __func__);
5820 return -EAGAIN;
5821 }
5822
5823 if (NULL == pWextState)
5824 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305825 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption\n",
Jeff Johnson295189b2012-06-20 16:38:30 -07005826 __func__);
5827 return -EIO;
5828 }
5829
5830 pRoamProfile = &pWextState->roamProfile;
5831
5832 if ( eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType )
5833 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305834 hddLog (VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07005835 "%s Interface type is not set to IBSS \n", __func__);
5836 return -EINVAL;
5837 }
5838
5839 /* Set Channel */
5840 if (NULL != params->channel)
5841 {
5842 u8 channelNum;
5843 if (IEEE80211_BAND_5GHZ == params->channel->band)
5844 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305845 hddLog(VOS_TRACE_LEVEL_ERROR,
5846 "%s: IBSS join is called with unsupported band %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07005847 __func__, params->channel->band);
5848 return -EOPNOTSUPP;
5849 }
5850
5851 /* Get channel number */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305852 channelNum =
Jeff Johnson295189b2012-06-20 16:38:30 -07005853 ieee80211_frequency_to_channel(params->channel->center_freq);
5854
5855 /*TODO: use macro*/
5856 if (14 >= channelNum)
5857 {
5858 v_U32_t numChans = WNI_CFG_VALID_CHANNEL_LIST_LEN;
5859 v_U8_t validChan[WNI_CFG_VALID_CHANNEL_LIST_LEN];
5860 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
5861 int indx;
5862
5863 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
5864 validChan, &numChans))
5865 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305866 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid channel list",
Jeff Johnson295189b2012-06-20 16:38:30 -07005867 __func__);
5868 return -EOPNOTSUPP;
5869 }
5870
5871 for (indx = 0; indx < numChans; indx++)
5872 {
5873 if (channelNum == validChan[indx])
5874 {
5875 break;
5876 }
5877 }
5878 if (indx >= numChans)
5879 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305880 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Not valid Channel %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07005881 __func__, channelNum);
5882 return -EINVAL;
5883 }
5884 /* Set the Operational Channel */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305885 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: set channel %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07005886 channelNum);
5887 pRoamProfile->ChannelInfo.numOfChannels = 1;
5888 pHddStaCtx->conn_info.operationChannel = channelNum;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305889 pRoamProfile->ChannelInfo.ChannelList =
Jeff Johnson295189b2012-06-20 16:38:30 -07005890 &pHddStaCtx->conn_info.operationChannel;
5891 }
5892 else
5893 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305894 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Not valid Channel %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07005895 __func__, channelNum);
5896 return -EINVAL;
5897 }
5898 }
5899
5900 /* Initialize security parameters */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305901 status = wlan_hdd_cfg80211_set_privacy_ibss(pAdapter, params);
Jeff Johnson295189b2012-06-20 16:38:30 -07005902 if (status < 0)
5903 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305904 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security parameters",
Jeff Johnson295189b2012-06-20 16:38:30 -07005905 __func__);
5906 return status;
5907 }
5908
5909 /* Issue connect start */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305910 status = wlan_hdd_cfg80211_connect_start(pAdapter, params->ssid,
Jeff Johnson32d95a32012-09-10 13:15:23 -07005911 params->ssid_len, params->bssid, 0);
Jeff Johnson295189b2012-06-20 16:38:30 -07005912
5913 if (0 > status)
5914 {
5915 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: connect failed", __func__);
5916 return status;
5917 }
5918
5919 return 0;
5920}
5921
5922/*
5923 * FUNCTION: wlan_hdd_cfg80211_leave_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305924 * This function is used to leave an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -07005925 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305926static int wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07005927 struct net_device *dev
5928 )
5929{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305930 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Jeff Johnson295189b2012-06-20 16:38:30 -07005931 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
5932 tCsrRoamProfile *pRoamProfile;
5933
5934 ENTER();
5935
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005936 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
5937 {
5938 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5939 "%s:LOGP in Progress. Ignore!!!", __func__);
5940 return -EAGAIN;
5941 }
5942
Jeff Johnson295189b2012-06-20 16:38:30 -07005943 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",__func__,pAdapter->device_mode);
5944 if (NULL == pWextState)
5945 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305946 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption\n",
Jeff Johnson295189b2012-06-20 16:38:30 -07005947 __func__);
5948 return -EIO;
5949 }
5950
5951 pRoamProfile = &pWextState->roamProfile;
5952
5953 /* Issue disconnect only if interface type is set to IBSS */
5954 if (eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType)
5955 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305956 hddLog (VOS_TRACE_LEVEL_ERROR, "%s: BSS Type is not set to IBSS",
Jeff Johnson295189b2012-06-20 16:38:30 -07005957 __func__);
5958 return -EINVAL;
5959 }
5960
5961 /* Issue Disconnect request */
5962 INIT_COMPLETION(pAdapter->disconnect_comp_var);
5963 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
5964 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
5965
5966 return 0;
5967}
5968
5969/*
5970 * FUNCTION: wlan_hdd_cfg80211_set_wiphy_params
5971 * This function is used to set the phy parameters
5972 * (RTS Threshold/FRAG Threshold/Retry Count etc ...)
5973 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305974static int wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07005975 u32 changed)
5976{
5977 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5978 tHalHandle hHal = pHddCtx->hHal;
5979
5980 ENTER();
5981
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005982 if ( pHddCtx->isLogpInProgress )
5983 {
5984 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5985 "%s:LOGP in Progress. Ignore!!!", __func__);
5986 return -EAGAIN;
5987 }
5988
Jeff Johnson295189b2012-06-20 16:38:30 -07005989 if (changed & WIPHY_PARAM_RTS_THRESHOLD)
5990 {
5991 u16 rts_threshold = (wiphy->rts_threshold == -1) ?
5992 WNI_CFG_RTS_THRESHOLD_STAMAX :
5993 wiphy->rts_threshold;
5994
5995 if ((WNI_CFG_RTS_THRESHOLD_STAMIN > rts_threshold) ||
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305996 (WNI_CFG_RTS_THRESHOLD_STAMAX < rts_threshold))
Jeff Johnson295189b2012-06-20 16:38:30 -07005997 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305998 hddLog(VOS_TRACE_LEVEL_ERROR,
5999 "%s: Invalid RTS Threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07006000 __func__, rts_threshold);
6001 return -EINVAL;
6002 }
6003
6004 if (0 != ccmCfgSetInt(hHal, WNI_CFG_RTS_THRESHOLD,
6005 rts_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306006 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -07006007 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306008 hddLog(VOS_TRACE_LEVEL_ERROR,
6009 "%s: ccmCfgSetInt failed for rts_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07006010 __func__, rts_threshold);
6011 return -EIO;
6012 }
6013
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306014 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set rts threshold %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07006015 rts_threshold);
6016 }
6017
6018 if (changed & WIPHY_PARAM_FRAG_THRESHOLD)
6019 {
6020 u16 frag_threshold = (wiphy->frag_threshold == -1) ?
6021 WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX :
6022 wiphy->frag_threshold;
6023
6024 if ((WNI_CFG_FRAGMENTATION_THRESHOLD_STAMIN > frag_threshold)||
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306025 (WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX < frag_threshold) )
Jeff Johnson295189b2012-06-20 16:38:30 -07006026 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306027 hddLog(VOS_TRACE_LEVEL_ERROR,
6028 "%s: Invalid frag_threshold value %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07006029 frag_threshold);
6030 return -EINVAL;
6031 }
6032
6033 if (0 != ccmCfgSetInt(hHal, WNI_CFG_FRAGMENTATION_THRESHOLD,
6034 frag_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306035 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -07006036 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306037 hddLog(VOS_TRACE_LEVEL_ERROR,
6038 "%s: ccmCfgSetInt failed for frag_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07006039 __func__, frag_threshold);
6040 return -EIO;
6041 }
6042
6043 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set frag threshold %hu", __func__,
6044 frag_threshold);
6045 }
6046
6047 if ((changed & WIPHY_PARAM_RETRY_SHORT)
6048 || (changed & WIPHY_PARAM_RETRY_LONG))
6049 {
6050 u8 retry_value = (changed & WIPHY_PARAM_RETRY_SHORT) ?
6051 wiphy->retry_short :
6052 wiphy->retry_long;
6053
6054 if ((WNI_CFG_LONG_RETRY_LIMIT_STAMIN > retry_value) ||
6055 (WNI_CFG_LONG_RETRY_LIMIT_STAMAX < retry_value))
6056 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306057 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07006058 __func__, retry_value);
6059 return -EINVAL;
6060 }
6061
6062 if (changed & WIPHY_PARAM_RETRY_SHORT)
6063 {
6064 if (0 != ccmCfgSetInt(hHal, WNI_CFG_LONG_RETRY_LIMIT,
6065 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306066 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -07006067 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306068 hddLog(VOS_TRACE_LEVEL_ERROR,
6069 "%s: ccmCfgSetInt failed for long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07006070 __func__, retry_value);
6071 return -EIO;
6072 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306073 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07006074 __func__, retry_value);
6075 }
6076 else if (changed & WIPHY_PARAM_RETRY_SHORT)
6077 {
6078 if (0 != ccmCfgSetInt(hHal, WNI_CFG_SHORT_RETRY_LIMIT,
6079 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306080 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -07006081 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306082 hddLog(VOS_TRACE_LEVEL_ERROR,
6083 "%s: ccmCfgSetInt failed for short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07006084 __func__, retry_value);
6085 return -EIO;
6086 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306087 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07006088 __func__, retry_value);
6089 }
6090 }
6091
6092 return 0;
6093}
6094
6095/*
6096 * FUNCTION: wlan_hdd_cfg80211_set_txpower
6097 * This function is used to set the txpower
6098 */
6099static int wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
6100#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306101 enum tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -07006102#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306103 enum nl80211_tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -07006104#endif
6105 int dbm)
6106{
6107 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
6108 tHalHandle hHal = pHddCtx->hHal;
6109 tSirMacAddr bssid = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
6110 tSirMacAddr selfMac = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
6111
6112 ENTER();
6113
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306114 if (0 != ccmCfgSetInt(hHal, WNI_CFG_CURRENT_TX_POWER_LEVEL,
6115 dbm, ccmCfgSetCallback,
6116 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -07006117 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306118 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07006119 "%s: ccmCfgSetInt failed for tx power %hu", __func__, dbm);
6120 return -EIO;
6121 }
6122
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006123 if ( pHddCtx->isLogpInProgress )
6124 {
6125 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6126 "%s:LOGP in Progress. Ignore!!!", __func__);
6127 return -EAGAIN;
6128 }
6129
Jeff Johnson295189b2012-06-20 16:38:30 -07006130 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set tx power level %d dbm", __func__,
6131 dbm);
6132
6133 switch(type)
6134 {
6135 case NL80211_TX_POWER_AUTOMATIC: /*automatically determine transmit power*/
6136 /* Fall through */
6137 case NL80211_TX_POWER_LIMITED: /*limit TX power by the mBm parameter*/
6138 if( sme_SetMaxTxPower(hHal, bssid, selfMac, dbm) != eHAL_STATUS_SUCCESS )
6139 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306140 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Setting maximum tx power failed",
6141 __func__);
6142 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -07006143 }
6144 break;
6145 case NL80211_TX_POWER_FIXED: /*fix TX power to the mBm parameter*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306146 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: NL80211_TX_POWER_FIXED not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -07006147 __func__);
6148 return -EOPNOTSUPP;
6149 break;
6150 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306151 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid power setting type %d",
6152 __func__, type);
Jeff Johnson295189b2012-06-20 16:38:30 -07006153 return -EIO;
6154 }
6155
6156 return 0;
6157}
6158
6159/*
6160 * FUNCTION: wlan_hdd_cfg80211_get_txpower
6161 * This function is used to read the txpower
6162 */
6163static int wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy, int *dbm)
6164{
6165
6166 hdd_adapter_t *pAdapter;
6167 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
6168
Jeff Johnsone7245742012-09-05 17:12:55 -07006169 ENTER();
6170
Jeff Johnson295189b2012-06-20 16:38:30 -07006171 if (NULL == pHddCtx)
6172 {
6173 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD context is Null",__func__);
6174 *dbm = 0;
6175 return -ENOENT;
6176 }
6177
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006178 if ( pHddCtx->isLogpInProgress )
6179 {
6180 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6181 "%s:LOGP in Progress. Ignore!!!", __func__);
6182 return -EAGAIN;
6183 }
6184
Jeff Johnson295189b2012-06-20 16:38:30 -07006185 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
6186 if (NULL == pAdapter)
6187 {
6188 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Not in station context " ,__func__);
6189 return -ENOENT;
6190 }
6191
6192 wlan_hdd_get_classAstats(pAdapter);
6193 *dbm = pAdapter->hdd_stats.ClassA_stat.max_pwr;
6194
Jeff Johnsone7245742012-09-05 17:12:55 -07006195 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07006196 return 0;
6197}
6198
6199static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
6200 u8* mac, struct station_info *sinfo)
6201{
6202 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
6203 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6204 int ssidlen = pHddStaCtx->conn_info.SSID.SSID.length;
6205 tANI_U8 rate_flags;
6206
6207 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
6208 hdd_config_t *pCfg = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -07006209
6210 tANI_U8 OperationalRates[CSR_DOT11_SUPPORTED_RATES_MAX];
6211 tANI_U32 ORLeng = CSR_DOT11_SUPPORTED_RATES_MAX;
6212 tANI_U8 ExtendedRates[CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX];
6213 tANI_U32 ERLeng = CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX;
6214 tANI_U8 MCSRates[SIZE_OF_BASIC_MCS_SET];
6215 tANI_U32 MCSLeng = SIZE_OF_BASIC_MCS_SET;
6216 tANI_U16 maxRate = 0;
6217 tANI_U16 myRate;
6218 tANI_U16 currentRate = 0;
6219 tANI_U8 maxSpeedMCS = 0;
6220 tANI_U8 maxMCSIdx = 0;
6221 tANI_U8 rateFlag = 1;
6222 tANI_U8 i, j, rssidx;
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07006223 tANI_U16 temp;
Jeff Johnson295189b2012-06-20 16:38:30 -07006224
Leo Chang6f8870f2013-03-26 18:11:36 -07006225#ifdef WLAN_FEATURE_11AC
6226 tANI_U32 vht_mcs_map;
6227 eDataRate11ACMaxMcs vhtMaxMcs;
6228#endif /* WLAN_FEATURE_11AC */
6229
Jeff Johnsone7245742012-09-05 17:12:55 -07006230 ENTER();
6231
Jeff Johnson295189b2012-06-20 16:38:30 -07006232 if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) ||
6233 (0 == ssidlen))
6234 {
6235 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Not associated or"
6236 " Invalid ssidlen, %d", __func__, ssidlen);
6237 /*To keep GUI happy*/
6238 return 0;
6239 }
6240
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006241 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
6242 {
6243 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6244 "%s:LOGP in Progress. Ignore!!!", __func__);
6245 return -EAGAIN;
6246 }
6247
Jeff Johnson295189b2012-06-20 16:38:30 -07006248 wlan_hdd_get_rssi(pAdapter, &sinfo->signal);
6249 sinfo->filled |= STATION_INFO_SIGNAL;
6250
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -07006251 wlan_hdd_get_station_stats(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07006252 rate_flags = pAdapter->hdd_stats.ClassA_stat.tx_rate_flags;
6253
6254 //convert to the UI units of 100kbps
6255 myRate = pAdapter->hdd_stats.ClassA_stat.tx_rate * 5;
6256
6257#ifdef LINKSPEED_DEBUG_ENABLED
Leo Chang6f8870f2013-03-26 18:11:36 -07006258 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 -07006259 sinfo->signal,
6260 pCfg->reportMaxLinkSpeed,
6261 myRate,
6262 (int) pCfg->linkSpeedRssiHigh,
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07006263 (int) pCfg->linkSpeedRssiMid,
6264 (int) pCfg->linkSpeedRssiLow,
Leo Chang6f8870f2013-03-26 18:11:36 -07006265 (int) rate_flags,
6266 (int) pAdapter->hdd_stats.ClassA_stat.mcs_index);
Jeff Johnson295189b2012-06-20 16:38:30 -07006267#endif //LINKSPEED_DEBUG_ENABLED
6268
6269 if (eHDD_LINK_SPEED_REPORT_ACTUAL != pCfg->reportMaxLinkSpeed)
6270 {
6271 // we do not want to necessarily report the current speed
6272 if (eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed)
6273 {
6274 // report the max possible speed
6275 rssidx = 0;
6276 }
6277 else if (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed)
6278 {
6279 // report the max possible speed with RSSI scaling
6280 if (sinfo->signal >= pCfg->linkSpeedRssiHigh)
6281 {
6282 // report the max possible speed
6283 rssidx = 0;
6284 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07006285 else if (sinfo->signal >= pCfg->linkSpeedRssiMid)
Jeff Johnson295189b2012-06-20 16:38:30 -07006286 {
6287 // report middle speed
6288 rssidx = 1;
6289 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07006290 else if (sinfo->signal >= pCfg->linkSpeedRssiLow)
6291 {
6292 // report middle speed
6293 rssidx = 2;
6294 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006295 else
6296 {
6297 // report actual speed
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07006298 rssidx = 3;
Jeff Johnson295189b2012-06-20 16:38:30 -07006299 }
6300 }
6301 else
6302 {
6303 // unknown, treat as eHDD_LINK_SPEED_REPORT_MAX
6304 hddLog(VOS_TRACE_LEVEL_ERROR,
6305 "%s: Invalid value for reportMaxLinkSpeed: %u",
6306 __func__, pCfg->reportMaxLinkSpeed);
6307 rssidx = 0;
6308 }
6309
6310 maxRate = 0;
6311
6312 /* Get Basic Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +05306313 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_OPERATIONAL_RATE_SET,
6314 OperationalRates, &ORLeng))
6315 {
6316 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
6317 /*To keep GUI happy*/
6318 return 0;
6319 }
6320
Jeff Johnson295189b2012-06-20 16:38:30 -07006321 for (i = 0; i < ORLeng; i++)
6322 {
Jeff Johnsone7245742012-09-05 17:12:55 -07006323 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -07006324 {
6325 /* Validate Rate Set */
6326 if (supported_data_rate[j].beacon_rate_index == (OperationalRates[i] & 0x7F))
6327 {
6328 currentRate = supported_data_rate[j].supported_rate[rssidx];
6329 break;
6330 }
6331 }
6332 /* Update MAX rate */
6333 maxRate = (currentRate > maxRate)?currentRate:maxRate;
6334 }
6335
6336 /* Get Extended Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +05306337 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET,
6338 ExtendedRates, &ERLeng))
6339 {
6340 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
6341 /*To keep GUI happy*/
6342 return 0;
6343 }
6344
Jeff Johnson295189b2012-06-20 16:38:30 -07006345 for (i = 0; i < ERLeng; i++)
6346 {
Jeff Johnsone7245742012-09-05 17:12:55 -07006347 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -07006348 {
6349 if (supported_data_rate[j].beacon_rate_index == (ExtendedRates[i] & 0x7F))
6350 {
6351 currentRate = supported_data_rate[j].supported_rate[rssidx];
6352 break;
6353 }
6354 }
6355 /* Update MAX rate */
6356 maxRate = (currentRate > maxRate)?currentRate:maxRate;
6357 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006358 /* Get MCS Rate Set -- but only if we are connected at MCS
6359 rates or if we are always reporting max speed or if we have
6360 good rssi */
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07006361 if ((0 == rssidx) && !(rate_flags & eHAL_TX_RATE_LEGACY))
Jeff Johnson295189b2012-06-20 16:38:30 -07006362 {
Gopichand Nakkala05ab1322013-02-15 11:28:38 +05306363 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_CURRENT_MCS_SET,
6364 MCSRates, &MCSLeng))
6365 {
6366 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
6367 /*To keep GUI happy*/
6368 return 0;
6369 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006370 rateFlag = 0;
Leo Chang6f8870f2013-03-26 18:11:36 -07006371#ifdef WLAN_FEATURE_11AC
6372 /* VHT80 rate has seperate rate table */
Gopichand Nakkala4c705372013-04-24 13:20:33 +05306373 if (rate_flags & (eHAL_TX_RATE_VHT20|eHAL_TX_RATE_VHT40|eHAL_TX_RATE_VHT80))
Jeff Johnson295189b2012-06-20 16:38:30 -07006374 {
Leo Chang6f8870f2013-03-26 18:11:36 -07006375 ccmCfgGetInt(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_VHT_TX_MCS_MAP, &vht_mcs_map);
Gopichand Nakkala4c705372013-04-24 13:20:33 +05306376 vhtMaxMcs = (eDataRate11ACMaxMcs)(vht_mcs_map & DATA_RATE_11AC_MCS_MASK );
Leo Chang6f8870f2013-03-26 18:11:36 -07006377 if (rate_flags & eHAL_TX_RATE_SGI)
Jeff Johnson295189b2012-06-20 16:38:30 -07006378 {
Leo Chang6f8870f2013-03-26 18:11:36 -07006379 rateFlag |= 1;
Jeff Johnson295189b2012-06-20 16:38:30 -07006380 }
Leo Chang6f8870f2013-03-26 18:11:36 -07006381 if (DATA_RATE_11AC_MAX_MCS_7 == vhtMaxMcs)
Jeff Johnson295189b2012-06-20 16:38:30 -07006382 {
Leo Chang6f8870f2013-03-26 18:11:36 -07006383 maxMCSIdx = 7;
6384 }
6385 else if (DATA_RATE_11AC_MAX_MCS_8 == vhtMaxMcs)
6386 {
6387 maxMCSIdx = 8;
6388 }
6389 else if (DATA_RATE_11AC_MAX_MCS_9 == vhtMaxMcs)
6390 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +05306391 //VHT20 is supporting 0~8
6392 if (rate_flags & eHAL_TX_RATE_VHT20)
6393 maxMCSIdx = 8;
6394 else
6395 maxMCSIdx = 9;
Leo Chang6f8870f2013-03-26 18:11:36 -07006396 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +05306397
6398 if (rate_flags & eHAL_TX_RATE_VHT80)
6399 {
6400 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT80_rate[rateFlag];
6401 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT80_rate[rateFlag];
6402 }
6403 else if (rate_flags & eHAL_TX_RATE_VHT40)
6404 {
6405 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT40_rate[rateFlag];
6406 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT40_rate[rateFlag];
6407 }
6408 else if (rate_flags & eHAL_TX_RATE_VHT20)
6409 {
6410 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT20_rate[rateFlag];
6411 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT20_rate[rateFlag];
6412 }
6413
Leo Chang6f8870f2013-03-26 18:11:36 -07006414 maxSpeedMCS = 1;
6415 if (currentRate > maxRate)
6416 {
6417 maxRate = currentRate;
6418 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +05306419
Leo Chang6f8870f2013-03-26 18:11:36 -07006420 }
6421 else
6422#endif /* WLAN_FEATURE_11AC */
6423 {
6424 if (rate_flags & eHAL_TX_RATE_HT40)
6425 {
6426 rateFlag |= 1;
6427 }
6428 if (rate_flags & eHAL_TX_RATE_SGI)
6429 {
6430 rateFlag |= 2;
6431 }
6432
6433 for (i = 0; i < MCSLeng; i++)
6434 {
6435 temp = sizeof(supported_mcs_rate) / sizeof(supported_mcs_rate[0]);
6436 for (j = 0; j < temp; j++)
6437 {
6438 if (supported_mcs_rate[j].beacon_rate_index == MCSRates[i])
6439 {
6440 currentRate = supported_mcs_rate[j].supported_rate[rateFlag];
6441 break;
6442 }
6443 }
6444 if ((j < temp) && (currentRate > maxRate))
6445 {
6446 maxRate = currentRate;
6447 maxSpeedMCS = 1;
6448 maxMCSIdx = supported_mcs_rate[j].beacon_rate_index;
6449 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006450 }
6451 }
6452 }
6453
Gopichand Nakkala4c705372013-04-24 13:20:33 +05306454 else if (!(rate_flags & eHAL_TX_RATE_LEGACY))
6455 {
6456 maxRate = myRate;
6457 maxSpeedMCS = 1;
6458 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
6459 }
6460
Jeff Johnson295189b2012-06-20 16:38:30 -07006461 // make sure we report a value at least as big as our current rate
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07006462 if (((maxRate < myRate) && (0 == rssidx)) ||
6463 (0 == maxRate))
Jeff Johnson295189b2012-06-20 16:38:30 -07006464 {
6465 maxRate = myRate;
6466 if (rate_flags & eHAL_TX_RATE_LEGACY)
6467 {
6468 maxSpeedMCS = 0;
6469 }
6470 else
6471 {
6472 maxSpeedMCS = 1;
6473 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
6474 }
6475 }
6476
Gopichand Nakkala4c705372013-04-24 13:20:33 +05306477 if (rate_flags & eHAL_TX_RATE_LEGACY)
Jeff Johnson295189b2012-06-20 16:38:30 -07006478 {
6479 sinfo->txrate.legacy = maxRate;
6480#ifdef LINKSPEED_DEBUG_ENABLED
6481 pr_info("Reporting legacy rate %d\n", sinfo->txrate.legacy);
6482#endif //LINKSPEED_DEBUG_ENABLED
6483 }
6484 else
6485 {
6486 sinfo->txrate.mcs = maxMCSIdx;
Leo Chang6f8870f2013-03-26 18:11:36 -07006487#ifdef WLAN_FEATURE_11AC
6488 sinfo->txrate.nss = 1;
6489 if (rate_flags & eHAL_TX_RATE_VHT80)
6490 {
6491 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
Gopichand Nakkala4c705372013-04-24 13:20:33 +05306492 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
Leo Chang6f8870f2013-03-26 18:11:36 -07006493 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +05306494 else if (rate_flags & eHAL_TX_RATE_VHT40)
Leo Chang6f8870f2013-03-26 18:11:36 -07006495 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +05306496 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
6497 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
6498 }
6499 else if (rate_flags & eHAL_TX_RATE_VHT20)
6500 {
6501 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
6502 }
6503#endif /* WLAN_FEATURE_11AC */
6504 if (rate_flags & (eHAL_TX_RATE_HT20 | eHAL_TX_RATE_HT40))
6505 {
6506 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
6507 if (rate_flags & eHAL_TX_RATE_HT40)
6508 {
6509 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
6510 }
Leo Chang6f8870f2013-03-26 18:11:36 -07006511 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006512 if (rate_flags & eHAL_TX_RATE_SGI)
6513 {
6514 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
6515 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +05306516
Jeff Johnson295189b2012-06-20 16:38:30 -07006517#ifdef LINKSPEED_DEBUG_ENABLED
6518 pr_info("Reporting MCS rate %d flags %x\n",
6519 sinfo->txrate.mcs,
6520 sinfo->txrate.flags );
6521#endif //LINKSPEED_DEBUG_ENABLED
6522 }
6523 }
6524 else
6525 {
6526 // report current rate instead of max rate
6527
6528 if (rate_flags & eHAL_TX_RATE_LEGACY)
6529 {
6530 //provide to the UI in units of 100kbps
6531 sinfo->txrate.legacy = myRate;
6532#ifdef LINKSPEED_DEBUG_ENABLED
6533 pr_info("Reporting actual legacy rate %d\n", sinfo->txrate.legacy);
6534#endif //LINKSPEED_DEBUG_ENABLED
6535 }
6536 else
6537 {
6538 //must be MCS
6539 sinfo->txrate.mcs = pAdapter->hdd_stats.ClassA_stat.mcs_index;
Leo Chang6f8870f2013-03-26 18:11:36 -07006540#ifdef WLAN_FEATURE_11AC
6541 sinfo->txrate.nss = 1;
6542 if (rate_flags & eHAL_TX_RATE_VHT80)
6543 {
6544 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
6545 }
6546 else
6547#endif /* WLAN_FEATURE_11AC */
6548 {
6549 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
6550 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006551 if (rate_flags & eHAL_TX_RATE_SGI)
6552 {
6553 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
6554 }
6555 if (rate_flags & eHAL_TX_RATE_HT40)
6556 {
6557 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
6558 }
Leo Chang6f8870f2013-03-26 18:11:36 -07006559#ifdef WLAN_FEATURE_11AC
6560 else if (rate_flags & eHAL_TX_RATE_VHT80)
6561 {
6562 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
6563 }
6564#endif /* WLAN_FEATURE_11AC */
Jeff Johnson295189b2012-06-20 16:38:30 -07006565#ifdef LINKSPEED_DEBUG_ENABLED
6566 pr_info("Reporting actual MCS rate %d flags %x\n",
6567 sinfo->txrate.mcs,
6568 sinfo->txrate.flags );
6569#endif //LINKSPEED_DEBUG_ENABLED
6570 }
6571 }
6572 sinfo->filled |= STATION_INFO_TX_BITRATE;
6573
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -07006574 sinfo->tx_packets =
6575 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[0] +
6576 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[1] +
6577 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[2] +
6578 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[3];
6579
6580 sinfo->tx_retries =
6581 pAdapter->hdd_stats.summary_stat.retry_cnt[0] +
6582 pAdapter->hdd_stats.summary_stat.retry_cnt[1] +
6583 pAdapter->hdd_stats.summary_stat.retry_cnt[2] +
6584 pAdapter->hdd_stats.summary_stat.retry_cnt[3];
6585
6586 sinfo->tx_failed =
6587 pAdapter->hdd_stats.summary_stat.fail_cnt[0] +
6588 pAdapter->hdd_stats.summary_stat.fail_cnt[1] +
6589 pAdapter->hdd_stats.summary_stat.fail_cnt[2] +
6590 pAdapter->hdd_stats.summary_stat.fail_cnt[3];
6591
6592 sinfo->filled |=
6593 STATION_INFO_TX_PACKETS |
6594 STATION_INFO_TX_RETRIES |
6595 STATION_INFO_TX_FAILED;
6596
6597 EXIT();
6598 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07006599}
6600
6601static int wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
6602 struct net_device *dev, bool mode, v_SINT_t timeout)
6603{
6604 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +05306605 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07006606 VOS_STATUS vos_status;
6607
Jeff Johnsone7245742012-09-05 17:12:55 -07006608 ENTER();
6609
Jeff Johnson295189b2012-06-20 16:38:30 -07006610 if (NULL == pAdapter)
6611 {
6612 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL\n", __func__);
6613 return -ENODEV;
6614 }
6615
Gopichand Nakkala20c4c042013-04-19 22:08:55 +05306616 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
6617 if (NULL == pHddCtx)
6618 {
6619 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: HDD context is NULL\n", __func__);
6620 return -ENODEV;
6621 }
6622
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306623 if ( pHddCtx->isLogpInProgress )
6624 {
6625 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6626 "%s:LOGP in Progress. Ignore!!!", __func__);
6627 return -EAGAIN;
6628 }
6629
Gopichand Nakkala20c4c042013-04-19 22:08:55 +05306630 if ((DRIVER_POWER_MODE_AUTO == !mode) &&
6631 (TRUE == pHddCtx->hdd_wlan_suspended) &&
6632 (pHddCtx->cfg_ini->fhostArpOffload) &&
6633 (eConnectionState_Associated ==
6634 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
6635 {
6636 vos_status = hdd_conf_hostarpoffload(pAdapter, TRUE);
6637 if (!VOS_IS_STATUS_SUCCESS(vos_status))
6638 {
6639 hddLog(VOS_TRACE_LEVEL_INFO,
6640 "%s:Failed to enable ARPOFFLOAD Feature %d\n",
6641 __func__, vos_status);
6642 }
6643 }
6644
Jeff Johnson295189b2012-06-20 16:38:30 -07006645 /**The get power cmd from the supplicant gets updated by the nl only
6646 *on successful execution of the function call
6647 *we are oppositely mapped w.r.t mode in the driver
6648 **/
6649 vos_status = wlan_hdd_enter_bmps(pAdapter, !mode);
6650
Jeff Johnsone7245742012-09-05 17:12:55 -07006651 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07006652 if (VOS_STATUS_E_FAILURE == vos_status)
6653 {
6654 return -EINVAL;
6655 }
6656 return 0;
6657}
6658
6659
6660#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
6661static int wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
6662 struct net_device *netdev,
6663 u8 key_index)
6664{
Jeff Johnsone7245742012-09-05 17:12:55 -07006665 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07006666 return 0;
6667}
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306668#endif //LINUX_VERSION_CODE
Jeff Johnson295189b2012-06-20 16:38:30 -07006669
6670#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
6671static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
6672 struct net_device *dev,
6673 struct ieee80211_txq_params *params)
6674{
Jeff Johnsone7245742012-09-05 17:12:55 -07006675 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07006676 return 0;
6677}
6678#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
6679static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
6680 struct ieee80211_txq_params *params)
6681{
Jeff Johnsone7245742012-09-05 17:12:55 -07006682 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07006683 return 0;
6684}
6685#endif //LINUX_VERSION_CODE
6686
6687static int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
6688 struct net_device *dev, u8 *mac)
6689{
6690 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08006691 VOS_STATUS vos_status;
6692 v_U8_t staId;
Jeff Johnson295189b2012-06-20 16:38:30 -07006693
Jeff Johnsone7245742012-09-05 17:12:55 -07006694 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07006695 if ( NULL == pAdapter || NULL == pAdapter->pHddCtx)
6696 {
6697 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Invalid Adapter or HDD Context " ,__func__);
6698 return -EINVAL;
6699 }
6700
6701 if (((hdd_context_t*)pAdapter->pHddCtx)->isLoadUnloadInProgress)
6702 {
6703 hddLog( LOGE,
6704 "%s: Wlan Load/Unload is in progress", __func__);
6705 return -EBUSY;
6706 }
6707
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006708 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
6709 {
6710 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6711 "%s:LOGP in Progress. Ignore!!!", __func__);
6712 return -EAGAIN;
6713 }
6714
Jeff Johnson295189b2012-06-20 16:38:30 -07006715 if ( (WLAN_HDD_SOFTAP == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -07006716 || (WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -07006717 )
6718 {
6719 if( NULL == mac )
6720 {
6721 v_U16_t i;
6722 for(i = 0; i < WLAN_MAX_STA_COUNT; i++)
6723 {
6724 if(pAdapter->aStaInfo[i].isUsed)
6725 {
6726 u8 *macAddr = pAdapter->aStaInfo[i].macAddrSTA.bytes;
6727 hddLog(VOS_TRACE_LEVEL_INFO,
6728 "%s: Delete STA with MAC::"
6729 "%02x:%02x:%02x:%02x:%02x:%02x",
6730 __func__,
6731 macAddr[0], macAddr[1], macAddr[2],
6732 macAddr[3], macAddr[4], macAddr[5]);
6733 hdd_softap_sta_deauth(pAdapter, macAddr);
6734 }
6735 }
6736 }
6737 else
6738 {
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08006739
6740 vos_status = hdd_softap_GetStaId(pAdapter,(v_MACADDR_t *)mac, &staId);
6741 if (!VOS_IS_STATUS_SUCCESS(vos_status))
6742 {
6743 hddLog(VOS_TRACE_LEVEL_INFO,
6744 "%s: Skip this DEL STA as this is not used::"
6745 "%02x:%02x:%02x:%02x:%02x:%02x",
6746 __func__,
6747 mac[0], mac[1], mac[2],
6748 mac[3], mac[4], mac[5]);
6749 return -ENOENT;
6750 }
6751
6752 if( pAdapter->aStaInfo[staId].isDeauthInProgress == TRUE)
6753 {
6754 hddLog(VOS_TRACE_LEVEL_INFO,
6755 "%s: Skip this DEL STA as deauth is in progress::"
6756 "%02x:%02x:%02x:%02x:%02x:%02x",
6757 __func__,
6758 mac[0], mac[1], mac[2],
6759 mac[3], mac[4], mac[5]);
6760 return -ENOENT;
6761 }
6762
6763 pAdapter->aStaInfo[staId].isDeauthInProgress = TRUE;
6764
Jeff Johnson295189b2012-06-20 16:38:30 -07006765 hddLog(VOS_TRACE_LEVEL_INFO,
6766 "%s: Delete STA with MAC::"
6767 "%02x:%02x:%02x:%02x:%02x:%02x",
6768 __func__,
6769 mac[0], mac[1], mac[2],
6770 mac[3], mac[4], mac[5]);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08006771
6772 vos_status = hdd_softap_sta_deauth(pAdapter, mac);
6773 if (!VOS_IS_STATUS_SUCCESS(vos_status))
6774 {
6775 pAdapter->aStaInfo[staId].isDeauthInProgress = FALSE;
6776 hddLog(VOS_TRACE_LEVEL_INFO,
6777 "%s: STA removal failed for ::"
6778 "%02x:%02x:%02x:%02x:%02x:%02x",
6779 __func__,
6780 mac[0], mac[1], mac[2],
6781 mac[3], mac[4], mac[5]);
6782 return -ENOENT;
6783 }
6784
Jeff Johnson295189b2012-06-20 16:38:30 -07006785 }
6786 }
6787
6788 EXIT();
6789
6790 return 0;
6791}
6792
Hoonki Lee11f7dda2013-02-14 16:55:44 -08006793static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
6794 struct net_device *dev, u8 *mac, struct station_parameters *params)
6795{
Gopichand Nakkalab977a972013-02-18 19:15:09 -08006796 int status = -EPERM;
Hoonki Lee11f7dda2013-02-14 16:55:44 -08006797#ifdef FEATURE_WLAN_TDLS
6798 u32 mask, set;
Hoonki Lee11f7dda2013-02-14 16:55:44 -08006799 ENTER();
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006800 mask = params->sta_flags_mask;
6801
6802 set = params->sta_flags_set;
6803
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07006804#ifdef WLAN_FEATURE_TDLS_DEBUG
6805 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6806 "%s: mask 0x%x set 0x%x " MAC_ADDRESS_STR,
6807 __func__, mask, set, MAC_ADDR_ARRAY(mac));
6808#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006809
6810 if (mask & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
6811 if (set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006812 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 0, NULL);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006813 }
6814 }
6815#endif
Gopichand Nakkalab977a972013-02-18 19:15:09 -08006816 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -07006817}
6818
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006819
6820#ifdef FEATURE_WLAN_LFR
6821static int wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
Jeff Johnsond13512a2012-07-17 11:42:19 -07006822 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006823{
6824#define MAX_PMKSAIDS_IN_CACHE 8
6825 static tPmkidCacheInfo PMKIDCache[MAX_PMKSAIDS_IN_CACHE]; // HDD Local cache
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306826 static tANI_U32 i; // HDD Local Cache index
6827 tANI_U32 j=0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006828 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6829 tHalHandle halHandle;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306830 eHalStatus result;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006831 tANI_U8 BSSIDMatched = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306832
Jeff Johnsone7245742012-09-05 17:12:55 -07006833 ENTER();
6834
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306835 // Validate pAdapter
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006836 if ( NULL == pAdapter || NULL == pAdapter->pHddCtx)
6837 {
6838 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Invalid Adapter or HDD Context " ,__func__);
6839 return -EINVAL;
6840 }
6841
6842 if (((hdd_context_t*)pAdapter->pHddCtx)->isLoadUnloadInProgress)
6843 {
6844 hddLog( LOGE,
6845 "%s: Wlan Load/Unload is in progress", __func__);
6846 return -EBUSY;
6847 }
6848
6849 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
6850 {
6851 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6852 "%s:LOGP in Progress. Ignore!!!", __func__);
6853 return -EAGAIN;
6854 }
6855
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306856 // Retrieve halHandle
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006857 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
6858
6859 for (j = 0; j < i; j++)
6860 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306861 if(vos_mem_compare(PMKIDCache[j].BSSID,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006862 pmksa->bssid, WNI_CFG_BSSID_LEN))
6863 {
6864 /* BSSID matched previous entry. Overwrite it. */
6865 BSSIDMatched = 1;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306866 vos_mem_copy(PMKIDCache[j].BSSID,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006867 pmksa->bssid, WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306868 vos_mem_copy(PMKIDCache[j].PMKID,
6869 pmksa->pmkid,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006870 CSR_RSN_PMKID_SIZE);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306871 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Reusing cache entry %d.",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006872 __func__, j );
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006873 dump_bssid(pmksa->bssid);
6874 dump_pmkid(halHandle, pmksa->pmkid);
6875 break;
6876 }
6877 }
6878
Madan Mohan Koyyalamudic4b317d2012-10-18 19:43:08 -07006879 /* Check we compared all entries,if then take the first slot now */
6880 if(j == MAX_PMKSAIDS_IN_CACHE) i=0;
6881
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006882 if (!BSSIDMatched)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306883 {
6884 // Now, we DON'T have a BSSID match, so take a new entry in the cache.
6885 vos_mem_copy(PMKIDCache[i].BSSID,
6886 pmksa->bssid, ETHER_ADDR_LEN);
6887 vos_mem_copy(PMKIDCache[i].PMKID,
6888 pmksa->pmkid,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006889 CSR_RSN_PMKID_SIZE);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306890 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Adding a new cache entry %d.",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006891 __func__, i );
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006892 dump_bssid(pmksa->bssid);
6893 dump_pmkid(halHandle, pmksa->pmkid);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306894 // Increment the HDD Local Cache index
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006895 // The "i=0" doesn't work for the call to sme_RoamSetPMKIDCache() - LFR FIXME
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306896 if (i<=(MAX_PMKSAIDS_IN_CACHE-1)) i++; else i=0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006897 }
6898
6899
6900 // Calling csrRoamSetPMKIDCache to configure the PMKIDs into the cache
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306901 //hddLog(LOG1, FL("%s: Calling csrRoamSetPMKIDCache with %d cache entries."),
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006902 // __func__, i );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306903 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Calling csrRoamSetPMKIDCache with %d cache entries.",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006904 __func__, i );
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006905 // Finally set the PMKSA ID Cache in CSR
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306906 result = sme_RoamSetPMKIDCache(halHandle,pAdapter->sessionId,
6907 PMKIDCache,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006908 i );
6909 return 0;
6910}
6911
6912
6913static int wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
Jeff Johnsond13512a2012-07-17 11:42:19 -07006914 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006915{
Jeff Johnsone7245742012-09-05 17:12:55 -07006916 ENTER();
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006917 // TODO: Implement this later.
6918 return 0;
6919}
6920
6921static int wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
6922{
Jeff Johnsone7245742012-09-05 17:12:55 -07006923 ENTER();
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006924 // TODO: Implement this later.
6925 return 0;
6926}
6927#endif
6928
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07006929#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306930static int wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07006931 struct net_device *dev, struct cfg80211_update_ft_ies_params *ftie)
6932{
6933 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6934 hdd_station_ctx_t *pHddStaCtx;
6935
6936 if (NULL == pAdapter)
6937 {
6938 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL\n", __func__);
6939 return -ENODEV;
6940 }
6941
6942 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6943
6944 // Added for debug on reception of Re-assoc Req.
6945 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
6946 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306947 hddLog(LOGE, FL("Called with Ie of length = %d when not associated\n"),
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07006948 ftie->ie_len);
6949 hddLog(LOGE, FL("Should be Re-assoc Req IEs\n"));
6950 }
6951
6952#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306953 hddLog(LOGE, FL("%s called with Ie of length = %d\n"), __func__,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07006954 ftie->ie_len);
6955#endif
6956
6957 // Pass the received FT IEs to SME
Gopichand Nakkala356fb102013-03-06 12:34:04 +05306958 sme_SetFTIEs( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
6959 (const u8 *)ftie->ie,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07006960 ftie->ie_len);
6961 return 0;
6962}
6963#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006964
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006965#ifdef FEATURE_WLAN_TDLS
6966static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
6967 u8 *peer, u8 action_code, u8 dialog_token,
6968 u16 status_code, const u8 *buf, size_t len)
6969{
6970
6971 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6972 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006973 u8 peerMac[6];
6974 VOS_STATUS status;
Gopichand Nakkala05922802013-03-14 12:23:19 -07006975 int max_sta_failed = 0;
Hoonki Leea34dd892013-02-05 22:56:02 -08006976 int responder;
Hoonki Leed37cbb32013-04-20 00:31:14 -07006977 long rc;
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006978
Hoonki Lee11f7dda2013-02-14 16:55:44 -08006979 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006980 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306981 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006982 "Invalid arguments");
6983 return -EINVAL;
6984 }
6985
Sameer Thalappil75ea31a2013-02-21 19:38:16 -08006986 if (pHddCtx->isLogpInProgress)
6987 {
6988 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6989 "%s:LOGP in Progress. Ignore!!!", __func__);
Gopichand Nakkala05922802013-03-14 12:23:19 -07006990 wlan_hdd_tdls_set_link_status(pAdapter, peer, eTDLS_LINK_IDLE);
Sameer Thalappil75ea31a2013-02-21 19:38:16 -08006991 return -EBUSY;
6992 }
6993
Hoonki Lee27511902013-03-14 18:19:06 -07006994 if (eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode)
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006995 {
Hoonki Lee27511902013-03-14 18:19:06 -07006996 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
6997 "%s: TDLS mode is disabled OR not enabled in FW."
6998 MAC_ADDRESS_STR " action %d declined.",
6999 __func__, MAC_ADDR_ARRAY(peer), action_code);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007000 return -ENOTSUPP;
7001 }
Lee Hoonkic1262f22013-01-24 21:59:00 -08007002
Hoonki Lee27511902013-03-14 18:19:06 -07007003 /* other than teardown frame, other mgmt frames are not sent if disabled */
7004 if (SIR_MAC_TDLS_TEARDOWN != action_code)
7005 {
7006 /* if tdls_mode is disabled to respond to peer's request */
7007 if (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode)
7008 {
7009 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
7010 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07007011 " TDLS mode is disabled. action %d declined.",
7012 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee27511902013-03-14 18:19:06 -07007013
7014 return -ENOTSUPP;
7015 }
7016 }
7017
Gopichand Nakkalab977a972013-02-18 19:15:09 -08007018 if (WLAN_IS_TDLS_SETUP_ACTION(action_code))
7019 {
Hoonki Leefb8df672013-04-10 18:20:34 -07007020 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, peer, TRUE, TRUE))
Gopichand Nakkalab977a972013-02-18 19:15:09 -08007021 {
7022 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007023 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07007024 " TDLS setup is ongoing. action %d declined.",
7025 __func__, MAC_ADDR_ARRAY(peer), action_code);
7026 return -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -08007027 }
7028 }
7029
Hoonki Lee11f7dda2013-02-14 16:55:44 -08007030 if (SIR_MAC_TDLS_SETUP_REQ == action_code ||
7031 SIR_MAC_TDLS_SETUP_RSP == action_code )
Lee Hoonkic1262f22013-01-24 21:59:00 -08007032 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -08007033 if (HDD_MAX_NUM_TDLS_STA <= wlan_hdd_tdlsConnectedPeers(pAdapter))
Lee Hoonkic1262f22013-01-24 21:59:00 -08007034 {
7035 /* supplicant still sends tdls_mgmt(SETUP_REQ) even after
7036 we return error code at 'add_station()'. Hence we have this
7037 check again in addtion to add_station().
7038 Anyway, there is no hard to double-check. */
Hoonki Lee11f7dda2013-02-14 16:55:44 -08007039 if (SIR_MAC_TDLS_SETUP_REQ == action_code)
Lee Hoonkic1262f22013-01-24 21:59:00 -08007040 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007041 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7042 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07007043 " TDLS Max peer already connected. action %d declined.",
7044 __func__, MAC_ADDR_ARRAY(peer), action_code);
Gopichand Nakkala05922802013-03-14 12:23:19 -07007045 goto error;
Lee Hoonkic1262f22013-01-24 21:59:00 -08007046 }
7047 else
7048 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -08007049 /* maximum reached. tweak to send error code to peer and return
7050 error code to supplicant */
Lee Hoonkic1262f22013-01-24 21:59:00 -08007051 status_code = eSIR_MAC_UNSPEC_FAILURE_STATUS;
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007052 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7053 "%s: " MAC_ADDRESS_STR
7054 " TDLS Max peer already connected send response status %d",
7055 __func__, MAC_ADDR_ARRAY(peer), status_code);
Gopichand Nakkala05922802013-03-14 12:23:19 -07007056 max_sta_failed = -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -08007057 /* fall through to send setup resp with failure status
7058 code */
Lee Hoonkic1262f22013-01-24 21:59:00 -08007059 }
7060 }
Hoonki Lee11f7dda2013-02-14 16:55:44 -08007061 else
7062 {
7063 hddTdlsPeer_t *pTdlsPeer;
Gopichand Nakkala4327a152013-03-04 23:22:42 -08007064 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007065 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Hoonki Lee11f7dda2013-02-14 16:55:44 -08007066 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007067 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07007068 "%s:" MAC_ADDRESS_STR " already connected. action %d declined.",
7069 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee11f7dda2013-02-14 16:55:44 -08007070 return -EPERM;
7071 }
7072 }
Lee Hoonkic1262f22013-01-24 21:59:00 -08007073 }
Hoonki Lee11f7dda2013-02-14 16:55:44 -08007074 vos_mem_copy(peerMac, peer, 6);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007075
Hoonki Lee1090c6a2013-01-16 17:40:54 -08007076#ifdef WLAN_FEATURE_TDLS_DEBUG
7077 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007078 "%s: " MAC_ADDRESS_STR " action %d, dialog_token %d status %d, len = %d",
7079 "tdls_mgmt", MAC_ADDR_ARRAY(peer),
7080 action_code, dialog_token, status_code, len);
Hoonki Lee1090c6a2013-01-16 17:40:54 -08007081#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007082
Hoonki Leea34dd892013-02-05 22:56:02 -08007083 /*Except teardown responder will not be used so just make 0*/
7084 responder = 0;
Hoonki Lee11f7dda2013-02-14 16:55:44 -08007085 if (SIR_MAC_TDLS_TEARDOWN == action_code)
Hoonki Leea34dd892013-02-05 22:56:02 -08007086 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -07007087
7088 hddTdlsPeer_t *pTdlsPeer;
7089 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peerMac);
7090
7091 if(pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
7092 responder = pTdlsPeer->is_responder;
7093 else
Hoonki Leea34dd892013-02-05 22:56:02 -08007094 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -07007095 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7096 "%s: " MAC_ADDRESS_STR " peer doesn't exist or not connected %d dialog_token %d status %d, len = %d",
7097 __func__, MAC_ADDR_ARRAY(peer), (NULL == pTdlsPeer) ? -1 : pTdlsPeer->link_status,
7098 dialog_token, status_code, len);
7099 return -EPERM;
Hoonki Leea34dd892013-02-05 22:56:02 -08007100 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007101 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007102
Hoonki Lee14621352013-04-16 17:51:19 -07007103 if ((SIR_MAC_TDLS_SETUP_RSP == action_code) ||
7104 (SIR_MAC_TDLS_DIS_RSP == action_code))
7105 {
7106 if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter)))
7107 {
7108 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
7109 "%s: Sending Disc/Setup Rsp Frame.Disable BMPS", __func__);
7110 hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
7111 }
7112 wlan_hdd_tdls_set_cap(pAdapter, peerMac, eTDLS_CAP_SUPPORTED);
7113 }
7114
Gopichand Nakkalab977a972013-02-18 19:15:09 -08007115 INIT_COMPLETION(pAdapter->tdls_mgmt_comp);
7116
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007117 status = sme_SendTdlsMgmtFrame(WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
Hoonki Leea34dd892013-02-05 22:56:02 -08007118 peerMac, action_code, dialog_token, status_code, (tANI_U8 *)buf, len, responder);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007119
Gopichand Nakkalab977a972013-02-18 19:15:09 -08007120 if (VOS_STATUS_SUCCESS != status)
7121 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007122 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7123 "%s: sme_SendTdlsMgmtFrame failed!", __func__);
Hoonki Lee14621352013-04-16 17:51:19 -07007124 wlan_hdd_tdls_check_bmps(pAdapter);
7125 goto error;
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007126 }
7127
Hoonki Leed37cbb32013-04-20 00:31:14 -07007128 rc = wait_for_completion_interruptible_timeout(&pAdapter->tdls_mgmt_comp,
7129 msecs_to_jiffies(WAIT_TIME_TDLS_MGMT));
7130
7131 if ((rc <= 0) || (TRUE != pAdapter->mgmtTxCompletionStatus))
Gopichand Nakkalab977a972013-02-18 19:15:09 -08007132 {
Hoonki Leed37cbb32013-04-20 00:31:14 -07007133 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7134 "%s: Mgmt Tx Completion failed status %ld TxCompletion %lu",
7135 __func__, rc, pAdapter->mgmtTxCompletionStatus);
7136 wlan_hdd_tdls_check_bmps(pAdapter);
7137 goto error;
Gopichand Nakkalab977a972013-02-18 19:15:09 -08007138 }
7139
Gopichand Nakkala05922802013-03-14 12:23:19 -07007140 if (max_sta_failed)
Hoonki Lee14621352013-04-16 17:51:19 -07007141 {
7142 wlan_hdd_tdls_check_bmps(pAdapter);
Gopichand Nakkala05922802013-03-14 12:23:19 -07007143 return max_sta_failed;
Hoonki Lee14621352013-04-16 17:51:19 -07007144 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -08007145
Hoonki Leea34dd892013-02-05 22:56:02 -08007146 if (SIR_MAC_TDLS_SETUP_RSP == action_code)
7147 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -08007148 wlan_hdd_tdls_set_responder(pAdapter, peerMac, TRUE);
Hoonki Leea34dd892013-02-05 22:56:02 -08007149 }
7150 else if (SIR_MAC_TDLS_SETUP_CNF == action_code)
7151 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -08007152 wlan_hdd_tdls_set_responder(pAdapter, peerMac, FALSE);
Hoonki Leea34dd892013-02-05 22:56:02 -08007153 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007154
7155 return 0;
Gopichand Nakkala05922802013-03-14 12:23:19 -07007156error:
7157 /* max_sta_failed ; we didn't set to CONNECTING for this case,
7158 because we already know that this transaction will be failed,
7159 but we weren't sure if supplicant call DISABLE_LINK or not. So,
7160 to be safe, do not change the state mahine.
7161 */
7162 if(max_sta_failed == 0 &&
7163 (WLAN_IS_TDLS_SETUP_ACTION(action_code)))
7164 wlan_hdd_tdls_set_link_status(pAdapter, peerMac, eTDLS_LINK_IDLE);
7165 return -EPERM;
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007166}
7167
7168static int wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
7169 u8 *peer, enum nl80211_tdls_operation oper)
7170{
7171 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
7172 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Hoonki Lee1090c6a2013-01-16 17:40:54 -08007173#ifdef WLAN_FEATURE_TDLS_DEBUG
7174 const char *tdls_oper_str[]= {
7175 "NL80211_TDLS_DISCOVERY_REQ",
7176 "NL80211_TDLS_SETUP",
7177 "NL80211_TDLS_TEARDOWN",
7178 "NL80211_TDLS_ENABLE_LINK",
7179 "NL80211_TDLS_DISABLE_LINK",
7180 "NL80211_TDLS_UNKONW_OPER"};
7181#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007182
Chilam Ngc4244af2013-04-01 15:37:32 -07007183 if ( NULL == pHddCtx || NULL == pHddCtx->cfg_ini || NULL == peer )
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007184 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -08007185 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chilam Ngc4244af2013-04-01 15:37:32 -07007186 "%s: Invalid arguments", __func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007187 return -EINVAL;
7188 }
Hoonki Lee1090c6a2013-01-16 17:40:54 -08007189
Sameer Thalappil75ea31a2013-02-21 19:38:16 -08007190 if (pHddCtx->isLogpInProgress)
7191 {
7192 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7193 "%s:LOGP in Progress. Ignore!!!", __func__);
7194 return -EBUSY;
7195 }
7196
Hoonki Lee1090c6a2013-01-16 17:40:54 -08007197#ifdef WLAN_FEATURE_TDLS_DEBUG
7198 if((int)oper > 4)
7199 oper = 5;
7200
7201 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007202 "%s: " MAC_ADDRESS_STR " %d (%s) ", "tdls_oper",
7203 MAC_ADDR_ARRAY(peer), (int)oper,
7204 tdls_oper_str[(int)oper]);
Hoonki Lee1090c6a2013-01-16 17:40:54 -08007205#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007206
7207 if( FALSE == pHddCtx->cfg_ini->fEnableTDLSSupport ||
Hoonki Lee1090c6a2013-01-16 17:40:54 -08007208 FALSE == sme_IsFeatureSupportedByFW(TDLS))
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007209 {
Hoonki Lee1090c6a2013-01-16 17:40:54 -08007210 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chilam Ngc4244af2013-04-01 15:37:32 -07007211 "TDLS Disabled in INI OR not enabled in FW. "
7212 "Cannot process TDLS commands");
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007213 return -ENOTSUPP;
7214 }
7215
7216 switch (oper) {
7217 case NL80211_TDLS_ENABLE_LINK:
7218 {
Hoonki Lee387663d2013-02-05 18:08:43 -08007219 hddTdlsPeer_t *pTdlsPeer;
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007220 VOS_STATUS status;
7221
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007222 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007223
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007224 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
7225 "%s: TDLS_LINK_ENABLE " MAC_ADDRESS_STR,
7226 __func__, MAC_ADDR_ARRAY(peer));
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007227
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007228 if ( NULL == pTdlsPeer ) {
7229 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wlan_hdd_tdls_find_peer "
7230 MAC_ADDRESS_STR " failed",
7231 __func__, MAC_ADDR_ARRAY(peer));
7232 return -EINVAL;
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007233 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007234
Gopichand Nakkala2f4a2822013-04-17 11:22:01 -07007235 if (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
7236 {
7237 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Staion Index %u "
7238 MAC_ADDRESS_STR " failed",
7239 __func__, pTdlsPeer->staId, MAC_ADDR_ARRAY(peer));
7240 return -EINVAL;
7241 }
7242
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007243 if (eTDLS_LINK_CONNECTING == pTdlsPeer->link_status)
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007244 {
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -07007245 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer, eTDLS_LINK_CONNECTED);
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007246 /* start TDLS client registration with TL */
7247 status = hdd_roamRegisterTDLSSTA( pAdapter, peer, pTdlsPeer->staId, pTdlsPeer->signature);
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -07007248 if (VOS_STATUS_SUCCESS == status)
7249 {
Hoonki Lee14621352013-04-16 17:51:19 -07007250 if (pTdlsPeer->is_responder == 0)
7251 {
7252 v_U8_t staId = (v_U8_t)pTdlsPeer->staId;
7253
7254 wlan_hdd_tdls_timer_restart(pAdapter,
7255 &pTdlsPeer->initiatorWaitTimeoutTimer,
7256 WAIT_TIME_TDLS_INITIATOR);
7257 /* suspend initiator TX until it receives direct packet from the
7258 reponder or WAIT_TIME_TDLS_INITIATOR timer expires */
7259 WLANTL_SuspendDataTx( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
7260 &staId, NULL);
7261 }
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -07007262 wlan_hdd_tdls_increment_peer_count(pAdapter);
7263 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007264 wlan_hdd_tdls_check_bmps(pAdapter);
7265 }
7266
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007267 }
7268 break;
7269 case NL80211_TDLS_DISABLE_LINK:
Lee Hoonkic1262f22013-01-24 21:59:00 -08007270 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -08007271 hddTdlsPeer_t *curr_peer = wlan_hdd_tdls_find_peer(pAdapter, peer);
Gopichand Nakkalab977a972013-02-18 19:15:09 -08007272
Gopichand Nakkala2f4a2822013-04-17 11:22:01 -07007273 if((NULL != curr_peer) && TDLS_STA_INDEX_VALID(curr_peer->staId))
Lee Hoonkic1262f22013-01-24 21:59:00 -08007274 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007275 long status;
7276
7277 INIT_COMPLETION(pAdapter->tdls_del_station_comp);
7278
Lee Hoonkic1262f22013-01-24 21:59:00 -08007279 sme_DeleteTdlsPeerSta( WLAN_HDD_GET_HAL_CTX(pAdapter),
7280 pAdapter->sessionId, peer );
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007281
7282 status = wait_for_completion_interruptible_timeout(&pAdapter->tdls_del_station_comp,
7283 msecs_to_jiffies(WAIT_TIME_TDLS_DEL_STA));
7284 if (status <= 0)
7285 {
7286 wlan_hdd_tdls_set_peer_link_status(curr_peer, eTDLS_LINK_IDLE);
7287 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7288 "%s: Del station failed status %ld",
7289 __func__, status);
7290 return -EPERM;
7291 }
Gopichand Nakkala8b00c632013-03-08 19:47:52 -08007292 wlan_hdd_tdls_set_peer_link_status(curr_peer, eTDLS_LINK_IDLE);
Lee Hoonkic1262f22013-01-24 21:59:00 -08007293 }
7294 else
7295 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007296 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7297 "%s: TDLS Peer Station doesn't exist.", __func__);
Lee Hoonkic1262f22013-01-24 21:59:00 -08007298 }
Lee Hoonkic1262f22013-01-24 21:59:00 -08007299 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007300 break;
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007301 case NL80211_TDLS_TEARDOWN:
7302 case NL80211_TDLS_SETUP:
7303 case NL80211_TDLS_DISCOVERY_REQ:
7304 /* We don't support in-driver setup/teardown/discovery */
7305 return -ENOTSUPP;
7306 default:
7307 return -ENOTSUPP;
7308 }
7309 return 0;
7310}
Chilam NG571c65a2013-01-19 12:27:36 +05307311
7312int wlan_hdd_cfg80211_send_tdls_discover_req(struct wiphy *wiphy,
7313 struct net_device *dev, u8 *peer)
7314{
7315 hddLog(VOS_TRACE_LEVEL_INFO, "tdls send discover req: %x %x %x %x %x %x",
7316 peer[0], peer[1], peer[2], peer[3], peer[4], peer[5]);
7317
7318 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
7319 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, NULL, 0);
7320}
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007321#endif
7322
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05307323#ifdef WLAN_FEATURE_GTK_OFFLOAD
7324/*
7325 * FUNCTION: wlan_hdd_cfg80211_update_replayCounterCallback
7326 * Callback rountine called upon receiving response for
7327 * get offload info
7328 */
7329void wlan_hdd_cfg80211_update_replayCounterCallback(void *callbackContext,
7330 tpSirGtkOffloadGetInfoRspParams pGtkOffloadGetInfoRsp)
7331{
7332
7333 hdd_adapter_t *pAdapter = (hdd_adapter_t *)callbackContext;
7334
7335 ENTER();
7336
7337 if (NULL == pAdapter)
7338 {
7339 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
7340 "%s: HDD adapter is Null", __func__);
7341 return ;
7342 }
7343
7344 if (NULL == pGtkOffloadGetInfoRsp)
7345 {
7346 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7347 "%s: pGtkOffloadGetInfoRsp is Null", __func__);
7348 return ;
7349 }
7350
7351 if (VOS_STATUS_SUCCESS != pGtkOffloadGetInfoRsp->ulStatus)
7352 {
7353 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7354 "%s: wlan Failed to get replay counter value",
7355 __func__);
7356 return ;
7357 }
7358
7359 /* Update replay counter to NL */
7360 cfg80211_gtk_rekey_notify(pAdapter->dev, pGtkOffloadGetInfoRsp->bssId,
7361 (tANI_U8 *)&pGtkOffloadGetInfoRsp->ullKeyReplayCounter, GFP_KERNEL);
7362}
7363
7364/*
7365 * FUNCTION: wlan_hdd_cfg80211_set_rekey_data
7366 * This function is used to offload GTK rekeying job to the firmware.
7367 */
7368int wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
7369 struct cfg80211_gtk_rekey_data *data)
7370{
7371 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
7372 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
7373 hdd_station_ctx_t *pHddStaCtx;
7374 tHalHandle hHal;
7375 tpSirGtkOffloadParams pGtkOffloadReqParams;
7376 eHalStatus status = eHAL_STATUS_FAILURE;
7377
7378 ENTER();
7379
7380 if (NULL == pAdapter)
7381 {
7382 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
7383 "%s: HDD adapter is Null", __func__);
7384 return -ENODEV;
7385 }
7386
7387 if (NULL == pHddCtx)
7388 {
7389 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7390 "%s: HDD context is Null!!!", __func__);
7391 return -ENODEV;
7392 }
7393
7394 if (pHddCtx->isLogpInProgress)
7395 {
7396 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
7397 "%s: LOGP in Progress. Ignore!!!", __func__);
7398 return -EAGAIN;
7399 }
7400
7401 if (pHddCtx->isLoadUnloadInProgress)
7402 {
7403 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
7404 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
7405 return -EAGAIN;
7406 }
7407
7408 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7409 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
7410 if (NULL == hHal)
7411 {
7412 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7413 "%s: HAL context is Null!!!", __func__);
7414 return -EAGAIN;
7415 }
7416
7417 pGtkOffloadReqParams =
7418 &pHddStaCtx->gtkOffloadRequestParams.gtkOffloadReqParams;
7419
7420 pGtkOffloadReqParams->ulFlags = GTK_OFFLOAD_ENABLE;
7421 memcpy(pGtkOffloadReqParams->aKCK, data->kck, NL80211_KCK_LEN);
7422 memcpy(pGtkOffloadReqParams->aKEK, data->kek, NL80211_KEK_LEN);
7423 memcpy(pGtkOffloadReqParams->bssId, &pHddStaCtx->conn_info.bssId,
7424 WNI_CFG_BSSID_LEN);
7425 memcpy(&pGtkOffloadReqParams->ullKeyReplayCounter, &data->replay_ctr,
7426 sizeof (tANI_U64));
7427
7428 if (TRUE == pHddCtx->hdd_wlan_suspended)
7429 {
7430 /* if wlan is suspended, enable GTK offload directly from here */
7431 status = sme_SetGTKOffload(hHal, pGtkOffloadReqParams,
7432 pAdapter->sessionId);
7433
7434 if (eHAL_STATUS_SUCCESS != status)
7435 {
7436 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7437 "%s: sme_SetGTKOffload failed, returned %d",
7438 __func__, status);
7439 return status;
7440 }
7441 pHddStaCtx->gtkOffloadRequestParams.requested = FALSE;
7442 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
7443 "%s: sme_SetGTKOffload successfull", __func__);
7444 }
7445 else
7446 {
7447 pHddStaCtx->gtkOffloadRequestParams.requested = TRUE;
7448 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
7449 "%s: wlan not suspended GTKOffload request is stored",
7450 __func__);
7451 return eHAL_STATUS_SUCCESS;
7452 }
7453 return status;
7454}
7455#endif /*WLAN_FEATURE_GTK_OFFLOAD*/
7456
Jeff Johnson295189b2012-06-20 16:38:30 -07007457/* cfg80211_ops */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307458static struct cfg80211_ops wlan_hdd_cfg80211_ops =
Jeff Johnson295189b2012-06-20 16:38:30 -07007459{
7460 .add_virtual_intf = wlan_hdd_add_virtual_intf,
7461 .del_virtual_intf = wlan_hdd_del_virtual_intf,
7462 .change_virtual_intf = wlan_hdd_cfg80211_change_iface,
7463 .change_station = wlan_hdd_change_station,
7464#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
7465 .add_beacon = wlan_hdd_cfg80211_add_beacon,
7466 .del_beacon = wlan_hdd_cfg80211_del_beacon,
7467 .set_beacon = wlan_hdd_cfg80211_set_beacon,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007468#else
7469 .start_ap = wlan_hdd_cfg80211_start_ap,
7470 .change_beacon = wlan_hdd_cfg80211_change_beacon,
7471 .stop_ap = wlan_hdd_cfg80211_stop_ap,
Jeff Johnson295189b2012-06-20 16:38:30 -07007472#endif
7473 .change_bss = wlan_hdd_cfg80211_change_bss,
7474 .add_key = wlan_hdd_cfg80211_add_key,
7475 .get_key = wlan_hdd_cfg80211_get_key,
7476 .del_key = wlan_hdd_cfg80211_del_key,
7477 .set_default_key = wlan_hdd_cfg80211_set_default_key,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -08007478#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07007479 .set_channel = wlan_hdd_cfg80211_set_channel,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -08007480#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007481 .scan = wlan_hdd_cfg80211_scan,
7482 .connect = wlan_hdd_cfg80211_connect,
7483 .disconnect = wlan_hdd_cfg80211_disconnect,
7484 .join_ibss = wlan_hdd_cfg80211_join_ibss,
7485 .leave_ibss = wlan_hdd_cfg80211_leave_ibss,
7486 .set_wiphy_params = wlan_hdd_cfg80211_set_wiphy_params,
7487 .set_tx_power = wlan_hdd_cfg80211_set_txpower,
7488 .get_tx_power = wlan_hdd_cfg80211_get_txpower,
Jeff Johnson295189b2012-06-20 16:38:30 -07007489 .remain_on_channel = wlan_hdd_cfg80211_remain_on_channel,
7490 .cancel_remain_on_channel = wlan_hdd_cfg80211_cancel_remain_on_channel,
7491 .mgmt_tx = wlan_hdd_action,
7492#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
7493 .mgmt_tx_cancel_wait = wlan_hdd_cfg80211_mgmt_tx_cancel_wait,
7494 .set_default_mgmt_key = wlan_hdd_set_default_mgmt_key,
7495 .set_txq_params = wlan_hdd_set_txq_params,
7496#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007497 .get_station = wlan_hdd_cfg80211_get_station,
7498 .set_power_mgmt = wlan_hdd_cfg80211_set_power_mgmt,
7499 .del_station = wlan_hdd_cfg80211_del_station,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007500 .add_station = wlan_hdd_cfg80211_add_station,
7501#ifdef FEATURE_WLAN_LFR
7502 .set_pmksa = wlan_hdd_cfg80211_set_pmksa,
7503 .del_pmksa = wlan_hdd_cfg80211_del_pmksa,
7504 .flush_pmksa = wlan_hdd_cfg80211_flush_pmksa,
7505#endif
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07007506#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
7507 .update_ft_ies = wlan_hdd_cfg80211_update_ft_ies,
7508#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007509#ifdef FEATURE_WLAN_TDLS
7510 .tdls_mgmt = wlan_hdd_cfg80211_tdls_mgmt,
7511 .tdls_oper = wlan_hdd_cfg80211_tdls_oper,
7512#endif
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05307513#ifdef WLAN_FEATURE_GTK_OFFLOAD
7514 .set_rekey_data = wlan_hdd_cfg80211_set_rekey_data,
7515#endif /* WLAN_FEATURE_GTK_OFFLOAD */
Jeff Johnson295189b2012-06-20 16:38:30 -07007516};
7517