blob: 42d4c7a4199c7571643683cac86c73abe0cb97d2 [file] [log] [blame]
Jeff Johnson295189b2012-06-20 16:38:30 -07001/*
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302 * Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
3 *
4 * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
5 *
6 *
7 * Permission to use, copy, modify, and/or distribute this software for
8 * any purpose with or without fee is hereby granted, provided that the
9 * above copyright notice and this permission notice appear in all
10 * copies.
11 *
12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
13 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
14 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
15 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
16 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
17 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
18 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
19 * PERFORMANCE OF THIS SOFTWARE.
20*/
Jeff Johnson295189b2012-06-20 16:38:30 -070021
22/**========================================================================
23
24 \file wlan_hdd_cfg80211.c
25
26 \brief WLAN Host Device Driver implementation
27
Gopichand Nakkala747461f2013-04-24 19:24:45 +053028 Copyright 2008 (c) Qualcomm Technologies, Inc. All Rights Reserved.
Jeff Johnson295189b2012-06-20 16:38:30 -070029
Gopichand Nakkala747461f2013-04-24 19:24:45 +053030 Qualcomm Technologies Confidential and Proprietary.
Jeff Johnson295189b2012-06-20 16:38:30 -070031
32 ========================================================================*/
33
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070034/**=========================================================================
Jeff Johnson295189b2012-06-20 16:38:30 -070035
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070036 EDIT HISTORY FOR FILE
Jeff Johnson295189b2012-06-20 16:38:30 -070037
38
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070039 This section contains comments describing changes made to the module.
40 Notice that changes are listed in reverse chronological order.
Jeff Johnson295189b2012-06-20 16:38:30 -070041
42
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070043 $Header:$ $DateTime: $ $Author: $
Jeff Johnson295189b2012-06-20 16:38:30 -070044
45
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070046 when who what, where, why
Jeff Johnson295189b2012-06-20 16:38:30 -070047 -------- --- --------------------------------------------------------
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070048 21/12/09 Ashwani Created module.
Jeff Johnson295189b2012-06-20 16:38:30 -070049
50 07/06/10 Kumar Deepak Implemented cfg80211 callbacks for ANDROID
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070051 Ganesh K
Jeff Johnson295189b2012-06-20 16:38:30 -070052 ==========================================================================*/
53
Jeff Johnson295189b2012-06-20 16:38:30 -070054
55#include <linux/version.h>
56#include <linux/module.h>
57#include <linux/kernel.h>
58#include <linux/init.h>
59#include <linux/wireless.h>
60#include <wlan_hdd_includes.h>
61#include <net/arp.h>
62#include <net/cfg80211.h>
63#include <linux/wireless.h>
64#include <wlan_hdd_wowl.h>
65#include <aniGlobal.h>
66#include "ccmApi.h"
67#include "sirParams.h"
68#include "dot11f.h"
69#include "wlan_hdd_assoc.h"
70#include "wlan_hdd_wext.h"
71#include "sme_Api.h"
72#include "wlan_hdd_p2p.h"
73#include "wlan_hdd_cfg80211.h"
74#include "wlan_hdd_hostapd.h"
75#include "sapInternal.h"
76#include "wlan_hdd_softap_tx_rx.h"
77#include "wlan_hdd_main.h"
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053078#include "wlan_hdd_assoc.h"
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053079#include "wlan_hdd_power.h"
Jeff Johnson295189b2012-06-20 16:38:30 -070080#ifdef WLAN_BTAMP_FEATURE
81#include "bap_hdd_misc.h"
82#endif
83#include <qc_sap_ioctl.h>
Mohit Khanna698ba2a2012-12-04 15:08:18 -080084#ifdef FEATURE_WLAN_TDLS
85#include "wlan_hdd_tdls.h"
86#endif
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +053087#include "wlan_nv.h"
Jeff Johnson295189b2012-06-20 16:38:30 -070088
89#define g_mode_rates_size (12)
90#define a_mode_rates_size (8)
91#define FREQ_BASE_80211G (2407)
92#define FREQ_BAND_DIFF_80211G (5)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070093#define MAX_SCAN_SSID 9
Jeff Johnson295189b2012-06-20 16:38:30 -070094#define GET_IE_LEN_IN_BSS_DESC(lenInBss) ( lenInBss + sizeof(lenInBss) - \
95 ((int) OFFSET_OF( tSirBssDescription, ieFields)))
96
97#define HDD2GHZCHAN(freq, chan, flag) { \
98 .band = IEEE80211_BAND_2GHZ, \
99 .center_freq = (freq), \
100 .hw_value = (chan),\
101 .flags = (flag), \
102 .max_antenna_gain = 0 ,\
103 .max_power = 30, \
104}
105
106#define HDD5GHZCHAN(freq, chan, flag) { \
107 .band = IEEE80211_BAND_5GHZ, \
108 .center_freq = (freq), \
109 .hw_value = (chan),\
110 .flags = (flag), \
111 .max_antenna_gain = 0 ,\
112 .max_power = 30, \
113}
114
115#define HDD_G_MODE_RATETAB(rate, rate_id, flag)\
116{\
117 .bitrate = rate, \
118 .hw_value = rate_id, \
119 .flags = flag, \
120}
121
Lee Hoonkic1262f22013-01-24 21:59:00 -0800122#ifndef WLAN_FEATURE_TDLS_DEBUG
123#define TDLS_LOG_LEVEL VOS_TRACE_LEVEL_INFO
124#else
125#define TDLS_LOG_LEVEL VOS_TRACE_LEVEL_ERROR
126#endif
127
Gopichand Nakkala356fb102013-03-06 12:34:04 +0530128#ifdef WLAN_FEATURE_VOWIFI_11R
129#define WLAN_AKM_SUITE_FT_8021X 0x000FAC03
130#define WLAN_AKM_SUITE_FT_PSK 0x000FAC04
131#endif
132
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530133static const u32 hdd_cipher_suites[] =
Jeff Johnson295189b2012-06-20 16:38:30 -0700134{
135 WLAN_CIPHER_SUITE_WEP40,
136 WLAN_CIPHER_SUITE_WEP104,
137 WLAN_CIPHER_SUITE_TKIP,
138#ifdef FEATURE_WLAN_CCX
139#define WLAN_CIPHER_SUITE_KRK 0x004096ff /* use for KRK */
140 WLAN_CIPHER_SUITE_KRK,
141 WLAN_CIPHER_SUITE_CCMP,
142#else
143 WLAN_CIPHER_SUITE_CCMP,
144#endif
145#ifdef FEATURE_WLAN_WAPI
146 WLAN_CIPHER_SUITE_SMS4,
147#endif
Chet Lanctot186b5732013-03-18 10:26:30 -0700148#ifdef WLAN_FEATURE_11W
149 WLAN_CIPHER_SUITE_AES_CMAC,
150#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700151};
152
153static inline int is_broadcast_ether_addr(const u8 *addr)
154{
155 return ((addr[0] == 0xff) && (addr[1] == 0xff) && (addr[2] == 0xff) &&
156 (addr[3] == 0xff) && (addr[4] == 0xff) && (addr[5] == 0xff));
157}
158
159static struct ieee80211_channel hdd_channels_2_4_GHZ[] =
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530160{
Jeff Johnson295189b2012-06-20 16:38:30 -0700161 HDD2GHZCHAN(2412, 1, 0) ,
162 HDD2GHZCHAN(2417, 2, 0) ,
163 HDD2GHZCHAN(2422, 3, 0) ,
164 HDD2GHZCHAN(2427, 4, 0) ,
165 HDD2GHZCHAN(2432, 5, 0) ,
166 HDD2GHZCHAN(2437, 6, 0) ,
167 HDD2GHZCHAN(2442, 7, 0) ,
168 HDD2GHZCHAN(2447, 8, 0) ,
169 HDD2GHZCHAN(2452, 9, 0) ,
170 HDD2GHZCHAN(2457, 10, 0) ,
171 HDD2GHZCHAN(2462, 11, 0) ,
172 HDD2GHZCHAN(2467, 12, 0) ,
173 HDD2GHZCHAN(2472, 13, 0) ,
174 HDD2GHZCHAN(2484, 14, 0) ,
175};
176
Jeff Johnson295189b2012-06-20 16:38:30 -0700177static struct ieee80211_channel hdd_social_channels_2_4_GHZ[] =
178{
179 HDD2GHZCHAN(2412, 1, 0) ,
180 HDD2GHZCHAN(2437, 6, 0) ,
181 HDD2GHZCHAN(2462, 11, 0) ,
182};
Jeff Johnson295189b2012-06-20 16:38:30 -0700183
184static struct ieee80211_channel hdd_channels_5_GHZ[] =
185{
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -0700186 HDD5GHZCHAN(4920, 240, 0) ,
187 HDD5GHZCHAN(4940, 244, 0) ,
188 HDD5GHZCHAN(4960, 248, 0) ,
189 HDD5GHZCHAN(4980, 252, 0) ,
190 HDD5GHZCHAN(5040, 208, 0) ,
191 HDD5GHZCHAN(5060, 212, 0) ,
192 HDD5GHZCHAN(5080, 216, 0) ,
Jeff Johnson295189b2012-06-20 16:38:30 -0700193 HDD5GHZCHAN(5180, 36, 0) ,
194 HDD5GHZCHAN(5200, 40, 0) ,
195 HDD5GHZCHAN(5220, 44, 0) ,
196 HDD5GHZCHAN(5240, 48, 0) ,
197 HDD5GHZCHAN(5260, 52, 0) ,
198 HDD5GHZCHAN(5280, 56, 0) ,
199 HDD5GHZCHAN(5300, 60, 0) ,
200 HDD5GHZCHAN(5320, 64, 0) ,
201 HDD5GHZCHAN(5500,100, 0) ,
202 HDD5GHZCHAN(5520,104, 0) ,
203 HDD5GHZCHAN(5540,108, 0) ,
204 HDD5GHZCHAN(5560,112, 0) ,
205 HDD5GHZCHAN(5580,116, 0) ,
206 HDD5GHZCHAN(5600,120, 0) ,
207 HDD5GHZCHAN(5620,124, 0) ,
208 HDD5GHZCHAN(5640,128, 0) ,
209 HDD5GHZCHAN(5660,132, 0) ,
210 HDD5GHZCHAN(5680,136, 0) ,
211 HDD5GHZCHAN(5700,140, 0) ,
212 HDD5GHZCHAN(5745,149, 0) ,
213 HDD5GHZCHAN(5765,153, 0) ,
214 HDD5GHZCHAN(5785,157, 0) ,
215 HDD5GHZCHAN(5805,161, 0) ,
216 HDD5GHZCHAN(5825,165, 0) ,
217};
218
219static struct ieee80211_rate g_mode_rates[] =
220{
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530221 HDD_G_MODE_RATETAB(10, 0x1, 0),
222 HDD_G_MODE_RATETAB(20, 0x2, 0),
223 HDD_G_MODE_RATETAB(55, 0x4, 0),
224 HDD_G_MODE_RATETAB(110, 0x8, 0),
225 HDD_G_MODE_RATETAB(60, 0x10, 0),
226 HDD_G_MODE_RATETAB(90, 0x20, 0),
227 HDD_G_MODE_RATETAB(120, 0x40, 0),
228 HDD_G_MODE_RATETAB(180, 0x80, 0),
229 HDD_G_MODE_RATETAB(240, 0x100, 0),
230 HDD_G_MODE_RATETAB(360, 0x200, 0),
231 HDD_G_MODE_RATETAB(480, 0x400, 0),
Jeff Johnson295189b2012-06-20 16:38:30 -0700232 HDD_G_MODE_RATETAB(540, 0x800, 0),
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530233};
Jeff Johnson295189b2012-06-20 16:38:30 -0700234
235static struct ieee80211_rate a_mode_rates[] =
236{
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530237 HDD_G_MODE_RATETAB(60, 0x10, 0),
238 HDD_G_MODE_RATETAB(90, 0x20, 0),
239 HDD_G_MODE_RATETAB(120, 0x40, 0),
240 HDD_G_MODE_RATETAB(180, 0x80, 0),
241 HDD_G_MODE_RATETAB(240, 0x100, 0),
242 HDD_G_MODE_RATETAB(360, 0x200, 0),
243 HDD_G_MODE_RATETAB(480, 0x400, 0),
Jeff Johnson295189b2012-06-20 16:38:30 -0700244 HDD_G_MODE_RATETAB(540, 0x800, 0),
245};
246
247static struct ieee80211_supported_band wlan_hdd_band_2_4_GHZ =
248{
249 .channels = hdd_channels_2_4_GHZ,
250 .n_channels = ARRAY_SIZE(hdd_channels_2_4_GHZ),
251 .band = IEEE80211_BAND_2GHZ,
252 .bitrates = g_mode_rates,
253 .n_bitrates = g_mode_rates_size,
254 .ht_cap.ht_supported = 1,
255 .ht_cap.cap = IEEE80211_HT_CAP_SGI_20
256 | IEEE80211_HT_CAP_GRN_FLD
257 | IEEE80211_HT_CAP_DSSSCCK40
258 | IEEE80211_HT_CAP_LSIG_TXOP_PROT,
259 .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
260 .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
261 .ht_cap.mcs.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
262 .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ),
263 .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
264};
265
Jeff Johnson295189b2012-06-20 16:38:30 -0700266static struct ieee80211_supported_band wlan_hdd_band_p2p_2_4_GHZ =
267{
268 .channels = hdd_social_channels_2_4_GHZ,
269 .n_channels = ARRAY_SIZE(hdd_social_channels_2_4_GHZ),
270 .band = IEEE80211_BAND_2GHZ,
271 .bitrates = g_mode_rates,
272 .n_bitrates = g_mode_rates_size,
273 .ht_cap.ht_supported = 1,
274 .ht_cap.cap = IEEE80211_HT_CAP_SGI_20
275 | IEEE80211_HT_CAP_GRN_FLD
276 | IEEE80211_HT_CAP_DSSSCCK40
277 | IEEE80211_HT_CAP_LSIG_TXOP_PROT,
278 .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
279 .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
280 .ht_cap.mcs.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
281 .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ),
282 .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
283};
Jeff Johnson295189b2012-06-20 16:38:30 -0700284
285static struct ieee80211_supported_band wlan_hdd_band_5_GHZ =
286{
287 .channels = hdd_channels_5_GHZ,
288 .n_channels = ARRAY_SIZE(hdd_channels_5_GHZ),
289 .band = IEEE80211_BAND_5GHZ,
290 .bitrates = a_mode_rates,
291 .n_bitrates = a_mode_rates_size,
292 .ht_cap.ht_supported = 1,
293 .ht_cap.cap = IEEE80211_HT_CAP_SGI_20
294 | IEEE80211_HT_CAP_GRN_FLD
295 | IEEE80211_HT_CAP_DSSSCCK40
296 | IEEE80211_HT_CAP_LSIG_TXOP_PROT
297 | IEEE80211_HT_CAP_SGI_40
298 | IEEE80211_HT_CAP_SUP_WIDTH_20_40,
299 .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
300 .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
301 .ht_cap.mcs.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
302 .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ),
303 .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
304};
305
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530306/* This structure contain information what kind of frame are expected in
Jeff Johnson295189b2012-06-20 16:38:30 -0700307 TX/RX direction for each kind of interface */
308static const struct ieee80211_txrx_stypes
309wlan_hdd_txrx_stypes[NUM_NL80211_IFTYPES] = {
310 [NL80211_IFTYPE_STATION] = {
311 .tx = 0xffff,
312 .rx = BIT(SIR_MAC_MGMT_ACTION) |
313 BIT(SIR_MAC_MGMT_PROBE_REQ),
314 },
315 [NL80211_IFTYPE_AP] = {
316 .tx = 0xffff,
317 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
318 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
319 BIT(SIR_MAC_MGMT_PROBE_REQ) |
320 BIT(SIR_MAC_MGMT_DISASSOC) |
321 BIT(SIR_MAC_MGMT_AUTH) |
322 BIT(SIR_MAC_MGMT_DEAUTH) |
323 BIT(SIR_MAC_MGMT_ACTION),
324 },
Jeff Johnson295189b2012-06-20 16:38:30 -0700325 [NL80211_IFTYPE_P2P_CLIENT] = {
326 .tx = 0xffff,
327 .rx = BIT(SIR_MAC_MGMT_ACTION) |
328 BIT(SIR_MAC_MGMT_PROBE_REQ),
329 },
330 [NL80211_IFTYPE_P2P_GO] = {
331 /* This is also same as for SoftAP */
332 .tx = 0xffff,
333 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
334 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
335 BIT(SIR_MAC_MGMT_PROBE_REQ) |
336 BIT(SIR_MAC_MGMT_DISASSOC) |
337 BIT(SIR_MAC_MGMT_AUTH) |
338 BIT(SIR_MAC_MGMT_DEAUTH) |
339 BIT(SIR_MAC_MGMT_ACTION),
340 },
Jeff Johnson295189b2012-06-20 16:38:30 -0700341};
342
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800343#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800344static const struct ieee80211_iface_limit
345wlan_hdd_iface_limit[] = {
346 {
Sunil Ravia72c3992013-01-31 06:12:22 -0800347 /* max = 3 ; Our driver create two interfaces during driver init
348 * wlan0 and p2p0 interfaces. p2p0 is considered as station
349 * interface until a group is formed. In JB architecture, once the
350 * group is formed, interface type of p2p0 is changed to P2P GO or
351 * Client.
352 * When supplicant remove the group, it first issue a set interface
353 * cmd to change the mode back to Station. In JB this works fine as
354 * we advertize two station type interface during driver init.
355 * Some vendors create separate interface for P2P GO/Client,
356 * after group formation(Third one). But while group remove
357 * supplicant first tries to change the mode(3rd interface) to STATION
358 * But as we advertized only two sta type interfaces nl80211 was
359 * returning error for the third one which was leading to failure in
360 * delete interface. Ideally while removing the group, supplicant
361 * should not try to change the 3rd interface mode to Station type.
362 * Till we get a fix in wpa_supplicant, we advertize max STA
363 * interface type to 3
364 */
365 .max = 3,
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800366 .types = BIT(NL80211_IFTYPE_STATION),
367 },
368 {
369 .max = 1,
370 .types = BIT(NL80211_IFTYPE_AP),
371 },
372 {
373 .max = 1,
374 .types = BIT(NL80211_IFTYPE_P2P_GO) |
375 BIT(NL80211_IFTYPE_P2P_CLIENT),
376 },
377};
378
379/* By default, only single channel concurrency is allowed */
380static struct ieee80211_iface_combination
381wlan_hdd_iface_combination = {
382 .limits = wlan_hdd_iface_limit,
383 .num_different_channels = 1,
Sunil Ravia72c3992013-01-31 06:12:22 -0800384 /*
385 * max = WLAN_MAX_INTERFACES ; JellyBean architecture creates wlan0
386 * and p2p0 interfaces during driver init
387 * Some vendors create separate interface for P2P operations.
388 * wlan0: STA interface
389 * p2p0: P2P Device interface, action frames goes
390 * through this interface.
391 * p2p-xx: P2P interface, After GO negotiation this interface is
392 * created for p2p operations(GO/CLIENT interface).
393 */
394 .max_interfaces = WLAN_MAX_INTERFACES,
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800395 .n_limits = ARRAY_SIZE(wlan_hdd_iface_limit),
396 .beacon_int_infra_match = false,
397};
398#endif
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800399
Jeff Johnson295189b2012-06-20 16:38:30 -0700400static struct cfg80211_ops wlan_hdd_cfg80211_ops;
401
402/* Data rate 100KBPS based on IE Index */
403struct index_data_rate_type
404{
405 v_U8_t beacon_rate_index;
406 v_U16_t supported_rate[4];
407};
408
409/* 11B, 11G Rate table include Basic rate and Extended rate
410 The IDX field is the rate index
411 The HI field is the rate when RSSI is strong or being ignored
412 (in this case we report actual rate)
413 The MID field is the rate when RSSI is moderate
414 (in this case we cap 11b rates at 5.5 and 11g rates at 24)
415 The LO field is the rate when RSSI is low
416 (in this case we don't report rates, actual current rate used)
417 */
418static const struct
419{
420 v_U8_t beacon_rate_index;
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -0700421 v_U16_t supported_rate[4];
Jeff Johnson295189b2012-06-20 16:38:30 -0700422} supported_data_rate[] =
423{
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -0700424/* IDX HI HM LM LO (RSSI-based index */
425 {2, { 10, 10, 10, 0}},
426 {4, { 20, 20, 10, 0}},
427 {11, { 55, 20, 10, 0}},
428 {12, { 60, 55, 20, 0}},
429 {18, { 90, 55, 20, 0}},
430 {22, {110, 55, 20, 0}},
431 {24, {120, 90, 60, 0}},
432 {36, {180, 120, 60, 0}},
433 {44, {220, 180, 60, 0}},
434 {48, {240, 180, 90, 0}},
435 {66, {330, 180, 90, 0}},
436 {72, {360, 240, 90, 0}},
437 {96, {480, 240, 120, 0}},
438 {108, {540, 240, 120, 0}}
Jeff Johnson295189b2012-06-20 16:38:30 -0700439};
440
441/* MCS Based rate table */
442static struct index_data_rate_type supported_mcs_rate[] =
443{
444/* MCS L20 L40 S20 S40 */
445 {0, {65, 135, 72, 150}},
446 {1, {130, 270, 144, 300}},
447 {2, {195, 405, 217, 450}},
448 {3, {260, 540, 289, 600}},
449 {4, {390, 810, 433, 900}},
450 {5, {520, 1080, 578, 1200}},
451 {6, {585, 1215, 650, 1350}},
452 {7, {650, 1350, 722, 1500}}
453};
454
Leo Chang6f8870f2013-03-26 18:11:36 -0700455#ifdef WLAN_FEATURE_11AC
456
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530457#define DATA_RATE_11AC_MCS_MASK 0x03
Leo Chang6f8870f2013-03-26 18:11:36 -0700458
459struct index_vht_data_rate_type
460{
461 v_U8_t beacon_rate_index;
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530462 v_U16_t supported_VHT80_rate[2];
463 v_U16_t supported_VHT40_rate[2];
464 v_U16_t supported_VHT20_rate[2];
Leo Chang6f8870f2013-03-26 18:11:36 -0700465};
466
467typedef enum
468{
469 DATA_RATE_11AC_MAX_MCS_7,
470 DATA_RATE_11AC_MAX_MCS_8,
471 DATA_RATE_11AC_MAX_MCS_9,
472 DATA_RATE_11AC_MAX_MCS_NA
473} eDataRate11ACMaxMcs;
474
475/* MCS Based VHT rate table */
476static struct index_vht_data_rate_type supported_vht_mcs_rate[] =
477{
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530478/* MCS L80 S80 L40 S40 L20 S40*/
479 {0, {293, 325}, {135, 150}, {65, 72}},
480 {1, {585, 650}, {270, 300}, {130, 144}},
481 {2, {878, 975}, {405, 450}, {195, 217}},
482 {3, {1170, 1300}, {540, 600}, {260, 289}},
483 {4, {1755, 1950}, {810, 900}, {390, 433}},
484 {5, {2340, 2600}, {1080, 1200}, {520, 578}},
485 {6, {2633, 2925}, {1215, 1350}, {585, 650}},
486 {7, {2925, 3250}, {1350, 1500}, {650, 722}},
487 {8, {3510, 3900}, {1620, 1800}, {780, 867}},
488 {9, {3900, 4333}, {1800, 2000}, {780, 867}}
Leo Chang6f8870f2013-03-26 18:11:36 -0700489};
490#endif /* WLAN_FEATURE_11AC */
491
Jeff Johnson295189b2012-06-20 16:38:30 -0700492extern struct net_device_ops net_ops_struct;
493
494/*
495 * FUNCTION: wlan_hdd_cfg80211_init
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530496 * This function is called by hdd_wlan_startup()
497 * during initialization.
Jeff Johnson295189b2012-06-20 16:38:30 -0700498 * This function is used to initialize and register wiphy structure.
499 */
500struct wiphy *wlan_hdd_cfg80211_init(int priv_size)
501{
502 struct wiphy *wiphy;
503 ENTER();
504
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530505 /*
506 * Create wiphy device
Jeff Johnson295189b2012-06-20 16:38:30 -0700507 */
508 wiphy = wiphy_new(&wlan_hdd_cfg80211_ops, priv_size);
509
510 if (!wiphy)
511 {
512 /* Print error and jump into err label and free the memory */
513 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wiphy init failed", __func__);
514 return NULL;
515 }
516
517 return wiphy;
518}
519
520/*
521 * FUNCTION: wlan_hdd_cfg80211_update_band
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530522 * This function is called from the supplicant through a
Jeff Johnson295189b2012-06-20 16:38:30 -0700523 * private ioctl to change the band value
524 */
525int wlan_hdd_cfg80211_update_band(struct wiphy *wiphy, eCsrBand eBand)
526{
Jeff Johnsone7245742012-09-05 17:12:55 -0700527 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -0700528 switch(eBand)
529 {
530 case eCSR_BAND_24:
531 wiphy->bands[IEEE80211_BAND_2GHZ] = &wlan_hdd_band_2_4_GHZ;
532 wiphy->bands[IEEE80211_BAND_5GHZ] = NULL;
533 break;
534 case eCSR_BAND_5G:
Madan Mohan Koyyalamudi6f6390c2012-09-24 13:57:46 -0700535 wiphy->bands[IEEE80211_BAND_2GHZ] = &wlan_hdd_band_p2p_2_4_GHZ;
Jeff Johnson295189b2012-06-20 16:38:30 -0700536 wiphy->bands[IEEE80211_BAND_5GHZ] = &wlan_hdd_band_5_GHZ;
537 break;
538 case eCSR_BAND_ALL:
539 default:
540 wiphy->bands[IEEE80211_BAND_2GHZ] = &wlan_hdd_band_2_4_GHZ;
541 wiphy->bands[IEEE80211_BAND_5GHZ] = &wlan_hdd_band_5_GHZ;
542 }
543 return 0;
544}
545/*
546 * FUNCTION: wlan_hdd_cfg80211_init
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530547 * This function is called by hdd_wlan_startup()
548 * during initialization.
Jeff Johnson295189b2012-06-20 16:38:30 -0700549 * This function is used to initialize and register wiphy structure.
550 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530551int wlan_hdd_cfg80211_register(struct device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -0700552 struct wiphy *wiphy,
553 hdd_config_t *pCfg
554 )
555{
Jeff Johnsone7245742012-09-05 17:12:55 -0700556 ENTER();
557
Jeff Johnson295189b2012-06-20 16:38:30 -0700558 /* Now bind the underlying wlan device with wiphy */
559 set_wiphy_dev(wiphy, dev);
560
561 wiphy->mgmt_stypes = wlan_hdd_txrx_stypes;
562
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -0700563 wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY;
Jeff Johnson295189b2012-06-20 16:38:30 -0700564
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700565#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -0700566 wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME
567 | WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD
568 | WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL
Jeff Johnsone7245742012-09-05 17:12:55 -0700569 | WIPHY_FLAG_OFFCHAN_TX;
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700570#endif
Srinivas Girigowda640728a2013-03-28 12:21:54 -0700571#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_CCX) || defined(FEATURE_WLAN_LFR)
572 if (pCfg->isFastTransitionEnabled
James Zmuda77fb5ae2013-01-29 08:00:17 -0800573#ifdef FEATURE_WLAN_LFR
Srinivas Girigowda640728a2013-03-28 12:21:54 -0700574 || pCfg->isFastRoamIniFeatureEnabled
575#endif
576#ifdef FEATURE_WLAN_CCX
577 || pCfg->isCcxIniFeatureEnabled
578#endif
579 )
580 {
581 wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM;
582 }
James Zmuda77fb5ae2013-01-29 08:00:17 -0800583#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -0800584#ifdef FEATURE_WLAN_TDLS
585 wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS
586 | WIPHY_FLAG_TDLS_EXTERNAL_SETUP;
587#endif
588
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -0700589 /* even with WIPHY_FLAG_CUSTOM_REGULATORY,
590 driver can still register regulatory callback and
591 it will get CRDA setting in wiphy->band[], but
592 driver need to determine what to do with both
593 regulatory settings */
594 wiphy->reg_notifier = wlan_hdd_crda_reg_notifier;
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700595
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530596 wiphy->max_scan_ssids = MAX_SCAN_SSID;
597
Jeff Johnson295189b2012-06-20 16:38:30 -0700598 wiphy->max_scan_ie_len = 200 ; //TODO: define a macro
599
600 /* Supports STATION & AD-HOC modes right now */
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530601 wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -0700602 | BIT(NL80211_IFTYPE_ADHOC)
Jeff Johnson295189b2012-06-20 16:38:30 -0700603 | BIT(NL80211_IFTYPE_P2P_CLIENT)
604 | BIT(NL80211_IFTYPE_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -0700605 | BIT(NL80211_IFTYPE_AP);
606
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800607#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800608 if( pCfg->enableMCC )
609 {
610 /* Currently, supports up to two channels */
611 wlan_hdd_iface_combination.num_different_channels = 2;
612
613 if( !pCfg->allowMCCGODiffBI )
614 wlan_hdd_iface_combination.beacon_int_infra_match = true;
615
616 }
617 wiphy->iface_combinations = &wlan_hdd_iface_combination;
618 wiphy->n_iface_combinations = 1;
619#endif
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800620
Jeff Johnson295189b2012-06-20 16:38:30 -0700621 /* Before registering we need to update the ht capabilitied based
622 * on ini values*/
623 if( !pCfg->ShortGI20MhzEnable )
624 {
625 wlan_hdd_band_2_4_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
626 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
627 wlan_hdd_band_p2p_2_4_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
628 }
629
630 if( !pCfg->ShortGI40MhzEnable )
631 {
632 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_40;
633 }
634
635 if( !pCfg->nChannelBondingMode5GHz )
636 {
637 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
638 }
639
640 /*Initialize band capability*/
641 switch(pCfg->nBandCapability)
642 {
643 case eCSR_BAND_24:
644 wiphy->bands[IEEE80211_BAND_2GHZ] = &wlan_hdd_band_2_4_GHZ;
645 break;
646 case eCSR_BAND_5G:
Jeff Johnson295189b2012-06-20 16:38:30 -0700647 wiphy->bands[IEEE80211_BAND_2GHZ] = &wlan_hdd_band_p2p_2_4_GHZ;
Jeff Johnson295189b2012-06-20 16:38:30 -0700648 wiphy->bands[IEEE80211_BAND_5GHZ] = &wlan_hdd_band_5_GHZ;
649 break;
650 case eCSR_BAND_ALL:
651 default:
652 wiphy->bands[IEEE80211_BAND_2GHZ] = &wlan_hdd_band_2_4_GHZ;
653 wiphy->bands[IEEE80211_BAND_5GHZ] = &wlan_hdd_band_5_GHZ;
654 }
655 /*Initialise the supported cipher suite details*/
656 wiphy->cipher_suites = hdd_cipher_suites;
657 wiphy->n_cipher_suites = ARRAY_SIZE(hdd_cipher_suites);
658
659 /*signal strength in mBm (100*dBm) */
660 wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
661
662#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Jeff Johnson295189b2012-06-20 16:38:30 -0700663 wiphy->max_remain_on_channel_duration = 1000;
664#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700665
666 /* Register our wiphy dev with cfg80211 */
667 if (0 > wiphy_register(wiphy))
668 {
669 /* print eror */
670 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
671 return -EIO;
672 }
673
674 EXIT();
675 return 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530676}
Jeff Johnson295189b2012-06-20 16:38:30 -0700677
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -0700678/* In this function we will try to get default country code from crda.
679 If the gCrdaDefaultCountryCode is configured in ini file,
680 we will try to call user space crda to get the regulatory settings for
681 that country. We will timeout if we can't get it from crda.
682 It's called by hdd_wlan_startup() after wlan_hdd_cfg80211_register.
683*/
684int wlan_hdd_get_crda_regd_entry(struct wiphy *wiphy, hdd_config_t *pCfg)
685{
686 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
687 if (memcmp(pCfg->crdaDefaultCountryCode,
688 CFG_CRDA_DEFAULT_COUNTRY_CODE_DEFAULT , 2) != 0)
689 {
690 init_completion(&pHddCtx->driver_crda_req);
691 regulatory_hint(wiphy, pCfg->crdaDefaultCountryCode);
692 wait_for_completion_interruptible_timeout(&pHddCtx->driver_crda_req,
693 CRDA_WAIT_TIME);
Yunsen Wange3ba1fb2013-04-05 15:04:43 -0700694 /* if the country is not found from current regulatory.bin,
695 fall back to world domain */
696 if (is_crda_regulatory_entry_valid() == VOS_FALSE)
697 crda_regulatory_entry_default(pCfg->crdaDefaultCountryCode, NUM_REG_DOMAINS-1);
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -0700698 }
699 return 0;
700}
701
Jeff Johnson295189b2012-06-20 16:38:30 -0700702/* In this function we will do all post VOS start initialization.
703 In this function we will register for all frame in which supplicant
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530704 is interested.
Jeff Johnson295189b2012-06-20 16:38:30 -0700705*/
706void wlan_hdd_cfg80211_post_voss_start(hdd_adapter_t* pAdapter)
707{
Jeff Johnson295189b2012-06-20 16:38:30 -0700708 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
709 /* Register for all P2P action, public action etc frames */
710 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
711
Jeff Johnsone7245742012-09-05 17:12:55 -0700712 ENTER();
713
Jeff Johnson295189b2012-06-20 16:38:30 -0700714 /* Right now we are registering these frame when driver is getting
715 initialized. Once we will move to 2.6.37 kernel, in which we have
716 frame register ops, we will move this code as a part of that */
717 /* GAS Initial Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530718 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Jeff Johnson295189b2012-06-20 16:38:30 -0700719 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
720
721 /* GAS Initial Response */
722 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
723 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530724
Jeff Johnson295189b2012-06-20 16:38:30 -0700725 /* GAS Comeback Request */
726 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
727 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
728
729 /* GAS Comeback Response */
730 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
731 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
732
733 /* P2P Public Action */
734 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530735 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -0700736 P2P_PUBLIC_ACTION_FRAME_SIZE );
737
738 /* P2P Action */
739 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
740 (v_U8_t*)P2P_ACTION_FRAME,
741 P2P_ACTION_FRAME_SIZE );
Chet Lanctot186b5732013-03-18 10:26:30 -0700742
Gopichand Nakkalae3d56e72013-04-21 23:33:32 +0530743 /* WNM BSS Transition Request frame */
744 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
745 (v_U8_t*)WNM_BSS_ACTION_FRAME,
746 WNM_BSS_ACTION_FRAME_SIZE );
747
Chet Lanctot186b5732013-03-18 10:26:30 -0700748#ifdef WLAN_FEATURE_11W
749 /* SA Query Response Action Frame */
750 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
751 (v_U8_t*)SA_QUERY_FRAME_RSP,
752 SA_QUERY_FRAME_RSP_SIZE );
753#endif /* WLAN_FEATURE_11W */
Jeff Johnson295189b2012-06-20 16:38:30 -0700754}
755
756void wlan_hdd_cfg80211_pre_voss_stop(hdd_adapter_t* pAdapter)
757{
Jeff Johnson295189b2012-06-20 16:38:30 -0700758 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
759 /* Register for all P2P action, public action etc frames */
760 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
761
Jeff Johnsone7245742012-09-05 17:12:55 -0700762 ENTER();
763
Jeff Johnson295189b2012-06-20 16:38:30 -0700764 /* Right now we are registering these frame when driver is getting
765 initialized. Once we will move to 2.6.37 kernel, in which we have
766 frame register ops, we will move this code as a part of that */
767 /* GAS Initial Request */
768
769 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
770 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
771
772 /* GAS Initial Response */
773 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
774 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530775
Jeff Johnson295189b2012-06-20 16:38:30 -0700776 /* GAS Comeback Request */
777 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
778 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
779
780 /* GAS Comeback Response */
781 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
782 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
783
784 /* P2P Public Action */
785 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530786 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -0700787 P2P_PUBLIC_ACTION_FRAME_SIZE );
788
789 /* P2P Action */
790 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
791 (v_U8_t*)P2P_ACTION_FRAME,
792 P2P_ACTION_FRAME_SIZE );
Chet Lanctot186b5732013-03-18 10:26:30 -0700793
794#ifdef WLAN_FEATURE_11W
795 /* SA Query Response Action Frame */
796 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
797 (v_U8_t*)SA_QUERY_FRAME_RSP,
798 SA_QUERY_FRAME_RSP_SIZE );
799#endif /* WLAN_FEATURE_11W */
Jeff Johnson295189b2012-06-20 16:38:30 -0700800}
801
802#ifdef FEATURE_WLAN_WAPI
803void wlan_hdd_cfg80211_set_key_wapi(hdd_adapter_t* pAdapter, u8 key_index,
804 const u8 *mac_addr, u8 *key , int key_Len)
805{
806 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
807 tCsrRoamSetKey setKey;
808 v_BOOL_t isConnected = TRUE;
809 int status = 0;
810 v_U32_t roamId= 0xFF;
811 tANI_U8 *pKeyPtr = NULL;
812 int n = 0;
813
814 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",
815 __func__,pAdapter->device_mode);
816
Gopichand Nakkalae7480202013-02-11 15:24:22 +0530817 vos_mem_zero(&setKey, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -0700818 setKey.keyId = key_index; // Store Key ID
819 setKey.encType = eCSR_ENCRYPT_TYPE_WPI; // SET WAPI Encryption
820 setKey.keyDirection = eSIR_TX_RX; // Key Directionn both TX and RX
821 setKey.paeRole = 0 ; // the PAE role
822 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
823 {
824 vos_set_macaddr_broadcast( (v_MACADDR_t *)setKey.peerMac );
825 }
826 else
827 {
828 isConnected = hdd_connIsConnected(pHddStaCtx);
829 vos_mem_copy(setKey.peerMac,&pHddStaCtx->conn_info.bssId,WNI_CFG_BSSID_LEN);
830 }
831 setKey.keyLength = key_Len;
832 pKeyPtr = setKey.Key;
833 memcpy( pKeyPtr, key, key_Len);
834
835 hddLog(VOS_TRACE_LEVEL_INFO,"\n%s: WAPI KEY LENGTH:0x%04x",
836 __func__, key_Len);
837 for (n = 0 ; n < key_Len; n++)
838 hddLog(VOS_TRACE_LEVEL_INFO, "%s WAPI KEY Data[%d]:%02x ",
839 __func__,n,setKey.Key[n]);
840
841 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
842 if ( isConnected )
843 {
844 status= sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
845 pAdapter->sessionId, &setKey, &roamId );
846 }
847 if ( status != 0 )
848 {
849 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
850 "[%4d] sme_RoamSetKey returned ERROR status= %d",
851 __LINE__, status );
852 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
853 }
854}
855#endif /* FEATURE_WLAN_WAPI*/
856
857#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530858int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -0700859 beacon_data_t **ppBeacon,
860 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700861#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530862int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700863 beacon_data_t **ppBeacon,
864 struct cfg80211_beacon_data *params,
865 int dtim_period)
866#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530867{
Jeff Johnson295189b2012-06-20 16:38:30 -0700868 int size;
869 beacon_data_t *beacon = NULL;
870 beacon_data_t *old = NULL;
871 int head_len,tail_len;
872
Jeff Johnsone7245742012-09-05 17:12:55 -0700873 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -0700874 if (params->head && !params->head_len)
875 return -EINVAL;
876
877 old = pAdapter->sessionCtx.ap.beacon;
878
879 if (!params->head && !old)
880 return -EINVAL;
881
882 if (params->tail && !params->tail_len)
883 return -EINVAL;
884
885#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,38))
886 /* Kernel 3.0 is not updating dtim_period for set beacon */
887 if (!params->dtim_period)
888 return -EINVAL;
889#endif
890
891 if(params->head)
892 head_len = params->head_len;
893 else
894 head_len = old->head_len;
895
896 if(params->tail || !old)
897 tail_len = params->tail_len;
898 else
899 tail_len = old->tail_len;
900
901 size = sizeof(beacon_data_t) + head_len + tail_len;
902
903 beacon = kzalloc(size, GFP_KERNEL);
904
905 if( beacon == NULL )
906 return -ENOMEM;
907
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700908#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -0700909 if(params->dtim_period || !old )
910 beacon->dtim_period = params->dtim_period;
911 else
912 beacon->dtim_period = old->dtim_period;
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700913#else
914 if(dtim_period || !old )
915 beacon->dtim_period = dtim_period;
916 else
917 beacon->dtim_period = old->dtim_period;
918#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530919
Jeff Johnson295189b2012-06-20 16:38:30 -0700920 beacon->head = ((u8 *) beacon) + sizeof(beacon_data_t);
921 beacon->tail = beacon->head + head_len;
922 beacon->head_len = head_len;
923 beacon->tail_len = tail_len;
924
925 if(params->head) {
926 memcpy (beacon->head,params->head,beacon->head_len);
927 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530928 else {
Jeff Johnson295189b2012-06-20 16:38:30 -0700929 if(old)
930 memcpy (beacon->head,old->head,beacon->head_len);
931 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530932
Jeff Johnson295189b2012-06-20 16:38:30 -0700933 if(params->tail) {
934 memcpy (beacon->tail,params->tail,beacon->tail_len);
935 }
936 else {
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530937 if(old)
Jeff Johnson295189b2012-06-20 16:38:30 -0700938 memcpy (beacon->tail,old->tail,beacon->tail_len);
939 }
940
941 *ppBeacon = beacon;
942
943 kfree(old);
944
945 return 0;
946
947}
Jeff Johnson295189b2012-06-20 16:38:30 -0700948
949v_U8_t* wlan_hdd_cfg80211_get_ie_ptr(v_U8_t *pIes, int length, v_U8_t eid)
950{
951 int left = length;
952 v_U8_t *ptr = pIes;
953 v_U8_t elem_id,elem_len;
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530954
Jeff Johnson295189b2012-06-20 16:38:30 -0700955 while(left >= 2)
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530956 {
Jeff Johnson295189b2012-06-20 16:38:30 -0700957 elem_id = ptr[0];
958 elem_len = ptr[1];
959 left -= 2;
960 if(elem_len > left)
961 {
962 hddLog(VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -0700963 FL("****Invalid IEs eid = %d elem_len=%d left=%d*****"),
Jeff Johnson295189b2012-06-20 16:38:30 -0700964 eid,elem_len,left);
965 return NULL;
966 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530967 if (elem_id == eid)
Jeff Johnson295189b2012-06-20 16:38:30 -0700968 {
969 return ptr;
970 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530971
Jeff Johnson295189b2012-06-20 16:38:30 -0700972 left -= elem_len;
973 ptr += (elem_len + 2);
974 }
975 return NULL;
976}
977
Jeff Johnson295189b2012-06-20 16:38:30 -0700978/* Check if rate is 11g rate or not */
979static int wlan_hdd_rate_is_11g(u8 rate)
980{
981 u8 gRateArray[8] = {12, 18, 24, 36, 48, 72, 96, 104}; /* actual rate * 2 */
982 u8 i;
983 for (i = 0; i < 8; i++)
984 {
985 if(rate == gRateArray[i])
986 return TRUE;
987 }
988 return FALSE;
989}
990
991/* Check for 11g rate and set proper 11g only mode */
992static void wlan_hdd_check_11gmode(u8 *pIe, u8* require_ht,
993 u8* pCheckRatesfor11g, eSapPhyMode* pSapHw_mode)
994{
995 u8 i, num_rates = pIe[0];
996
997 pIe += 1;
998 for ( i = 0; i < num_rates; i++)
999 {
1000 if( *pCheckRatesfor11g && (TRUE == wlan_hdd_rate_is_11g(pIe[i] & RATE_MASK)))
1001 {
1002 /* If rate set have 11g rate than change the mode to 11G */
1003 *pSapHw_mode = eSAP_DOT11_MODE_11g;
1004 if (pIe[i] & BASIC_RATE_MASK)
1005 {
1006 /* If we have 11g rate as basic rate, it means mode
1007 is 11g only mode.
1008 */
1009 *pSapHw_mode = eSAP_DOT11_MODE_11g_ONLY;
1010 *pCheckRatesfor11g = FALSE;
1011 }
1012 }
1013 else if((BASIC_RATE_MASK | WLAN_BSS_MEMBERSHIP_SELECTOR_HT_PHY) == pIe[i])
1014 {
1015 *require_ht = TRUE;
1016 }
1017 }
1018 return;
1019}
1020
1021static void wlan_hdd_set_sapHwmode(hdd_adapter_t *pHostapdAdapter)
1022{
1023 tsap_Config_t *pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
1024 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
1025 struct ieee80211_mgmt *pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
1026 u8 checkRatesfor11g = TRUE;
1027 u8 require_ht = FALSE;
1028 u8 *pIe=NULL;
1029
1030 pConfig->SapHw_mode= eSAP_DOT11_MODE_11b;
1031
1032 pIe = wlan_hdd_cfg80211_get_ie_ptr(&pMgmt_frame->u.beacon.variable[0],
1033 pBeacon->head_len, WLAN_EID_SUPP_RATES);
1034 if (pIe != NULL)
1035 {
1036 pIe += 1;
1037 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
1038 &pConfig->SapHw_mode);
1039 }
1040
1041 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
1042 WLAN_EID_EXT_SUPP_RATES);
1043 if (pIe != NULL)
1044 {
1045
1046 pIe += 1;
1047 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
1048 &pConfig->SapHw_mode);
1049 }
1050
1051 if( pConfig->channel > 14 )
1052 {
1053 pConfig->SapHw_mode= eSAP_DOT11_MODE_11a;
1054 }
1055
1056 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
1057 WLAN_EID_HT_CAPABILITY);
1058
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301059 if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07001060 {
1061 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n;
1062 if(require_ht)
1063 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n_ONLY;
1064 }
1065}
1066
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05301067static int wlan_hdd_add_ie(hdd_adapter_t* pHostapdAdapter, v_U8_t *genie,
1068 v_U8_t *total_ielen, v_U8_t *oui, v_U8_t oui_size)
1069{
1070 v_U8_t ielen = 0;
1071 v_U8_t *pIe = NULL;
1072 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
1073
1074 pIe = wlan_hdd_get_vendor_oui_ie_ptr(oui, oui_size,
1075 pBeacon->tail, pBeacon->tail_len);
1076
1077 if (pIe)
1078 {
1079 ielen = pIe[1] + 2;
1080 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
1081 {
1082 vos_mem_copy(&genie[*total_ielen], pIe, ielen);
1083 }
1084 else
1085 {
1086 hddLog( VOS_TRACE_LEVEL_ERROR, "**Ie Length is too big***");
1087 return -EINVAL;
1088 }
1089 *total_ielen += ielen;
1090 }
1091 return 0;
1092}
1093
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001094#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07001095static int wlan_hdd_cfg80211_update_apies(hdd_adapter_t* pHostapdAdapter,
1096 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001097#else
1098static int wlan_hdd_cfg80211_update_apies(hdd_adapter_t* pHostapdAdapter,
1099 struct cfg80211_beacon_data *params)
1100#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07001101{
1102 v_U8_t *genie;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05301103 v_U8_t total_ielen = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07001104 v_U8_t addIE[1] = {0};
Jeff Johnsone7245742012-09-05 17:12:55 -07001105 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07001106
1107 genie = vos_mem_malloc(MAX_GENIE_LEN);
1108
1109 if(genie == NULL) {
1110
1111 return -ENOMEM;
1112 }
1113
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05301114 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
1115 &total_ielen, WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07001116 {
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05301117 ret = -EINVAL;
1118 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001119 }
1120
1121#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05301122 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
1123 &total_ielen, WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE))
1124 {
1125 ret = -EINVAL;
1126 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001127 }
1128#endif
1129
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05301130 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
1131 &total_ielen, P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07001132 {
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05301133 ret = -EINVAL;
1134 goto done;
1135 }
1136
1137 if (WLAN_HDD_SOFTAP == pHostapdAdapter->device_mode)
1138 {
1139 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
1140 &total_ielen, SS_OUI_TYPE, SS_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07001141 {
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05301142 ret = -EINVAL;
1143 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001144 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001145 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001146
1147 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1148 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, genie, total_ielen, NULL,
1149 eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
1150 {
1151 hddLog(LOGE,
1152 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001153 ret = -EINVAL;
1154 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001155 }
1156
1157 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1158 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
1159 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
1160 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
1161 ==eHAL_STATUS_FAILURE)
1162 {
1163 hddLog(LOGE,
1164 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001165 ret = -EINVAL;
1166 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001167 }
1168
1169 // Added for ProResp IE
1170 if ( (params->proberesp_ies != NULL) && (params->proberesp_ies_len != 0) )
1171 {
1172 u16 rem_probe_resp_ie_len = params->proberesp_ies_len;
1173 u8 probe_rsp_ie_len[3] = {0};
1174 u8 counter = 0;
1175 /* Check Probe Resp Length if it is greater then 255 then Store
1176 Probe Resp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1 &
1177 WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are not able
1178 Store More then 255 bytes into One Variable.
1179 */
1180 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
1181 {
1182 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
1183 {
1184 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
1185 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
1186 }
1187 else
1188 {
1189 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
1190 rem_probe_resp_ie_len = 0;
1191 }
1192 }
1193
1194 rem_probe_resp_ie_len = 0;
1195
1196 if (probe_rsp_ie_len[0] > 0)
1197 {
1198 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1199 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
1200 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
1201 probe_rsp_ie_len[0], NULL,
1202 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
1203 {
1204 hddLog(LOGE,
1205 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001206 ret = -EINVAL;
1207 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001208 }
1209 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
1210 }
1211
1212 if (probe_rsp_ie_len[1] > 0)
1213 {
1214 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1215 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
1216 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
1217 probe_rsp_ie_len[1], NULL,
1218 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
1219 {
1220 hddLog(LOGE,
1221 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001222 ret = -EINVAL;
1223 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001224 }
1225 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
1226 }
1227
1228 if (probe_rsp_ie_len[2] > 0)
1229 {
1230 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1231 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
1232 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
1233 probe_rsp_ie_len[2], NULL,
1234 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
1235 {
1236 hddLog(LOGE,
1237 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001238 ret = -EINVAL;
1239 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001240 }
1241 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
1242 }
1243
1244 if (probe_rsp_ie_len[1] == 0 )
1245 {
1246 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1247 WNI_CFG_PROBE_RSP_ADDNIE_DATA2, (tANI_U8*)addIE, 0, NULL,
1248 eANI_BOOLEAN_FALSE) )
1249 {
1250 hddLog(LOGE,
1251 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM\n");
1252 }
1253 }
1254
1255 if (probe_rsp_ie_len[2] == 0 )
1256 {
1257 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1258 WNI_CFG_PROBE_RSP_ADDNIE_DATA3, (tANI_U8*)addIE, 0, NULL,
1259 eANI_BOOLEAN_FALSE) )
1260 {
1261 hddLog(LOGE,
1262 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM\n");
1263 }
1264 }
1265
1266 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1267 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
1268 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
1269 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
1270 == eHAL_STATUS_FAILURE)
1271 {
1272 hddLog(LOGE,
1273 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001274 ret = -EINVAL;
1275 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001276 }
1277 }
1278 else
1279 {
1280 // Reset WNI_CFG_PROBE_RSP Flags
1281 wlan_hdd_reset_prob_rspies(pHostapdAdapter);
1282
1283 hddLog(VOS_TRACE_LEVEL_INFO,
1284 "%s: No Probe Response IE received in set beacon",
1285 __func__);
1286 }
1287
1288 // Added for AssocResp IE
1289 if ( (params->assocresp_ies != NULL) && (params->assocresp_ies_len != 0) )
1290 {
1291 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1292 WNI_CFG_ASSOC_RSP_ADDNIE_DATA, (tANI_U8*)params->assocresp_ies,
1293 params->assocresp_ies_len, NULL,
1294 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
1295 {
1296 hddLog(LOGE,
1297 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001298 ret = -EINVAL;
1299 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001300 }
1301
1302 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1303 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 1, NULL,
1304 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
1305 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
1306 == eHAL_STATUS_FAILURE)
1307 {
1308 hddLog(LOGE,
1309 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001310 ret = -EINVAL;
1311 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001312 }
1313 }
1314 else
1315 {
1316 hddLog(VOS_TRACE_LEVEL_INFO,
1317 "%s: No Assoc Response IE received in set beacon",
1318 __func__);
1319
1320 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1321 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
1322 eANI_BOOLEAN_FALSE) )
1323 {
1324 hddLog(LOGE,
1325 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM\n");
1326 }
1327 }
1328
Jeff Johnsone7245742012-09-05 17:12:55 -07001329done:
Jeff Johnson295189b2012-06-20 16:38:30 -07001330 vos_mem_free(genie);
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05301331 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07001332}
Jeff Johnson295189b2012-06-20 16:38:30 -07001333
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301334/*
Jeff Johnson295189b2012-06-20 16:38:30 -07001335 * FUNCTION: wlan_hdd_validate_operation_channel
1336 * called by wlan_hdd_cfg80211_start_bss() and
1337 * wlan_hdd_cfg80211_set_channel()
1338 * This function validates whether given channel is part of valid
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301339 * channel list.
1340 */
Jeff Johnson295189b2012-06-20 16:38:30 -07001341static VOS_STATUS wlan_hdd_validate_operation_channel(hdd_adapter_t *pAdapter,int channel)
1342{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301343
Jeff Johnson295189b2012-06-20 16:38:30 -07001344 v_U32_t num_ch = 0;
1345 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN];
1346 u32 indx = 0;
1347 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05301348 v_U8_t fValidChannel = FALSE, count = 0;
1349 hdd_config_t *hdd_pConfig_ini= (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301350
Jeff Johnson295189b2012-06-20 16:38:30 -07001351 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
1352
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05301353 if ( hdd_pConfig_ini->sapAllowAllChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -07001354 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05301355 /* Validate the channel */
1356 for (count = RF_CHAN_1 ; count <= RF_CHAN_165 ; count++)
Jeff Johnson295189b2012-06-20 16:38:30 -07001357 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05301358 if ( channel == rfChannels[count].channelNum )
1359 {
1360 fValidChannel = TRUE;
1361 break;
1362 }
1363 }
1364 if (fValidChannel != TRUE)
1365 {
1366 hddLog(VOS_TRACE_LEVEL_ERROR,
1367 "%s: Invalid Channel [%d]", __func__, channel);
1368 return VOS_STATUS_E_FAILURE;
Jeff Johnson295189b2012-06-20 16:38:30 -07001369 }
1370 }
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05301371 else
Jeff Johnson295189b2012-06-20 16:38:30 -07001372 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05301373 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
1374 valid_ch, &num_ch))
1375 {
1376 hddLog(VOS_TRACE_LEVEL_ERROR,
1377 "%s: failed to get valid channel list", __func__);
1378 return VOS_STATUS_E_FAILURE;
1379 }
1380 for (indx = 0; indx < num_ch; indx++)
1381 {
1382 if (channel == valid_ch[indx])
1383 {
1384 break;
1385 }
1386 }
1387
1388 if (indx >= num_ch)
1389 {
1390 hddLog(VOS_TRACE_LEVEL_ERROR,
1391 "%s: Invalid Channel [%d]", __func__, channel);
1392 return VOS_STATUS_E_FAILURE;
1393 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001394 }
1395 return VOS_STATUS_SUCCESS;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301396
Jeff Johnson295189b2012-06-20 16:38:30 -07001397}
1398
Viral Modi3a32cc52013-02-08 11:14:52 -08001399/**
1400 * FUNCTION: wlan_hdd_cfg80211_set_channel
1401 * This function is used to set the channel number
1402 */
1403static int wlan_hdd_cfg80211_set_channel( struct wiphy *wiphy, struct net_device *dev,
1404 struct ieee80211_channel *chan,
1405 enum nl80211_channel_type channel_type
1406 )
1407{
1408 v_U32_t num_ch = 0;
Jeff Johnson4416a782013-03-25 14:17:50 -07001409 int channel = 0;
Viral Modi3a32cc52013-02-08 11:14:52 -08001410 hdd_adapter_t *pAdapter = NULL;
1411 int freq = chan->center_freq; /* freq is in MHZ */
1412
1413 ENTER();
1414
1415 if( NULL == dev )
1416 {
1417 hddLog(VOS_TRACE_LEVEL_ERROR,
1418 "%s: Called with dev = NULL.\n", __func__);
1419 return -ENODEV;
1420 }
1421 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
1422
1423 hddLog(VOS_TRACE_LEVEL_INFO,
1424 "%s: device_mode = %d freq = %d \n",__func__,
1425 pAdapter->device_mode, chan->center_freq);
1426 if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress)
1427 {
1428 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:LOGP in Progress. Ignore!!!",__func__);
1429 return -EAGAIN;
1430 }
1431
1432 /*
1433 * Do freq to chan conversion
1434 * TODO: for 11a
1435 */
1436
1437 channel = ieee80211_frequency_to_channel(freq);
1438
1439 /* Check freq range */
1440 if ((WNI_CFG_CURRENT_CHANNEL_STAMIN > channel) ||
1441 (WNI_CFG_CURRENT_CHANNEL_STAMAX < channel))
1442 {
1443 hddLog(VOS_TRACE_LEVEL_ERROR,
1444 "%s: Channel [%d] is outside valid range from %d to %d\n",
1445 __func__, channel, WNI_CFG_CURRENT_CHANNEL_STAMIN,
1446 WNI_CFG_CURRENT_CHANNEL_STAMAX);
1447 return -EINVAL;
1448 }
1449
1450 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
1451
Gopichand Nakkala6ab19562013-03-07 13:59:42 +05301452 if ((WLAN_HDD_SOFTAP != pAdapter->device_mode) &&
1453 (WLAN_HDD_P2P_GO != pAdapter->device_mode))
Viral Modi3a32cc52013-02-08 11:14:52 -08001454 {
1455 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pAdapter,channel))
1456 {
1457 hddLog(VOS_TRACE_LEVEL_ERROR,
1458 "%s: Invalid Channel [%d] \n", __func__, channel);
1459 return -EINVAL;
1460 }
1461 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
1462 "%s: set channel to [%d] for device mode =%d",
1463 __func__, channel,pAdapter->device_mode);
1464 }
1465 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Viral Modi3a32cc52013-02-08 11:14:52 -08001466 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Viral Modi3a32cc52013-02-08 11:14:52 -08001467 )
1468 {
1469 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
1470 tCsrRoamProfile * pRoamProfile = &pWextState->roamProfile;
1471 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
1472
1473 if (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState)
1474 {
1475 /* Link is up then return cant set channel*/
1476 hddLog( VOS_TRACE_LEVEL_ERROR,
1477 "%s: IBSS Associated, can't set the channel\n", __func__);
1478 return -EINVAL;
1479 }
1480
1481 num_ch = pRoamProfile->ChannelInfo.numOfChannels = 1;
1482 pHddStaCtx->conn_info.operationChannel = channel;
1483 pRoamProfile->ChannelInfo.ChannelList =
1484 &pHddStaCtx->conn_info.operationChannel;
1485 }
1486 else if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Viral Modi3a32cc52013-02-08 11:14:52 -08001487 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Viral Modi3a32cc52013-02-08 11:14:52 -08001488 )
1489 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05301490 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
1491 {
1492 if(VOS_STATUS_SUCCESS !=
1493 wlan_hdd_validate_operation_channel(pAdapter,channel))
1494 {
1495 hddLog(VOS_TRACE_LEVEL_ERROR,
1496 "%s: Invalid Channel [%d] \n", __func__, channel);
1497 return -EINVAL;
1498 }
1499 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
1500 }
1501 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
Viral Modi3a32cc52013-02-08 11:14:52 -08001502 {
1503 hdd_config_t *cfg_param = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
1504
1505 /* If auto channel selection is configured as enable/ 1 then ignore
1506 channel set by supplicant
1507 */
1508 if ( cfg_param->apAutoChannelSelection )
1509 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05301510 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel =
1511 AUTO_CHANNEL_SELECT;
Viral Modi3a32cc52013-02-08 11:14:52 -08001512 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
1513 "%s: set channel to auto channel (0) for device mode =%d",
1514 __func__, pAdapter->device_mode);
1515 }
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05301516 else
1517 {
1518 if(VOS_STATUS_SUCCESS !=
1519 wlan_hdd_validate_operation_channel(pAdapter,channel))
1520 {
1521 hddLog(VOS_TRACE_LEVEL_ERROR,
1522 "%s: Invalid Channel [%d] \n", __func__, channel);
1523 return -EINVAL;
1524 }
1525 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
1526 }
Viral Modi3a32cc52013-02-08 11:14:52 -08001527 }
1528 }
1529 else
1530 {
1531 hddLog(VOS_TRACE_LEVEL_FATAL,
1532 "%s: Invalid device mode failed to set valid channel", __func__);
1533 return -EINVAL;
1534 }
1535 EXIT();
1536 return 0;
1537}
1538
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301539/*
Madan Mohan Koyyalamudi59381622012-11-28 01:56:47 +05301540 * FUNCTION: wlan_hdd_select_cbmode
1541 * called by wlan_hdd_cfg80211_start_bss() and
1542 * This function selects the cbmode based on primary channel
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301543 */
Madan Mohan Koyyalamudi527935a2012-12-04 16:41:16 -08001544VOS_STATUS wlan_sap_select_cbmode(void *pAdapter,eSapPhyMode SapHw_mode, v_U8_t channel)
Madan Mohan Koyyalamudi59381622012-11-28 01:56:47 +05301545{
1546 tSmeConfigParams smeConfig;
Madan Mohan Koyyalamudi527935a2012-12-04 16:41:16 -08001547 hdd_context_t *pHddCtx = ( hdd_context_t *) pAdapter;
1548 hdd_config_t *pConfigIni = ((hdd_context_t *)(pAdapter))->cfg_ini;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301549
Madan Mohan Koyyalamudi59381622012-11-28 01:56:47 +05301550 if(
1551#ifdef WLAN_FEATURE_11AC
Madan Mohan Koyyalamudi527935a2012-12-04 16:41:16 -08001552 SapHw_mode != eSAP_DOT11_MODE_11ac &&
1553 SapHw_mode != eSAP_DOT11_MODE_11ac_ONLY &&
Madan Mohan Koyyalamudi59381622012-11-28 01:56:47 +05301554#endif
Madan Mohan Koyyalamudi527935a2012-12-04 16:41:16 -08001555 SapHw_mode != eSAP_DOT11_MODE_11n &&
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301556 SapHw_mode != eSAP_DOT11_MODE_11n_ONLY
Madan Mohan Koyyalamudi59381622012-11-28 01:56:47 +05301557 )
1558 {
1559 return VOS_STATUS_SUCCESS;
1560 }
1561
1562 if (!pConfigIni->nChannelBondingMode5GHz) {
1563 return VOS_STATUS_SUCCESS;
1564 }
1565
Madan Mohan Koyyalamudi527935a2012-12-04 16:41:16 -08001566 //channel = pSapConfig->channel;
Madan Mohan Koyyalamudi59381622012-11-28 01:56:47 +05301567 vos_mem_zero(&smeConfig, sizeof (tSmeConfigParams));
1568
1569 sme_GetConfigParam(pHddCtx->hHal, &smeConfig);
1570
1571#ifdef WLAN_FEATURE_11AC
1572
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301573 if ( SapHw_mode == eSAP_DOT11_MODE_11ac ||
Madan Mohan Koyyalamudi527935a2012-12-04 16:41:16 -08001574 SapHw_mode == eSAP_DOT11_MODE_11ac_ONLY )
Madan Mohan Koyyalamudi59381622012-11-28 01:56:47 +05301575 {
1576 if ( channel== 36 || channel == 52 || channel == 100 ||
1577 channel == 116 || channel == 149 )
1578 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301579 smeConfig.csrConfig.channelBondingMode5GHz =
Madan Mohan Koyyalamudi59381622012-11-28 01:56:47 +05301580 PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_LOW - 1;
1581 }
1582 else if ( channel == 40 || channel == 56 || channel == 104 ||
1583 channel == 120 || channel == 153 )
1584 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301585 smeConfig.csrConfig.channelBondingMode5GHz =
Madan Mohan Koyyalamudi59381622012-11-28 01:56:47 +05301586 PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_LOW - 1;
1587 }
1588 else if ( channel == 44 || channel == 60 || channel == 108 ||
1589 channel == 124 || channel == 157 )
1590 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301591 smeConfig.csrConfig.channelBondingMode5GHz =
Madan Mohan Koyyalamudi59381622012-11-28 01:56:47 +05301592 PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_HIGH -1;
1593 }
1594 else if ( channel == 48 || channel == 64 || channel == 112 ||
1595 channel == 128 || channel == 161 )
1596 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301597 smeConfig.csrConfig.channelBondingMode5GHz =
Madan Mohan Koyyalamudi59381622012-11-28 01:56:47 +05301598 PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_HIGH - 1;
1599 }
Shailender Karmuchi84f11f02013-02-12 17:11:45 -08001600 else if ( channel == 165 )
1601 {
1602 smeConfig.csrConfig.channelBondingMode5GHz = 0;
1603 }
Madan Mohan Koyyalamudi59381622012-11-28 01:56:47 +05301604 }
1605#endif
Madan Mohan Koyyalamudi527935a2012-12-04 16:41:16 -08001606 if ( SapHw_mode == eSAP_DOT11_MODE_11n ||
1607 SapHw_mode == eSAP_DOT11_MODE_11n_ONLY )
Madan Mohan Koyyalamudi59381622012-11-28 01:56:47 +05301608 {
1609 if ( channel== 40 || channel == 48 || channel == 56 ||
1610 channel == 64 || channel == 104 || channel == 112 ||
1611 channel == 120 || channel == 128 || channel == 136 ||
1612 channel == 144 || channel == 153 || channel == 161 )
1613 {
1614 smeConfig.csrConfig.channelBondingMode5GHz = 1;
1615 }
1616 else if ( channel== 36 || channel == 44 || channel == 52 ||
1617 channel == 60 || channel == 100 || channel == 108 ||
1618 channel == 116 || channel == 124 || channel == 132 ||
1619 channel == 140 || channel == 149 || channel == 157 )
1620 {
1621 smeConfig.csrConfig.channelBondingMode5GHz = 2;
1622 }
Shailender Karmuchi84f11f02013-02-12 17:11:45 -08001623 else if ( channel == 165 )
1624 {
1625 smeConfig.csrConfig.channelBondingMode5GHz = 0;
1626 }
Madan Mohan Koyyalamudi59381622012-11-28 01:56:47 +05301627 }
1628 pr_info ("cbmode selected=%ld\n",smeConfig.csrConfig.channelBondingMode5GHz);
1629
1630 sme_UpdateConfig (pHddCtx->hHal,&smeConfig);
1631 return VOS_STATUS_SUCCESS;
1632}
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001633
Jeff Johnson295189b2012-06-20 16:38:30 -07001634#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
1635static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
1636 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001637#else
1638static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
1639 struct cfg80211_beacon_data *params,
1640 const u8 *ssid, size_t ssid_len,
1641 enum nl80211_hidden_ssid hidden_ssid)
1642#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07001643{
1644 tsap_Config_t *pConfig;
1645 beacon_data_t *pBeacon = NULL;
1646 struct ieee80211_mgmt *pMgmt_frame;
1647 v_U8_t *pIe=NULL;
1648 v_U16_t capab_info;
1649 eCsrAuthType RSNAuthType;
1650 eCsrEncryptionType RSNEncryptType;
1651 eCsrEncryptionType mcRSNEncryptType;
1652 int status = VOS_STATUS_SUCCESS;
1653 tpWLAN_SAPEventCB pSapEventCallback;
1654 hdd_hostapd_state_t *pHostapdState;
1655 v_U8_t wpaRsnIEdata[(SIR_MAC_MAX_IE_LENGTH * 2)+4]; //Max ie length 255 * 2(WPA+RSN) + 2 bytes (vendor specific ID) * 2
1656 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05301657 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07001658 struct qc_mac_acl_entry *acl_entry = NULL;
1659 v_SINT_t i;
Madan Mohan Koyyalamudi543172b2012-12-05 16:40:18 -08001660 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07001661
1662 ENTER();
1663
1664 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter);
1665
1666 pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
1667
1668 pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
1669
1670 pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
1671
1672 pConfig->beacon_int = pMgmt_frame->u.beacon.beacon_int;
1673
1674 //channel is already set in the set_channel Call back
1675 //pConfig->channel = pCommitConfig->channel;
1676
1677 /*Protection parameter to enable or disable*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301678 pConfig->protEnabled =
Jeff Johnson295189b2012-06-20 16:38:30 -07001679 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtEnabled;
1680
1681 pConfig->dtim_period = pBeacon->dtim_period;
1682
1683 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"****pConfig->dtim_period=%d***\n",
1684 pConfig->dtim_period);
1685
1686
Madan Mohan Koyyalamudie0ca11f2012-11-27 15:57:52 -08001687 if (pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson32d95a32012-09-10 13:15:23 -07001688 {
1689 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -07001690 WLAN_EID_COUNTRY);
Jeff Johnson32d95a32012-09-10 13:15:23 -07001691 if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07001692 {
Jeff Johnson32d95a32012-09-10 13:15:23 -07001693 tANI_BOOLEAN restartNeeded;
Jeff Johnson32d95a32012-09-10 13:15:23 -07001694 pConfig->ieee80211d = 1;
1695 vos_mem_copy(pConfig->countryCode, &pIe[2], 3);
1696 sme_setRegInfo(hHal, pConfig->countryCode);
1697 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
Jeff Johnson295189b2012-06-20 16:38:30 -07001698 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07001699 else
1700 {
1701 pConfig->ieee80211d = 0;
1702 }
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05301703 /*
1704 * If auto channel is configured i.e. channel is 0,
1705 * so skip channel validation.
1706 */
1707 if( AUTO_CHANNEL_SELECT != pConfig->channel )
1708 {
1709 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pHostapdAdapter,pConfig->channel))
1710 {
1711 hddLog(VOS_TRACE_LEVEL_ERROR,
1712 "%s: Invalid Channel [%d] \n", __func__, pConfig->channel);
1713 return -EINVAL;
1714 }
1715 }
1716 else
1717 {
1718 if(1 != pHddCtx->is_dynamic_channel_range_set)
1719 {
1720 hdd_config_t *hdd_pConfig= (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini;
1721 WLANSAP_SetChannelRange(hHal, hdd_pConfig->apStartChannelNum,
1722 hdd_pConfig->apEndChannelNum,hdd_pConfig->apOperatingBand);
1723 }
1724 pHddCtx->is_dynamic_channel_range_set = 0;
1725 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001726 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07001727 else
Jeff Johnson295189b2012-06-20 16:38:30 -07001728 {
1729 pConfig->ieee80211d = 0;
1730 }
1731 pConfig->authType = eSAP_AUTO_SWITCH;
1732
1733 capab_info = pMgmt_frame->u.beacon.capab_info;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301734
1735 pConfig->privacy = (pMgmt_frame->u.beacon.capab_info &
Jeff Johnson295189b2012-06-20 16:38:30 -07001736 WLAN_CAPABILITY_PRIVACY) ? VOS_TRUE : VOS_FALSE;
1737
1738 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uPrivacy = pConfig->privacy;
1739
1740 /*Set wps station to configured*/
1741 pIe = wlan_hdd_get_wps_ie_ptr(pBeacon->tail, pBeacon->tail_len);
1742
1743 if(pIe)
1744 {
1745 if(pIe[1] < (2 + WPS_OUI_TYPE_SIZE))
1746 {
1747 hddLog( VOS_TRACE_LEVEL_ERROR, "**Wps Ie Length is too small***\n");
1748 return -EINVAL;
1749 }
1750 else if(memcmp(&pIe[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) == 0)
1751 {
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07001752 hddLog( VOS_TRACE_LEVEL_INFO, "** WPS IE(len %d) ***", (pIe[1]+2));
Jeff Johnson295189b2012-06-20 16:38:30 -07001753 /* Check 15 bit of WPS IE as it contain information for wps state
1754 * WPS state
1755 */
1756 if(SAP_WPS_ENABLED_UNCONFIGURED == pIe[15])
1757 {
1758 pConfig->wps_state = SAP_WPS_ENABLED_UNCONFIGURED;
1759 } else if(SAP_WPS_ENABLED_CONFIGURED == pIe[15])
1760 {
1761 pConfig->wps_state = SAP_WPS_ENABLED_CONFIGURED;
1762 }
1763 }
1764 }
1765 else
1766 {
1767 pConfig->wps_state = SAP_WPS_DISABLED;
1768 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301769 pConfig->fwdWPSPBCProbeReq = 1; // Forward WPS PBC probe request frame up
Jeff Johnson295189b2012-06-20 16:38:30 -07001770
1771 pConfig->RSNWPAReqIELength = 0;
1772 pConfig->pRSNWPAReqIE = NULL;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301773 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -07001774 WLAN_EID_RSN);
1775 if(pIe && pIe[1])
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301776 {
Jeff Johnson295189b2012-06-20 16:38:30 -07001777 pConfig->RSNWPAReqIELength = pIe[1] + 2;
1778 memcpy(&wpaRsnIEdata[0], pIe, pConfig->RSNWPAReqIELength);
1779 pConfig->pRSNWPAReqIE = &wpaRsnIEdata[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301780 /* The actual processing may eventually be more extensive than
1781 * this. Right now, just consume any PMKIDs that are sent in
Jeff Johnson295189b2012-06-20 16:38:30 -07001782 * by the app.
1783 * */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301784 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -07001785 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
1786 &RSNEncryptType,
1787 &mcRSNEncryptType,
1788 &RSNAuthType,
1789 pConfig->pRSNWPAReqIE[1]+2,
1790 pConfig->pRSNWPAReqIE );
1791
1792 if( VOS_STATUS_SUCCESS == status )
1793 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301794 /* Now copy over all the security attributes you have
1795 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -07001796 * */
1797 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
1798 pConfig->mcRSNEncryptType = mcRSNEncryptType;
1799 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
1800 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05301801 hddLog( LOG1, FL("CSR AuthType = %d, "
Jeff Johnson295189b2012-06-20 16:38:30 -07001802 "EncryptionType = %d mcEncryptionType = %d\n"),
1803 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
1804 }
1805 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301806
Jeff Johnson295189b2012-06-20 16:38:30 -07001807 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE,
1808 pBeacon->tail, pBeacon->tail_len);
1809
1810 if(pIe && pIe[1] && (pIe[0] == DOT11F_EID_WPA))
1811 {
1812 if (pConfig->pRSNWPAReqIE)
1813 {
1814 /*Mixed mode WPA/WPA2*/
1815 memcpy((&wpaRsnIEdata[0] + pConfig->RSNWPAReqIELength), pIe, pIe[1] + 2);
1816 pConfig->RSNWPAReqIELength += pIe[1] + 2;
1817 }
1818 else
1819 {
1820 pConfig->RSNWPAReqIELength = pIe[1] + 2;
1821 memcpy(&wpaRsnIEdata[0], pIe, pConfig->RSNWPAReqIELength);
1822 pConfig->pRSNWPAReqIE = &wpaRsnIEdata[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301823 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -07001824 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
1825 &RSNEncryptType,
1826 &mcRSNEncryptType,
1827 &RSNAuthType,
1828 pConfig->pRSNWPAReqIE[1]+2,
1829 pConfig->pRSNWPAReqIE );
1830
1831 if( VOS_STATUS_SUCCESS == status )
1832 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301833 /* Now copy over all the security attributes you have
1834 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -07001835 * */
1836 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
1837 pConfig->mcRSNEncryptType = mcRSNEncryptType;
1838 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
1839 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05301840 hddLog( LOG1, FL("CSR AuthType = %d, "
Jeff Johnson295189b2012-06-20 16:38:30 -07001841 "EncryptionType = %d mcEncryptionType = %d\n"),
1842 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
1843 }
1844 }
1845 }
1846
Jeff Johnson4416a782013-03-25 14:17:50 -07001847 if (pConfig->RSNWPAReqIELength > sizeof wpaRsnIEdata) {
1848 hddLog( VOS_TRACE_LEVEL_ERROR, "**RSNWPAReqIELength is too large***");
1849 return -EINVAL;
1850 }
1851
Jeff Johnson295189b2012-06-20 16:38:30 -07001852 pConfig->SSIDinfo.ssidHidden = VOS_FALSE;
1853
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001854#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07001855 if (params->ssid != NULL)
1856 {
1857 memcpy(pConfig->SSIDinfo.ssid.ssId, params->ssid, params->ssid_len);
1858 pConfig->SSIDinfo.ssid.length = params->ssid_len;
1859 if (params->hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
1860 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
1861 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001862#else
1863 if (ssid != NULL)
1864 {
1865 memcpy(pConfig->SSIDinfo.ssid.ssId, ssid, ssid_len);
1866 pConfig->SSIDinfo.ssid.length = ssid_len;
1867 if (hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
1868 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
1869 }
1870#endif
1871
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301872 vos_mem_copy(pConfig->self_macaddr.bytes,
Jeff Johnson295189b2012-06-20 16:38:30 -07001873 pHostapdAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301874
Jeff Johnson295189b2012-06-20 16:38:30 -07001875 /* default value */
1876 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
1877 pConfig->num_accept_mac = 0;
1878 pConfig->num_deny_mac = 0;
1879
1880 pIe = wlan_hdd_get_vendor_oui_ie_ptr(BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
1881 pBeacon->tail, pBeacon->tail_len);
1882
1883 /* pIe for black list is following form:
1884 type : 1 byte
1885 length : 1 byte
1886 OUI : 4 bytes
1887 acl type : 1 byte
1888 no of mac addr in black list: 1 byte
1889 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301890 */
1891 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07001892 {
1893 pConfig->SapMacaddr_acl = pIe[6];
1894 pConfig->num_deny_mac = pIe[7];
1895 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no deny mac = %d\n",
1896 pIe[6], pIe[7]);
1897 if (pConfig->num_deny_mac > MAX_MAC_ADDRESS_DENIED)
1898 pConfig->num_deny_mac = MAX_MAC_ADDRESS_DENIED;
1899 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
1900 for (i = 0; i < pConfig->num_deny_mac; i++)
1901 {
1902 vos_mem_copy(&pConfig->deny_mac[i], acl_entry->addr, sizeof(qcmacaddr));
1903 acl_entry++;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301904 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001905 }
1906 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
1907 pBeacon->tail, pBeacon->tail_len);
1908
1909 /* pIe for white list is following form:
1910 type : 1 byte
1911 length : 1 byte
1912 OUI : 4 bytes
1913 acl type : 1 byte
1914 no of mac addr in white list: 1 byte
1915 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301916 */
1917 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07001918 {
1919 pConfig->SapMacaddr_acl = pIe[6];
1920 pConfig->num_accept_mac = pIe[7];
1921 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no accept mac = %d\n",
1922 pIe[6], pIe[7]);
1923 if (pConfig->num_accept_mac > MAX_MAC_ADDRESS_ACCEPTED)
1924 pConfig->num_accept_mac = MAX_MAC_ADDRESS_ACCEPTED;
1925 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
1926 for (i = 0; i < pConfig->num_accept_mac; i++)
1927 {
1928 vos_mem_copy(&pConfig->accept_mac[i], acl_entry->addr, sizeof(qcmacaddr));
1929 acl_entry++;
1930 }
1931 }
1932 wlan_hdd_set_sapHwmode(pHostapdAdapter);
1933
Jeff Johnsone7245742012-09-05 17:12:55 -07001934#ifdef WLAN_FEATURE_11AC
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -08001935 /* Overwrite the hostapd setting for HW mode only for 11ac.
1936 * This is valid only if mode is set to 11n in hostapd and either AUTO or 11ac in .ini .
1937 * Otherwise, leave whatever is set in hostapd (a OR b OR g OR n mode) */
1938 if( ((pConfig->SapHw_mode == eSAP_DOT11_MODE_11n) ||
1939 (pConfig->SapHw_mode == eSAP_DOT11_MODE_11n_ONLY)) &&
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301940 (((WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->dot11Mode == eHDD_DOT11_MODE_AUTO) ||
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -08001941 ((WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->dot11Mode == eHDD_DOT11_MODE_11ac) ||
1942 ((WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->dot11Mode == eHDD_DOT11_MODE_11ac_ONLY)) )
Jeff Johnsone7245742012-09-05 17:12:55 -07001943 {
1944 pConfig->SapHw_mode = eSAP_DOT11_MODE_11ac;
1945 }
1946#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301947
Madan Mohan Koyyalamudi527935a2012-12-04 16:41:16 -08001948 if( AUTO_CHANNEL_SELECT != pConfig->channel)
1949 wlan_sap_select_cbmode((WLAN_HDD_GET_CTX(pHostapdAdapter)),pConfig->SapHw_mode,pConfig->channel);
Jeff Johnson295189b2012-06-20 16:38:30 -07001950 // ht_capab is not what the name conveys,this is used for protection bitmap
1951 pConfig->ht_capab =
1952 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtection;
1953
1954 if ( 0 != wlan_hdd_cfg80211_update_apies(pHostapdAdapter, params) )
1955 {
1956 hddLog(LOGE, FL("SAP Not able to set AP IEs"));
1957 return -EINVAL;
1958 }
1959
1960 //Uapsd Enabled Bit
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301961 pConfig->UapsdEnable =
Jeff Johnson295189b2012-06-20 16:38:30 -07001962 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apUapsdEnabled;
1963 //Enable OBSS protection
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301964 pConfig->obssProtEnabled =
1965 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apOBSSProtEnabled;
Jeff Johnson295189b2012-06-20 16:38:30 -07001966
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301967 hddLog(LOGW, FL("SOftAP macaddress : "MAC_ADDRESS_STR"\n"),
Jeff Johnson295189b2012-06-20 16:38:30 -07001968 MAC_ADDR_ARRAY(pHostapdAdapter->macAddressCurrent.bytes));
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301969 hddLog(LOGW,FL("ssid =%s\n"), pConfig->SSIDinfo.ssid.ssId);
Jeff Johnson295189b2012-06-20 16:38:30 -07001970 hddLog(LOGW,FL("beaconint=%d, channel=%d\n"), (int)pConfig->beacon_int,
1971 (int)pConfig->channel);
1972 hddLog(LOGW,FL("hw_mode=%x\n"), pConfig->SapHw_mode);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301973 hddLog(LOGW,FL("privacy=%d, authType=%d\n"), pConfig->privacy,
1974 pConfig->authType);
Jeff Johnson295189b2012-06-20 16:38:30 -07001975 hddLog(LOGW,FL("RSN/WPALen=%d, \n"),(int)pConfig->RSNWPAReqIELength);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301976 hddLog(LOGW,FL("Uapsd = %d\n"),pConfig->UapsdEnable);
Jeff Johnson295189b2012-06-20 16:38:30 -07001977 hddLog(LOGW,FL("ProtEnabled = %d, OBSSProtEnabled = %d\n"),
1978 pConfig->protEnabled, pConfig->obssProtEnabled);
1979
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301980 if(test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -07001981 {
1982 //Bss already started. just return.
1983 //TODO Probably it should update some beacon params.
1984 hddLog( LOGE, "Bss Already started...Ignore the request");
1985 EXIT();
1986 return 0;
1987 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301988
Jeff Johnson295189b2012-06-20 16:38:30 -07001989 pConfig->persona = pHostapdAdapter->device_mode;
1990
1991 pSapEventCallback = hdd_hostapd_SAPEventCB;
1992 if(WLANSAP_StartBss(pVosContext, pSapEventCallback, pConfig,
1993 (v_PVOID_t)pHostapdAdapter->dev) != VOS_STATUS_SUCCESS)
1994 {
1995 hddLog(LOGE,FL("SAP Start Bss fail\n"));
1996 return -EINVAL;
1997 }
1998
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301999 hddLog(LOG1,
Jeff Johnson295189b2012-06-20 16:38:30 -07002000 FL("Waiting for Scan to complete(auto mode) and BSS to start"));
2001
2002 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302003
Jeff Johnson295189b2012-06-20 16:38:30 -07002004 if (!VOS_IS_STATUS_SUCCESS(status))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302005 {
2006 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07002007 ("ERROR: HDD vos wait for single_event failed!!\n"));
2008 VOS_ASSERT(0);
2009 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302010
Jeff Johnson295189b2012-06-20 16:38:30 -07002011 //Succesfully started Bss update the state bit.
2012 set_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags);
2013
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07002014#ifdef WLAN_FEATURE_P2P_DEBUG
2015 if (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO)
2016 {
2017 if(globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED)
2018 {
2019 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
2020 hddLog(LOGE,"[P2P State] From Go nego completed to "
Jeff Johnson1250df42012-12-10 14:31:52 -08002021 "Non-autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07002022 }
2023 else if(globalP2PConnectionStatus == P2P_NOT_ACTIVE)
2024 {
2025 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
2026 hddLog(LOGE,"[P2P State] From Inactive to "
Jeff Johnson1250df42012-12-10 14:31:52 -08002027 "Autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07002028 }
2029 }
2030#endif
2031
Jeff Johnson295189b2012-06-20 16:38:30 -07002032 pHostapdState->bCommit = TRUE;
2033 EXIT();
2034
2035 return 0;
2036}
2037
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002038#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302039static int wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy,
2040 struct net_device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -07002041 struct beacon_parameters *params)
2042{
2043 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302044 int status=VOS_STATUS_SUCCESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07002045
2046 ENTER();
2047
2048 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "device mode=%d\n",pAdapter->device_mode);
2049
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002050 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
2051 {
2052 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2053 "%s:LOGP in Progress. Ignore!!!", __func__);
2054 return -EAGAIN;
2055 }
2056
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302057 if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07002058 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07002059 )
2060 {
2061 beacon_data_t *old,*new;
2062
2063 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302064
Jeff Johnson295189b2012-06-20 16:38:30 -07002065 if (old)
2066 return -EALREADY;
2067
2068 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
2069
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302070 if(status != VOS_STATUS_SUCCESS)
Jeff Johnson295189b2012-06-20 16:38:30 -07002071 {
2072 hddLog(VOS_TRACE_LEVEL_FATAL,
2073 "%s:Error!!! Allocating the new beacon\n",__func__);
2074 return -EINVAL;
2075 }
2076
2077 pAdapter->sessionCtx.ap.beacon = new;
2078
2079 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
2080 }
2081
2082 EXIT();
2083 return status;
2084}
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302085
2086static int wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07002087 struct net_device *dev,
2088 struct beacon_parameters *params)
2089{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302090 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnson295189b2012-06-20 16:38:30 -07002091 int status=VOS_STATUS_SUCCESS;
2092
2093 ENTER();
2094
2095 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",
2096 __func__,pAdapter->device_mode);
2097
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002098 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
2099 {
2100 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2101 "%s:LOGP in Progress. Ignore!!!", __func__);
2102 return -EAGAIN;
2103 }
2104
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302105 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07002106 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302107 )
Jeff Johnson295189b2012-06-20 16:38:30 -07002108 {
2109 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302110
Jeff Johnson295189b2012-06-20 16:38:30 -07002111 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302112
Jeff Johnson295189b2012-06-20 16:38:30 -07002113 if (!old)
2114 return -ENOENT;
2115
2116 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
2117
2118 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302119 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson295189b2012-06-20 16:38:30 -07002120 "%s: Error!!! Allocating the new beacon\n",__func__);
2121 return -EINVAL;
2122 }
2123
2124 pAdapter->sessionCtx.ap.beacon = new;
2125
2126 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
2127 }
2128
2129 EXIT();
2130 return status;
2131}
2132
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002133#endif //(LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
2134
2135#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07002136static int wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy,
2137 struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002138#else
2139static int wlan_hdd_cfg80211_stop_ap (struct wiphy *wiphy,
2140 struct net_device *dev)
2141#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07002142{
2143 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnsone7245742012-09-05 17:12:55 -07002144 hdd_context_t *pHddCtx = NULL;
2145 hdd_scaninfo_t *pScanInfo = NULL;
2146 hdd_adapter_t *staAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07002147 VOS_STATUS status = 0;
2148
2149 ENTER();
2150
2151 if (NULL == pAdapter)
2152 {
2153 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002154 "%s: HDD adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002155 return -ENODEV;
2156 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07002157
Jeff Johnson4416a782013-03-25 14:17:50 -07002158 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07002159 if (NULL == pHddCtx)
2160 {
2161 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002162 "%s: HDD context is Null", __func__);
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07002163 return -ENODEV;
2164 }
Jeff Johnson4416a782013-03-25 14:17:50 -07002165 if (pHddCtx->isLogpInProgress)
2166 {
2167 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2168 "%s:LOGP in Progress. Ignore!!!", __func__);
2169 return -EAGAIN;
2170 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07002171
2172 staAdapter = hdd_get_adapter(pAdapter->pHddCtx, WLAN_HDD_INFRA_STATION);
2173 if (NULL == staAdapter)
2174 {
2175 staAdapter = hdd_get_adapter(pAdapter->pHddCtx, WLAN_HDD_P2P_CLIENT);
2176 if (NULL == staAdapter)
2177 {
2178 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002179 "%s: HDD adapter context is Null", __func__);
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07002180 return -ENODEV;
2181 }
2182 }
2183
2184 pScanInfo = &pHddCtx->scan_info;
2185
Jeff Johnson4416a782013-03-25 14:17:50 -07002186 if (pHddCtx->isLogpInProgress)
Jeff Johnson295189b2012-06-20 16:38:30 -07002187 {
2188 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:LOGP in Progress. Ignore!!!",__func__);
2189 return -EAGAIN;
2190 }
2191
2192 pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
2193
2194 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",
2195 __func__,pAdapter->device_mode);
2196
Jeff Johnsone7245742012-09-05 17:12:55 -07002197 if ((pScanInfo != NULL) && pScanInfo->mScanPending)
2198 {
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -08002199 INIT_COMPLETION(pScanInfo->abortscan_event_var);
Jeff Johnsone7245742012-09-05 17:12:55 -07002200 hdd_abort_mac_scan(staAdapter->pHddCtx);
2201 status = wait_for_completion_interruptible_timeout(
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -08002202 &pScanInfo->abortscan_event_var,
Jeff Johnsone7245742012-09-05 17:12:55 -07002203 msecs_to_jiffies(WLAN_WAIT_TIME_ABORTSCAN));
2204 if (!status)
2205 {
2206 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Jeff Johnson902c9832012-12-10 14:28:09 -08002207 "%s: Timeout occurred while waiting for abortscan" ,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002208 __func__);
Jeff Johnsone7245742012-09-05 17:12:55 -07002209 VOS_ASSERT(pScanInfo->mScanPending);
2210 return 0;
2211 }
2212 }
2213
Jeff Johnson295189b2012-06-20 16:38:30 -07002214 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07002215 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07002216 )
2217 {
2218 beacon_data_t *old;
2219
2220 old = pAdapter->sessionCtx.ap.beacon;
2221
2222 if (!old)
2223 return -ENOENT;
2224
Jeff Johnson295189b2012-06-20 16:38:30 -07002225 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07002226
2227 mutex_lock(&pHddCtx->sap_lock);
2228 if(test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
2229 {
Jeff Johnson4416a782013-03-25 14:17:50 -07002230 if ( VOS_STATUS_SUCCESS == (status = WLANSAP_StopBss(pHddCtx->pvosContext) ) )
Jeff Johnson295189b2012-06-20 16:38:30 -07002231 {
2232 hdd_hostapd_state_t *pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
2233
2234 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
2235
2236 if (!VOS_IS_STATUS_SUCCESS(status))
2237 {
2238 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2239 ("ERROR: HDD vos wait for single_event failed!!\n"));
2240 VOS_ASSERT(0);
2241 }
2242 }
2243 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
2244 }
2245 mutex_unlock(&pHddCtx->sap_lock);
2246
2247 if(status != VOS_STATUS_SUCCESS)
2248 {
2249 hddLog(VOS_TRACE_LEVEL_FATAL,
2250 "%s:Error!!! Stopping the BSS\n",__func__);
2251 return -EINVAL;
2252 }
2253
Jeff Johnson4416a782013-03-25 14:17:50 -07002254 if (ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -07002255 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 0,NULL, eANI_BOOLEAN_FALSE)
2256 ==eHAL_STATUS_FAILURE)
2257 {
2258 hddLog(LOGE,
2259 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM\n");
2260 }
2261
Jeff Johnson4416a782013-03-25 14:17:50 -07002262 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -07002263 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
2264 eANI_BOOLEAN_FALSE) )
2265 {
2266 hddLog(LOGE,
2267 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM\n");
2268 }
2269
2270 // Reset WNI_CFG_PROBE_RSP Flags
2271 wlan_hdd_reset_prob_rspies(pAdapter);
2272
2273 pAdapter->sessionCtx.ap.beacon = NULL;
2274 kfree(old);
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07002275#ifdef WLAN_FEATURE_P2P_DEBUG
2276 if((pAdapter->device_mode == WLAN_HDD_P2P_GO) &&
2277 (globalP2PConnectionStatus == P2P_GO_COMPLETED_STATE))
2278 {
2279 hddLog(LOGE,"[P2P State] From GO completed to Inactive state "
2280 "GO got removed");
2281 globalP2PConnectionStatus = P2P_NOT_ACTIVE;
2282 }
2283#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07002284 }
2285 EXIT();
2286 return status;
2287}
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002288
2289#if (LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
2290
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302291static int wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
2292 struct net_device *dev,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002293 struct cfg80211_ap_settings *params)
2294{
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302295 hdd_adapter_t *pAdapter;
2296 hdd_context_t *pHddCtx;
2297 int status = 0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002298
2299 ENTER();
2300
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302301 if (NULL == dev)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07002302 {
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302303 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
2304 "%s: Device is Null", __func__);
2305 return -ENODEV;
2306 }
2307
2308 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2309 if (NULL == pAdapter)
2310 {
2311 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
2312 "%s: HDD adapter is Null", __func__);
2313 return -ENODEV;
2314 }
2315
2316 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
2317 {
2318 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
2319 "%s: HDD adapter magic is invalid", __func__);
2320 return -ENODEV;
2321 }
2322
2323 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2324 if (NULL == pHddCtx)
2325 {
2326 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
2327 "%s: HDD context is Null", __func__);
2328 return -ENODEV;
2329 }
2330
2331 if (pHddCtx->isLogpInProgress)
2332 {
2333 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
2334 "%s: LOGP in Progress. Ignore!!!", __func__);
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07002335 return -EAGAIN;
2336 }
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302337
2338 if (pHddCtx->isLoadUnloadInProgress)
2339 {
2340 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
2341 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
2342 return -EAGAIN;
2343 }
2344
2345 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device mode = %d",
2346 __func__, pAdapter->device_mode);
2347
2348 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002349 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002350 )
2351 {
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302352 beacon_data_t *old, *new;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002353
2354 old = pAdapter->sessionCtx.ap.beacon;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302355
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002356 if (old)
2357 return -EALREADY;
2358
2359 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter, &new, &params->beacon, params->dtim_period);
2360
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302361 if (status != 0)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002362 {
2363 hddLog(VOS_TRACE_LEVEL_FATAL,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302364 "%s:Error!!! Allocating the new beacon", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002365 return -EINVAL;
2366 }
2367 pAdapter->sessionCtx.ap.beacon = new;
Viral Modi3a32cc52013-02-08 11:14:52 -08002368#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
2369 wlan_hdd_cfg80211_set_channel(wiphy, dev, params->channel, params->channel_type);
2370#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002371 status = wlan_hdd_cfg80211_start_bss(pAdapter, &params->beacon, params->ssid,
2372 params->ssid_len, params->hidden_ssid);
2373 }
2374
2375 EXIT();
2376 return status;
2377}
2378
2379
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302380static int wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002381 struct net_device *dev,
2382 struct cfg80211_beacon_data *params)
2383{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302384 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002385 int status=VOS_STATUS_SUCCESS;
2386
2387 ENTER();
2388
2389 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",
2390 __func__, pAdapter->device_mode);
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07002391 if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress)
2392 {
2393 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:LOGP in Progress. Ignore!!!",__func__);
2394 return -EAGAIN;
2395 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002396
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302397 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002398 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302399 )
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002400 {
2401 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302402
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002403 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302404
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002405 if (!old)
2406 return -ENOENT;
2407
2408 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter, &new, params, 0);
2409
2410 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302411 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002412 "%s: Error!!! Allocating the new beacon\n",__func__);
2413 return -EINVAL;
2414 }
2415
2416 pAdapter->sessionCtx.ap.beacon = new;
2417
2418 status = wlan_hdd_cfg80211_start_bss(pAdapter, params, NULL, 0, 0);
2419 }
2420
2421 EXIT();
2422 return status;
2423}
2424
2425#endif //(LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
2426
Jeff Johnson295189b2012-06-20 16:38:30 -07002427
2428static int wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
2429 struct net_device *dev,
2430 struct bss_parameters *params)
2431{
2432 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2433
2434 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302435
Jeff Johnson295189b2012-06-20 16:38:30 -07002436 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",
2437 __func__,pAdapter->device_mode);
2438
2439 if((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07002440 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302441 )
Jeff Johnson295189b2012-06-20 16:38:30 -07002442 {
2443 /* ap_isolate == -1 means that in change bss, upper layer doesn't
2444 * want to update this parameter */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302445 if (-1 != params->ap_isolate)
Jeff Johnson295189b2012-06-20 16:38:30 -07002446 {
2447 pAdapter->sessionCtx.ap.apDisableIntraBssFwd = !!params->ap_isolate;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302448 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002449 }
2450
2451 EXIT();
2452 return 0;
2453}
2454
2455/*
2456 * FUNCTION: wlan_hdd_cfg80211_change_iface
2457 * This function is used to set the interface type (INFRASTRUCTURE/ADHOC)
2458 */
2459int wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
2460 struct net_device *ndev,
2461 enum nl80211_iftype type,
2462 u32 *flags,
2463 struct vif_params *params
2464 )
2465{
2466 struct wireless_dev *wdev;
2467 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
2468 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
Mohit Khanna0f232092012-09-11 14:46:08 -07002469 hdd_adapter_t *pP2pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07002470 tCsrRoamProfile *pRoamProfile = NULL;
2471 eCsrRoamBssType LastBSSType;
2472 hdd_config_t *pConfig = pHddCtx->cfg_ini;
2473 eMib_dot11DesiredBssType connectedBssType;
2474 VOS_STATUS status;
2475
2476 ENTER();
2477
2478 if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress)
2479 {
2480 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:LOGP in Progress. Ignore!!!",__func__);
2481 return -EAGAIN;
2482 }
2483
2484 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
2485 __func__, pAdapter->device_mode);
2486
2487 wdev = ndev->ieee80211_ptr;
2488
2489#ifdef WLAN_BTAMP_FEATURE
2490 if((NL80211_IFTYPE_P2P_CLIENT == type)||
2491 (NL80211_IFTYPE_ADHOC == type)||
2492 (NL80211_IFTYPE_AP == type)||
2493 (NL80211_IFTYPE_P2P_GO == type))
2494 {
2495 pHddCtx->isAmpAllowed = VOS_FALSE;
2496 // stop AMP traffic
2497 status = WLANBAP_StopAmp();
2498 if(VOS_STATUS_SUCCESS != status )
2499 {
2500 pHddCtx->isAmpAllowed = VOS_TRUE;
2501 hddLog(VOS_TRACE_LEVEL_FATAL,
2502 "%s: Failed to stop AMP", __func__);
2503 return -EINVAL;
2504 }
2505 }
2506#endif //WLAN_BTAMP_FEATURE
2507 /* Reset the current device mode bit mask*/
2508 wlan_hdd_clear_concurrency_mode(pHddCtx, pAdapter->device_mode);
2509
2510 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -07002511 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnsone7245742012-09-05 17:12:55 -07002512 || (pAdapter->device_mode == WLAN_HDD_P2P_DEVICE)
Jeff Johnson295189b2012-06-20 16:38:30 -07002513 )
2514 {
2515 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
2516 pRoamProfile = &pWextState->roamProfile;
2517 LastBSSType = pRoamProfile->BSSType;
2518
2519 switch (type)
2520 {
2521 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -07002522 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -07002523 hddLog(VOS_TRACE_LEVEL_INFO,
2524 "%s: setting interface Type to INFRASTRUCTURE", __func__);
2525 pRoamProfile->BSSType = eCSR_BSS_TYPE_INFRASTRUCTURE;
Jeff Johnsone7245742012-09-05 17:12:55 -07002526#ifdef WLAN_FEATURE_11AC
2527 if(pConfig->dot11Mode == eHDD_DOT11_MODE_AUTO)
2528 {
2529 pConfig->dot11Mode = eHDD_DOT11_MODE_11ac;
2530 }
2531#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302532 pRoamProfile->phyMode =
Jeff Johnsone7245742012-09-05 17:12:55 -07002533 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07002534 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08002535 //Check for sub-string p2p to confirm its a p2p interface
2536 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302537 {
Gopichand Nakkala864d3552012-12-31 16:08:51 -08002538 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
2539 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
2540 }
2541 else
2542 {
2543 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -07002544 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -08002545 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002546 break;
2547 case NL80211_IFTYPE_ADHOC:
2548 hddLog(VOS_TRACE_LEVEL_INFO,
2549 "%s: setting interface Type to ADHOC", __func__);
2550 pRoamProfile->BSSType = eCSR_BSS_TYPE_START_IBSS;
2551 pRoamProfile->phyMode =
2552 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Shailender Karmuchia734f332013-04-19 14:02:48 -07002553 pAdapter->device_mode = WLAN_HDD_IBSS;
Jeff Johnson295189b2012-06-20 16:38:30 -07002554 wdev->iftype = type;
2555 break;
2556
2557 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -07002558 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07002559 {
2560 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
2561 "%s: setting interface Type to %s", __func__,
2562 (type == NL80211_IFTYPE_AP) ? "SoftAP" : "P2pGo");
2563
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08002564 //Cancel any remain on channel for GO mode
2565 if (NL80211_IFTYPE_P2P_GO == type)
2566 {
2567 wlan_hdd_cancel_existing_remain_on_channel(pAdapter);
2568 }
Mohit Khanna0f232092012-09-11 14:46:08 -07002569 if (NL80211_IFTYPE_AP == type)
2570 {
2571 /* As Loading WLAN Driver one interface being created for p2p device
2572 * address. This will take one HW STA and the max number of clients
2573 * that can connect to softAP will be reduced by one. so while changing
2574 * the interface type to NL80211_IFTYPE_AP (SoftAP) remove p2p0
2575 * interface as it is not required in SoftAP mode.
2576 */
2577
2578 // Get P2P Adapter
2579 pP2pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_DEVICE);
2580
2581 if (pP2pAdapter)
2582 {
2583 hdd_stop_adapter(pHddCtx, pP2pAdapter);
2584 hdd_deinit_adapter(pHddCtx, pP2pAdapter);
2585 hdd_close_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
2586 }
2587 }
2588
Jeff Johnson295189b2012-06-20 16:38:30 -07002589 //De-init the adapter.
2590 hdd_stop_adapter( pHddCtx, pAdapter );
2591 hdd_deinit_adapter( pHddCtx, pAdapter );
2592 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
Jeff Johnson295189b2012-06-20 16:38:30 -07002593 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
2594 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Jeff Johnson32d95a32012-09-10 13:15:23 -07002595
2596 //Disable BMPS and IMPS if enabled
2597 //before starting Go
2598 if(WLAN_HDD_P2P_GO == pAdapter->device_mode)
2599 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302600 if(VOS_STATUS_E_FAILURE ==
Jeff Johnson32d95a32012-09-10 13:15:23 -07002601 hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_P2P_GO))
2602 {
2603 //Fail to Exit BMPS
2604 VOS_ASSERT(0);
2605 }
2606 }
2607
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -07002608 if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) &&
2609 (pConfig->apRandomBssidEnabled))
2610 {
2611 /* To meet Android requirements create a randomized
2612 MAC address of the form 02:1A:11:Fx:xx:xx */
2613 get_random_bytes(&ndev->dev_addr[3], 3);
2614 ndev->dev_addr[0] = 0x02;
2615 ndev->dev_addr[1] = 0x1A;
2616 ndev->dev_addr[2] = 0x11;
2617 ndev->dev_addr[3] |= 0xF0;
2618 memcpy(pAdapter->macAddressCurrent.bytes, ndev->dev_addr,
2619 VOS_MAC_ADDR_SIZE);
2620 pr_info("wlan: Generated HotSpot BSSID "
2621 "%02x:%02x:%02x:%02x:%02x:%02x\n",
2622 ndev->dev_addr[0],
2623 ndev->dev_addr[1],
2624 ndev->dev_addr[2],
2625 ndev->dev_addr[3],
2626 ndev->dev_addr[4],
2627 ndev->dev_addr[5]);
2628 }
2629
Jeff Johnson295189b2012-06-20 16:38:30 -07002630 hdd_set_ap_ops( pAdapter->dev );
2631
2632 status = hdd_init_ap_mode(pAdapter);
2633 if(status != VOS_STATUS_SUCCESS)
2634 {
2635 hddLog(VOS_TRACE_LEVEL_FATAL,
2636 "%s: Error initializing the ap mode", __func__);
2637 return -EINVAL;
2638 }
2639 hdd_set_conparam(1);
2640
Jeff Johnson295189b2012-06-20 16:38:30 -07002641 /*interface type changed update in wiphy structure*/
2642 if(wdev)
2643 {
2644 wdev->iftype = type;
2645 pHddCtx->change_iface = type;
2646 }
2647 else
2648 {
2649 hddLog(VOS_TRACE_LEVEL_ERROR,
2650 "%s: ERROR !!!! Wireless dev is NULL", __func__);
2651 return -EINVAL;
2652 }
2653 goto done;
2654 }
2655
2656 default:
2657 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
2658 __func__);
2659 return -EOPNOTSUPP;
2660 }
2661 }
2662 else if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07002663 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07002664 )
2665 {
2666 switch(type)
2667 {
2668 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -07002669 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -07002670 case NL80211_IFTYPE_ADHOC:
Jeff Johnson32d95a32012-09-10 13:15:23 -07002671 hdd_stop_adapter( pHddCtx, pAdapter );
2672 hdd_deinit_adapter( pHddCtx, pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07002673 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08002674 //Check for sub-string p2p to confirm its a p2p interface
2675 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala864d3552012-12-31 16:08:51 -08002676 {
2677 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
2678 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
2679 }
2680 else
2681 {
2682 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -07002683 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -08002684 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002685 hdd_set_conparam(0);
2686 pHddCtx->change_iface = type;
Jeff Johnson295189b2012-06-20 16:38:30 -07002687 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
2688 hdd_set_station_ops( pAdapter->dev );
2689 status = hdd_init_station_mode( pAdapter );
2690 if( VOS_STATUS_SUCCESS != status )
2691 return -EOPNOTSUPP;
Jeff Johnsone7245742012-09-05 17:12:55 -07002692 /* In case of JB, for P2P-GO, only change interface will be called,
2693 * This is the right place to enable back bmps_imps()
2694 */
2695 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07002696 goto done;
2697 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -07002698 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07002699 wdev->iftype = type;
Jeff Johnson295189b2012-06-20 16:38:30 -07002700 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
2701 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Jeff Johnson295189b2012-06-20 16:38:30 -07002702 goto done;
2703 default:
2704 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
2705 __func__);
2706 return -EOPNOTSUPP;
2707
2708 }
2709
2710 }
2711 else
2712 {
2713 return -EOPNOTSUPP;
2714 }
2715
2716
2717 if(pRoamProfile)
2718 {
2719 if ( LastBSSType != pRoamProfile->BSSType )
2720 {
2721 /*interface type changed update in wiphy structure*/
2722 wdev->iftype = type;
2723
2724 /*the BSS mode changed, We need to issue disconnect
2725 if connected or in IBSS disconnect state*/
2726 if ( hdd_connGetConnectedBssType(
2727 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), &connectedBssType ) ||
2728 ( eCSR_BSS_TYPE_START_IBSS == LastBSSType ) )
2729 {
2730 /*need to issue a disconnect to CSR.*/
2731 INIT_COMPLETION(pAdapter->disconnect_comp_var);
2732 if( eHAL_STATUS_SUCCESS ==
2733 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
2734 pAdapter->sessionId,
2735 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
2736 {
2737 wait_for_completion_interruptible_timeout(
2738 &pAdapter->disconnect_comp_var,
2739 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
2740 }
2741 }
2742 }
2743 }
2744
2745done:
2746 /*set bitmask based on updated value*/
2747 wlan_hdd_set_concurrency_mode(pHddCtx, pAdapter->device_mode);
2748#ifdef WLAN_BTAMP_FEATURE
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302749 if((NL80211_IFTYPE_STATION == type) && (pHddCtx->concurrency_mode <= 1) &&
Jeff Johnson295189b2012-06-20 16:38:30 -07002750 (pHddCtx->no_of_sessions[WLAN_HDD_INFRA_STATION] <=1))
2751 {
2752 //we are ok to do AMP
2753 pHddCtx->isAmpAllowed = VOS_TRUE;
2754 }
2755#endif //WLAN_BTAMP_FEATURE
2756 EXIT();
2757 return 0;
2758}
2759
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002760#ifdef FEATURE_WLAN_TDLS
2761static int wlan_hdd_tdls_add_station(struct wiphy *wiphy,
2762 struct net_device *dev, u8 *mac, bool update, tCsrStaParams *StaParams)
2763{
2764 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2765 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
2766 VOS_STATUS status;
Hoonki Lee5305c3a2013-04-29 23:28:59 -07002767 hddTdlsPeer_t *pTdlsPeer;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002768
2769 ENTER();
2770
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05302771 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002772 {
2773 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2774 "Invalid arguments");
2775 return -EINVAL;
2776 }
Hoonki Lee27511902013-03-14 18:19:06 -07002777
2778 if ((eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode) ||
2779 (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode))
2780 {
2781 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2782 "%s: TDLS mode is disabled OR not enabled in FW."
2783 MAC_ADDRESS_STR " Request declined.",
2784 __func__, MAC_ADDR_ARRAY(mac));
2785 return -ENOTSUPP;
2786 }
2787
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002788 if (pHddCtx->isLogpInProgress)
2789 {
2790 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2791 "%s:LOGP in Progress. Ignore!!!", __func__);
Gopichand Nakkala05922802013-03-14 12:23:19 -07002792 wlan_hdd_tdls_set_link_status(pAdapter, mac, eTDLS_LINK_IDLE);
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002793 return -EBUSY;
2794 }
2795
Hoonki Lee5305c3a2013-04-29 23:28:59 -07002796 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, mac);
2797
2798 if ( NULL == pTdlsPeer ) {
2799 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2800 "%s: " MAC_ADDRESS_STR " (update %d) not exist. return invalid",
2801 __func__, MAC_ADDR_ARRAY(mac), update);
2802 return -EINVAL;
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07002803 }
Hoonki Lee5305c3a2013-04-29 23:28:59 -07002804
2805 /* in add station, we accept existing valid staId if there is */
2806 if ((0 == update) &&
2807 ((pTdlsPeer->link_status >= eTDLS_LINK_CONNECTING) ||
2808 (TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07002809 {
Hoonki Lee5305c3a2013-04-29 23:28:59 -07002810 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07002811 "%s: " MAC_ADDRESS_STR
Hoonki Lee5305c3a2013-04-29 23:28:59 -07002812 " link_status %d. staId %d. add station ignored.",
2813 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, pTdlsPeer->staId);
2814 return 0;
2815 }
2816 /* in change station, we accept only when staId is valid */
2817 if ((1 == update) &&
2818 ((pTdlsPeer->link_status > eTDLS_LINK_CONNECTING) ||
2819 (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
2820 {
2821 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2822 "%s: " MAC_ADDRESS_STR
2823 " link status %d. staId %d. change station %s.",
2824 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, pTdlsPeer->staId,
2825 (TDLS_STA_INDEX_VALID(pTdlsPeer->staId)) ? "ignored" : "declined");
2826 return (TDLS_STA_INDEX_VALID(pTdlsPeer->staId)) ? 0 : -EPERM;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07002827 }
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07002828
2829 /* when others are on-going, we want to change link_status to idle */
Hoonki Leefb8df672013-04-10 18:20:34 -07002830 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, mac, TRUE, TRUE))
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002831 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07002832 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2833 "%s: " MAC_ADDRESS_STR
2834 " TDLS setup is ongoing. Request declined.",
2835 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala05922802013-03-14 12:23:19 -07002836 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002837 }
2838
2839 /* first to check if we reached to maximum supported TDLS peer.
2840 TODO: for now, return -EPERM looks working fine,
2841 but need to check if any other errno fit into this category.*/
2842 if (HDD_MAX_NUM_TDLS_STA <= wlan_hdd_tdlsConnectedPeers(pAdapter))
2843 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07002844 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2845 "%s: " MAC_ADDRESS_STR
2846 " TDLS Max peer already connected. Request declined.",
2847 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala05922802013-03-14 12:23:19 -07002848 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002849 }
2850 else
2851 {
2852 hddTdlsPeer_t *pTdlsPeer;
2853 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, mac);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07002854 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002855 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07002856 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2857 "%s: " MAC_ADDRESS_STR " already connected. Request declined.",
2858 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002859 return -EPERM;
2860 }
2861 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07002862 if (0 == update)
2863 wlan_hdd_tdls_set_link_status(pAdapter, mac, eTDLS_LINK_CONNECTING);
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002864
Jeff Johnsond75fe012013-04-06 10:53:06 -07002865 /* debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05302866 if (NULL != StaParams)
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07002867 {
2868 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2869 "%s: TDLS Peer Parameters.", __func__);
Hoonki Lee66b75f32013-04-16 18:30:07 -07002870 if(StaParams->htcap_present)
2871 {
2872 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2873 "ht_capa->cap_info: %0x", StaParams->HTCap.capInfo);
2874 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2875 "ht_capa->extended_capabilities: %0x",
2876 StaParams->HTCap.extendedHtCapInfo);
2877 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07002878 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2879 "params->capability: %0x",StaParams->capability);
2880 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2881 "params->ext_capab_len: %0x",StaParams->extn_capability);
Hoonki Lee66b75f32013-04-16 18:30:07 -07002882 if(StaParams->vhtcap_present)
2883 {
2884 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2885 "rxMcsMap %x rxHighest %x txMcsMap %x txHighest %x",
2886 StaParams->VHTCap.suppMcs.rxMcsMap, StaParams->VHTCap.suppMcs.rxHighest,
2887 StaParams->VHTCap.suppMcs.txMcsMap, StaParams->VHTCap.suppMcs.txHighest);
2888 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07002889 {
2890 int i = 0;
Hoonki Lee5305c3a2013-04-29 23:28:59 -07002891 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "Supported rates:");
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07002892 for (i = 0; i < sizeof(StaParams->supported_rates); i++)
2893 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2894 "[%d]: %x ", i, StaParams->supported_rates[i]);
2895 }
Jeff Johnsond75fe012013-04-06 10:53:06 -07002896 } /* end debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05302897 else if ((1 == update) && (NULL == StaParams))
2898 {
2899 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2900 "%s : update is true, but staParams is NULL. Error!", __func__);
2901 return -EPERM;
2902 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002903
2904 INIT_COMPLETION(pAdapter->tdls_add_station_comp);
2905
2906 if (!update)
2907 {
2908 status = sme_AddTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
2909 pAdapter->sessionId, mac);
2910 }
2911 else
2912 {
2913 status = sme_ChangeTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
2914 pAdapter->sessionId, mac, StaParams);
2915 }
2916
2917 status = wait_for_completion_interruptible_timeout(&pAdapter->tdls_add_station_comp,
2918 msecs_to_jiffies(WAIT_TIME_TDLS_ADD_STA));
2919
2920 if (!status)
2921 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07002922 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002923 "%s: timeout waiting for tdls add station indication",
2924 __func__);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07002925 return -EPERM;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002926 }
2927 if ( eHAL_STATUS_SUCCESS != pAdapter->tdlsAddStaStatus)
2928 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07002929 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002930 "%s: Add Station is unsucessful", __func__);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07002931 return -EPERM;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002932 }
2933
2934 return 0;
Gopichand Nakkala05922802013-03-14 12:23:19 -07002935
2936error:
2937 wlan_hdd_tdls_set_link_status(pAdapter, mac, eTDLS_LINK_IDLE);
2938 return -EPERM;
2939
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002940}
2941#endif
2942
Jeff Johnson295189b2012-06-20 16:38:30 -07002943static int wlan_hdd_change_station(struct wiphy *wiphy,
2944 struct net_device *dev,
2945 u8 *mac,
2946 struct station_parameters *params)
2947{
2948 VOS_STATUS status = VOS_STATUS_SUCCESS;
2949 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
2950 v_MACADDR_t STAMacAddress;
Gopichand Nakkalab0856222013-03-12 22:39:05 -07002951#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002952 tCsrStaParams StaParams = {0};
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002953 tANI_U8 isBufSta = 0;
Gopichand Nakkalab0856222013-03-12 22:39:05 -07002954#endif
Jeff Johnsone7245742012-09-05 17:12:55 -07002955 ENTER();
2956
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002957 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
2958 {
2959 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2960 "%s:LOGP in Progress. Ignore!!!", __func__);
2961 return -EAGAIN;
2962 }
2963
Jeff Johnson295189b2012-06-20 16:38:30 -07002964 vos_mem_copy(STAMacAddress.bytes, mac, sizeof(v_MACADDR_t));
2965
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002966 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
2967 || (pAdapter->device_mode == WLAN_HDD_P2P_GO))
Jeff Johnson295189b2012-06-20 16:38:30 -07002968 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002969 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED))
Jeff Johnson295189b2012-06-20 16:38:30 -07002970 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302971 status = hdd_softap_change_STA_state( pAdapter, &STAMacAddress,
Jeff Johnson295189b2012-06-20 16:38:30 -07002972 WLANTL_STA_AUTHENTICATED);
2973
2974 VOS_TRACE( VOS_MODULE_ID_HDD_SOFTAP, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002975 "%s: Station MAC address does not matching", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002976 return -EINVAL;
2977 }
2978 }
Gopichand Nakkalab0856222013-03-12 22:39:05 -07002979#ifdef FEATURE_WLAN_TDLS
Hoonki Leea6d49be2013-04-05 09:43:25 -07002980 else if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
2981 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)) {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07002982 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
2983 StaParams.capability = params->capability;
2984 StaParams.uapsd_queues = params->uapsd_queues;
2985 StaParams.max_sp = params->max_sp;
2986
2987 if (0 != params->ext_capab_len)
2988 vos_mem_copy(StaParams.extn_capability, params->ext_capab,
2989 sizeof(StaParams.extn_capability));
2990
2991 if (NULL != params->ht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -07002992 {
2993 StaParams.htcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07002994 vos_mem_copy(&StaParams.HTCap, params->ht_capa, sizeof(tSirHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -07002995 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07002996
2997 StaParams.supported_rates_len = params->supported_rates_len;
2998
2999 /* Note : The Maximum sizeof supported_rates sent by the Supplicant is 32.
3000 * The supported_rates array , for all the structures propogating till Add Sta
3001 * to the firmware has to be modified , if the supplicant (ieee80211) is
3002 * modified to send more rates.
3003 */
3004
3005 /* To avoid Data Currption , set to max length to SIR_MAC_MAX_SUPP_RATES
3006 */
3007 if (StaParams.supported_rates_len > SIR_MAC_MAX_SUPP_RATES)
3008 StaParams.supported_rates_len = SIR_MAC_MAX_SUPP_RATES;
3009
3010 if (0 != StaParams.supported_rates_len) {
3011 int i = 0;
3012 vos_mem_copy(StaParams.supported_rates, params->supported_rates,
3013 StaParams.supported_rates_len);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07003014 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003015 "Supported Rates with Length %d", StaParams.supported_rates_len);
3016 for (i=0; i < StaParams.supported_rates_len; i++)
Hoonki Lee5305c3a2013-04-29 23:28:59 -07003017 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003018 "[%d]: %0x", i, StaParams.supported_rates[i]);
3019 }
3020
3021 if (NULL != params->vht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -07003022 {
3023 StaParams.vhtcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003024 vos_mem_copy(&StaParams.VHTCap, params->vht_capa, sizeof(tSirVHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -07003025 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003026
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003027 if (0 != params->ext_capab_len ) {
3028 /*Define A Macro : TODO Sunil*/
3029 if ((1<<4) & StaParams.extn_capability[3]) {
3030 isBufSta = 1;
3031 }
3032 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003033 //status = wlan_hdd_tdls_set_peer_caps( mac, params->uapsd_queues,
3034 // params->max_sp, isBufSta);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003035 //if (VOS_STATUS_SUCCESS != status) {
3036 // VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3037 // "%s: wlan_hdd_tdls_set_peer_caps failed!", __func__);
3038 // return -EINVAL;
3039 //}
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003040 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 1, &StaParams);
3041
3042 if (VOS_STATUS_SUCCESS != status) {
3043 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3044 "%s: sme_ChangeTdlsPeerSta failed!", __func__);
3045 return -EINVAL;
3046 }
3047 }
3048 }
Gopichand Nakkalab0856222013-03-12 22:39:05 -07003049#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303050
Jeff Johnsone7245742012-09-05 17:12:55 -07003051 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07003052 return status;
3053}
3054
3055/*
3056 * FUNCTION: wlan_hdd_cfg80211_get_ibss_peer_staidx
3057 * This function is used to get peer station index in IBSS mode
3058 */
3059static u8 wlan_hdd_cfg80211_get_ibss_peer_staidx(hdd_adapter_t* pAdapter)
3060{
3061 u8 idx = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303062 u8 temp[VOS_MAC_ADDR_SIZE] = {0};
Jeff Johnson295189b2012-06-20 16:38:30 -07003063 ENTER();
3064 memset(temp, 0, VOS_MAC_ADDR_SIZE);
3065 for ( idx = 0; idx < HDD_MAX_NUM_IBSS_STA; idx++ )
3066 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303067 if ( (0 !=
3068 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.staId[idx])
Jeff Johnson295189b2012-06-20 16:38:30 -07003069 && memcmp((u8*)&(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.peerMacAddress[idx],
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303070 temp, VOS_MAC_ADDR_SIZE)
Jeff Johnson295189b2012-06-20 16:38:30 -07003071 )
3072 {
3073 return idx;
3074 }
3075 }
3076 return idx;
3077}
3078
3079
3080/*
3081 * FUNCTION: wlan_hdd_cfg80211_add_key
3082 * This function is used to initialize the key information
3083 */
3084#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003085static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07003086 struct net_device *ndev,
3087 u8 key_index, bool pairwise,
3088 const u8 *mac_addr,
3089 struct key_params *params
3090 )
3091#else
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003092static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07003093 struct net_device *ndev,
3094 u8 key_index, const u8 *mac_addr,
3095 struct key_params *params
3096 )
3097#endif
3098{
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003099 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -07003100 tCsrRoamSetKey setKey;
3101 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
3102 int status = 0;
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003103 v_U32_t roamId= 0xFF;
3104 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07003105 hdd_hostapd_state_t *pHostapdState;
3106 VOS_STATUS vos_status;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07003107 eHalStatus halStatus;
Jeff Johnson295189b2012-06-20 16:38:30 -07003108
3109 ENTER();
3110
Jeff Johnson04dd8a82012-06-29 20:41:40 -07003111 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
3112 {
3113 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3114 "%s:LOGP in Progress. Ignore!!!", __func__);
3115 return -EAGAIN;
3116 }
3117
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003118 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
3119 __func__, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07003120
3121 if (CSR_MAX_NUM_KEY <= key_index)
3122 {
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003123 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07003124 key_index);
3125
3126 return -EINVAL;
3127 }
3128
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003129 if (CSR_MAX_KEY_LEN < params->key_len)
3130 {
3131 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key length %d", __func__,
3132 params->key_len);
3133
3134 return -EINVAL;
3135 }
3136
3137 hddLog(VOS_TRACE_LEVEL_INFO,
3138 "%s: called with key index = %d & key length %d",
3139 __func__, key_index, params->key_len);
Jeff Johnson295189b2012-06-20 16:38:30 -07003140
3141 /*extract key idx, key len and key*/
3142 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
3143 setKey.keyId = key_index;
3144 setKey.keyLength = params->key_len;
3145 vos_mem_copy(&setKey.Key[0],params->key, params->key_len);
3146
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003147 switch (params->cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -07003148 {
3149 case WLAN_CIPHER_SUITE_WEP40:
3150 setKey.encType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
3151 break;
3152
3153 case WLAN_CIPHER_SUITE_WEP104:
3154 setKey.encType = eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
3155 break;
3156
3157 case WLAN_CIPHER_SUITE_TKIP:
3158 {
3159 u8 *pKey = &setKey.Key[0];
3160 setKey.encType = eCSR_ENCRYPT_TYPE_TKIP;
3161
3162 vos_mem_zero(pKey, CSR_MAX_KEY_LEN);
3163
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003164 /*Supplicant sends the 32bytes key in this order
Jeff Johnson295189b2012-06-20 16:38:30 -07003165
3166 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003167 | Tk1 |TX-MIC | RX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -07003168 |--------------|----------|----------|
3169 <---16bytes---><--8bytes--><--8bytes-->
3170
3171 */
3172 /*Sme expects the 32 bytes key to be in the below order
3173
3174 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003175 | Tk1 |RX-MIC | TX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -07003176 |--------------|----------|----------|
3177 <---16bytes---><--8bytes--><--8bytes-->
3178 */
3179 /* Copy the Temporal Key 1 (TK1) */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003180 vos_mem_copy(pKey, params->key, 16);
Jeff Johnson295189b2012-06-20 16:38:30 -07003181
3182 /*Copy the rx mic first*/
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003183 vos_mem_copy(&pKey[16], &params->key[24], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -07003184
3185 /*Copy the tx mic */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003186 vos_mem_copy(&pKey[24], &params->key[16], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -07003187
3188
3189 break;
3190 }
3191
3192 case WLAN_CIPHER_SUITE_CCMP:
3193 setKey.encType = eCSR_ENCRYPT_TYPE_AES;
3194 break;
3195
3196#ifdef FEATURE_WLAN_WAPI
3197 case WLAN_CIPHER_SUITE_SMS4:
3198 {
3199 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
3200 wlan_hdd_cfg80211_set_key_wapi(pAdapter, key_index, mac_addr,
3201 params->key, params->key_len);
3202 return 0;
3203 }
3204#endif
Chet Lanctot186b5732013-03-18 10:26:30 -07003205
Jeff Johnson295189b2012-06-20 16:38:30 -07003206#ifdef FEATURE_WLAN_CCX
3207 case WLAN_CIPHER_SUITE_KRK:
3208 setKey.encType = eCSR_ENCRYPT_TYPE_KRK;
3209 break;
3210#endif
Chet Lanctot186b5732013-03-18 10:26:30 -07003211
3212#ifdef WLAN_FEATURE_11W
3213 case WLAN_CIPHER_SUITE_AES_CMAC:
3214 setKey.encType = eCSR_ENCRYPT_TYPE_AES_CMAC;
Chet Lanctot3b5158a2013-03-31 16:45:21 -07003215 break;
Chet Lanctot186b5732013-03-18 10:26:30 -07003216#endif
3217
Jeff Johnson295189b2012-06-20 16:38:30 -07003218 default:
3219 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unsupported cipher type %lu",
3220 __func__, params->cipher);
3221 return -EOPNOTSUPP;
3222 }
3223
3224 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: encryption type %d",
3225 __func__, setKey.encType);
3226
3227
3228
3229 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07003230 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07003231 )
3232 {
3233
3234
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003235 if (
Jeff Johnson295189b2012-06-20 16:38:30 -07003236#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
3237 (!pairwise)
3238#else
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003239 (!mac_addr || is_broadcast_ether_addr(mac_addr))
Jeff Johnson295189b2012-06-20 16:38:30 -07003240#endif
3241 )
3242 {
3243 /* set group key*/
3244 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnson1250df42012-12-10 14:31:52 -08003245 "%s- %d: setting Broadcast key",
Jeff Johnson295189b2012-06-20 16:38:30 -07003246 __func__, __LINE__);
3247 setKey.keyDirection = eSIR_RX_ONLY;
3248 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
3249 }
3250 else
3251 {
3252 /* set pairwise key*/
3253 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3254 "%s- %d: setting pairwise key",
3255 __func__, __LINE__);
3256 setKey.keyDirection = eSIR_TX_RX;
3257 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
3258 }
3259
3260 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003261 if( pHostapdState->bssState == BSS_START )
3262 {
Jeff Johnson295189b2012-06-20 16:38:30 -07003263 status = WLANSAP_SetKeySta( pVosContext, &setKey);
3264
3265 if ( status != eHAL_STATUS_SUCCESS )
3266 {
3267 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3268 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
3269 __LINE__, status );
3270 }
3271 }
3272
3273 /* Saving WEP keys */
3274 else if( eCSR_ENCRYPT_TYPE_WEP40_STATICKEY == setKey.encType ||
3275 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY == setKey.encType )
3276 {
3277 //Save the wep key in ap context. Issue setkey after the BSS is started.
3278 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
3279 vos_mem_copy(&pAPCtx->wepKey[key_index], &setKey, sizeof(tCsrRoamSetKey));
3280 }
3281 else
3282 {
3283 //Save the key in ap context. Issue setkey after the BSS is started.
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003284 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07003285 vos_mem_copy(&pAPCtx->groupKey, &setKey, sizeof(tCsrRoamSetKey));
3286 }
3287 }
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003288 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION) ||
3289 (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT) )
Jeff Johnson295189b2012-06-20 16:38:30 -07003290 {
3291 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
3292 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3293
3294 pWextState->roamProfile.Keys.KeyLength[key_index] = (u8)params->key_len;
3295
Venkata Prathyusha Kuntupalliee2ce712013-01-17 14:09:24 -08003296 pWextState->roamProfile.Keys.defaultIndex = key_index;
3297
3298
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003299 vos_mem_copy(&pWextState->roamProfile.Keys.KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -07003300 params->key, params->key_len);
3301
3302 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
3303
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303304 if (!( ( IW_AUTH_KEY_MGMT_802_1X
3305 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X))
Jeff Johnson295189b2012-06-20 16:38:30 -07003306 && (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType)
3307 )
3308 &&
3309 ( (WLAN_CIPHER_SUITE_WEP40 == params->cipher)
3310 || (WLAN_CIPHER_SUITE_WEP104 == params->cipher)
3311 )
3312 )
3313 {
3314 /* in case of static WEP, macaddr/bssid is not coming from nl80211
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303315 * interface, copy bssid for pairwise key and group macaddr for
Jeff Johnson295189b2012-06-20 16:38:30 -07003316 * group key initialization*/
3317
3318 tCsrRoamProfile *pRoamProfile = &pWextState->roamProfile;
3319
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303320 pWextState->roamProfile.negotiatedUCEncryptionType =
3321 pHddStaCtx->conn_info.ucEncryptionType =
Jeff Johnson295189b2012-06-20 16:38:30 -07003322 ((WLAN_CIPHER_SUITE_WEP40 == params->cipher) ?
3323 eCSR_ENCRYPT_TYPE_WEP40_STATICKEY :
3324 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY);
3325
3326
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303327 hddLog(VOS_TRACE_LEVEL_INFO_MED,
3328 "%s: Negotiated encryption type %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07003329 pWextState->roamProfile.negotiatedUCEncryptionType);
3330
3331 sme_SetCfgPrivacy((tpAniSirGlobal)WLAN_HDD_GET_HAL_CTX(pAdapter),
3332 &pWextState->roamProfile, true);
3333 setKey.keyLength = 0;
3334 setKey.keyDirection = eSIR_TX_RX;
3335
3336#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303337 if (pairwise)
Jeff Johnson295189b2012-06-20 16:38:30 -07003338 {
3339#endif
3340 if (mac_addr)
3341 {
3342 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
3343 }
3344 else
3345 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303346 /* macaddr is NULL, set the peerMac to bssId in case of BSS,
Jeff Johnson295189b2012-06-20 16:38:30 -07003347 * and peerMacAddress in case of IBSS*/
3348 if (eCSR_BSS_TYPE_START_IBSS == pRoamProfile->BSSType)
3349 {
3350 u8 staidx = wlan_hdd_cfg80211_get_ibss_peer_staidx(pAdapter);
3351 if (HDD_MAX_NUM_IBSS_STA != staidx)
3352 {
3353 vos_mem_copy(setKey.peerMac,
3354 &pHddStaCtx->conn_info.peerMacAddress[staidx],
3355 WNI_CFG_BSSID_LEN);
3356
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303357 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003358 else
3359 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303360 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No peerMac found",
Jeff Johnson295189b2012-06-20 16:38:30 -07003361 __func__);
3362 return -EOPNOTSUPP;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303363 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003364 }
3365 else
3366 {
3367 vos_mem_copy(setKey.peerMac,
3368 &pHddStaCtx->conn_info.bssId[0],
3369 WNI_CFG_BSSID_LEN);
3370 }
3371 }
3372#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
3373 }
3374 else
3375 {
3376 /* set group key*/
3377 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3378 "%s- %d: setting Group key",
3379 __func__, __LINE__);
3380 setKey.keyDirection = eSIR_RX_ONLY;
3381 vos_mem_copy(setKey.peerMac, groupmacaddr, WNI_CFG_BSSID_LEN);
3382 }
3383#endif
3384 }
3385 else if (
3386#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
3387 (!pairwise)
3388#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303389 (!mac_addr || is_broadcast_ether_addr(mac_addr))
Jeff Johnson295189b2012-06-20 16:38:30 -07003390#endif
3391 )
3392 {
3393 /* set group key*/
3394 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3395 "%s- %d: setting Group key",
3396 __func__, __LINE__);
3397 setKey.keyDirection = eSIR_RX_ONLY;
3398 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
3399 }
3400 else
3401 {
3402 /* set pairwise key*/
3403 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3404 "%s- %d: setting pairwise key",
3405 __func__, __LINE__);
3406 setKey.keyDirection = eSIR_TX_RX;
3407 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
3408 }
3409
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303410 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -07003411 "%s: set key for peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303412 __func__, setKey.peerMac[0], setKey.peerMac[1],
3413 setKey.peerMac[2], setKey.peerMac[3],
3414 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -07003415 setKey.keyDirection);
3416
3417 vos_status = wlan_hdd_check_ula_done(pAdapter);
3418
3419 if ( vos_status != VOS_STATUS_SUCCESS )
3420 {
3421 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3422 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
3423 __LINE__, vos_status );
3424
3425 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
3426
3427 return -EINVAL;
3428
3429 }
3430
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07003431#ifdef WLAN_FEATURE_VOWIFI_11R
3432 /* The supplicant may attempt to set the PTK once pre-authentication is done.
3433 Save the key in the UMAC and include it in the ADD BSS request */
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07003434 halStatus = sme_FTUpdateKey( WLAN_HDD_GET_HAL_CTX(pAdapter), &setKey);
Gopichand Nakkalad7d13652013-02-15 01:48:00 +05303435 if( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_WAIT )
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07003436 {
Gopichand Nakkalad7d13652013-02-15 01:48:00 +05303437 return -EINVAL;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07003438 }
3439#endif /* WLAN_FEATURE_VOWIFI_11R */
Jeff Johnson295189b2012-06-20 16:38:30 -07003440
3441 /* issue set key request to SME*/
3442 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
3443 pAdapter->sessionId, &setKey, &roamId );
3444
3445 if ( 0 != status )
3446 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303447 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07003448 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
3449 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
3450 return -EINVAL;
3451 }
3452
3453
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303454 /* in case of IBSS as there was no information available about WEP keys during
3455 * IBSS join, group key intialized with NULL key, so re-initialize group key
Jeff Johnson295189b2012-06-20 16:38:30 -07003456 * with correct value*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303457 if ( (eCSR_BSS_TYPE_START_IBSS == pWextState->roamProfile.BSSType) &&
3458 !( ( IW_AUTH_KEY_MGMT_802_1X
3459 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X))
Jeff Johnson295189b2012-06-20 16:38:30 -07003460 && (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType)
3461 )
3462 &&
3463 ( (WLAN_CIPHER_SUITE_WEP40 == params->cipher)
3464 || (WLAN_CIPHER_SUITE_WEP104 == params->cipher)
3465 )
3466 )
3467 {
3468 setKey.keyDirection = eSIR_RX_ONLY;
3469 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
3470
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303471 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -07003472 "%s: set key peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303473 __func__, setKey.peerMac[0], setKey.peerMac[1],
3474 setKey.peerMac[2], setKey.peerMac[3],
3475 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -07003476 setKey.keyDirection);
3477
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303478 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07003479 pAdapter->sessionId, &setKey, &roamId );
3480
3481 if ( 0 != status )
3482 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303483 hddLog(VOS_TRACE_LEVEL_ERROR,
3484 "%s: sme_RoamSetKey failed for group key (IBSS), returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07003485 __func__, status);
3486 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
3487 return -EINVAL;
3488 }
3489 }
3490 }
3491
3492 return 0;
3493}
3494
3495/*
3496 * FUNCTION: wlan_hdd_cfg80211_get_key
3497 * This function is used to get the key information
3498 */
3499#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303500static int wlan_hdd_cfg80211_get_key(
3501 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07003502 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303503 u8 key_index, bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -07003504 const u8 *mac_addr, void *cookie,
3505 void (*callback)(void *cookie, struct key_params*)
3506 )
3507#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303508static int wlan_hdd_cfg80211_get_key(
3509 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07003510 struct net_device *ndev,
3511 u8 key_index, const u8 *mac_addr, void *cookie,
3512 void (*callback)(void *cookie, struct key_params*)
3513 )
3514#endif
3515{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303516 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -07003517 hdd_wext_state_t *pWextState= WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
3518 tCsrRoamProfile *pRoamProfile = &(pWextState->roamProfile);
3519 struct key_params params;
3520
3521 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303522
Jeff Johnson295189b2012-06-20 16:38:30 -07003523 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",
3524 __func__,pAdapter->device_mode);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303525
Jeff Johnson295189b2012-06-20 16:38:30 -07003526 memset(&params, 0, sizeof(params));
3527
3528 if (CSR_MAX_NUM_KEY <= key_index)
3529 {
3530 return -EINVAL;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303531 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003532
3533 switch(pRoamProfile->EncryptionType.encryptionType[0])
3534 {
3535 case eCSR_ENCRYPT_TYPE_NONE:
3536 params.cipher = IW_AUTH_CIPHER_NONE;
3537 break;
3538
3539 case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY:
3540 case eCSR_ENCRYPT_TYPE_WEP40:
3541 params.cipher = WLAN_CIPHER_SUITE_WEP40;
3542 break;
3543
3544 case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY:
3545 case eCSR_ENCRYPT_TYPE_WEP104:
3546 params.cipher = WLAN_CIPHER_SUITE_WEP104;
3547 break;
3548
3549 case eCSR_ENCRYPT_TYPE_TKIP:
3550 params.cipher = WLAN_CIPHER_SUITE_TKIP;
3551 break;
3552
3553 case eCSR_ENCRYPT_TYPE_AES:
3554 params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
3555 break;
3556
3557 default:
3558 params.cipher = IW_AUTH_CIPHER_NONE;
3559 break;
3560 }
3561
3562 params.key_len = pRoamProfile->Keys.KeyLength[key_index];
3563 params.seq_len = 0;
3564 params.seq = NULL;
3565 params.key = &pRoamProfile->Keys.KeyMaterial[key_index][0];
3566 callback(cookie, &params);
3567 return 0;
3568}
3569
3570/*
3571 * FUNCTION: wlan_hdd_cfg80211_del_key
3572 * This function is used to delete the key information
3573 */
3574#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303575static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07003576 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303577 u8 key_index,
3578 bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -07003579 const u8 *mac_addr
3580 )
3581#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303582static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07003583 struct net_device *ndev,
3584 u8 key_index,
3585 const u8 *mac_addr
3586 )
3587#endif
3588{
3589 int status = 0;
3590
3591 //This code needs to be revisited. There is sme_removeKey API, we should
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303592 //plan to use that. After the change to use correct index in setkey,
Jeff Johnson295189b2012-06-20 16:38:30 -07003593 //it is observed that this is invalidating peer
3594 //key index whenever re-key is done. This is affecting data link.
3595 //It should be ok to ignore del_key.
3596#if 0
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303597 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
3598 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07003599 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
3600 tCsrRoamSetKey setKey;
3601 v_U32_t roamId= 0xFF;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303602
Jeff Johnson295189b2012-06-20 16:38:30 -07003603 ENTER();
3604
3605 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device_mode = %d\n",
3606 __func__,pAdapter->device_mode);
3607
3608 if (CSR_MAX_NUM_KEY <= key_index)
3609 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303610 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07003611 key_index);
3612
3613 return -EINVAL;
3614 }
3615
3616 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
3617 setKey.keyId = key_index;
3618
3619 if (mac_addr)
3620 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
3621 else
3622 vos_mem_copy(setKey.peerMac, groupmacaddr, WNI_CFG_BSSID_LEN);
3623
3624 setKey.encType = eCSR_ENCRYPT_TYPE_NONE;
3625
3626 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07003627 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303628 )
3629 {
3630
3631 hdd_hostapd_state_t *pHostapdState =
Jeff Johnson295189b2012-06-20 16:38:30 -07003632 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
3633 if( pHostapdState->bssState == BSS_START)
3634 {
3635 status = WLANSAP_SetKeySta( pVosContext, &setKey);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303636
Jeff Johnson295189b2012-06-20 16:38:30 -07003637 if ( status != eHAL_STATUS_SUCCESS )
3638 {
3639 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3640 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
3641 __LINE__, status );
3642 }
3643 }
3644 }
3645 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303646 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnson295189b2012-06-20 16:38:30 -07003647 )
3648 {
3649 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3650
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303651 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
3652
3653 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -07003654 "%s: delete key for peerMac %2x:%2x:%2x:%2x:%2x:%2x",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303655 __func__, setKey.peerMac[0], setKey.peerMac[1],
3656 setKey.peerMac[2], setKey.peerMac[3],
Jeff Johnson295189b2012-06-20 16:38:30 -07003657 setKey.peerMac[4], setKey.peerMac[5]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303658 if(pAdapter->sessionCtx.station.conn_info.connState ==
3659 eConnectionState_Associated)
Jeff Johnson295189b2012-06-20 16:38:30 -07003660 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303661 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07003662 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303663
Jeff Johnson295189b2012-06-20 16:38:30 -07003664 if ( 0 != status )
3665 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303666 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07003667 "%s: sme_RoamSetKey failure, returned %d",
3668 __func__, status);
3669 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
3670 return -EINVAL;
3671 }
3672 }
3673 }
3674#endif
Jeff Johnsone7245742012-09-05 17:12:55 -07003675 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07003676 return status;
3677}
3678
3679/*
3680 * FUNCTION: wlan_hdd_cfg80211_set_default_key
3681 * This function is used to set the default tx key index
3682 */
3683#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
3684static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
3685 struct net_device *ndev,
3686 u8 key_index,
3687 bool unicast, bool multicast)
3688#else
3689static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
3690 struct net_device *ndev,
3691 u8 key_index)
3692#endif
3693{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303694 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -07003695 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
3696 int status = 0;
3697 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3698
3699 ENTER();
3700
3701 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d key_index = %d \n",
3702 __func__,pAdapter->device_mode, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303703
Jeff Johnson295189b2012-06-20 16:38:30 -07003704 if (CSR_MAX_NUM_KEY <= key_index)
3705 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303706 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07003707 key_index);
3708
3709 return -EINVAL;
3710 }
3711
Jeff Johnson04dd8a82012-06-29 20:41:40 -07003712 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
3713 {
3714 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3715 "%s:LOGP in Progress. Ignore!!!", __func__);
3716 return -EAGAIN;
3717 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303718
Jeff Johnson295189b2012-06-20 16:38:30 -07003719 if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -07003720 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303721 )
Jeff Johnson295189b2012-06-20 16:38:30 -07003722 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303723 if ( (key_index != pWextState->roamProfile.Keys.defaultIndex) &&
3724 (eCSR_ENCRYPT_TYPE_TKIP !=
Jeff Johnson295189b2012-06-20 16:38:30 -07003725 pWextState->roamProfile.EncryptionType.encryptionType[0]) &&
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303726 (eCSR_ENCRYPT_TYPE_AES !=
Jeff Johnson295189b2012-06-20 16:38:30 -07003727 pWextState->roamProfile.EncryptionType.encryptionType[0])
3728 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303729 {
3730 /* if default key index is not same as previous one,
Jeff Johnson295189b2012-06-20 16:38:30 -07003731 * then update the default key index */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303732
Jeff Johnson295189b2012-06-20 16:38:30 -07003733 tCsrRoamSetKey setKey;
3734 v_U32_t roamId= 0xFF;
3735 tCsrKeys *Keys = &pWextState->roamProfile.Keys;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303736
3737 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: default tx key index %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07003738 __func__, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303739
Jeff Johnson295189b2012-06-20 16:38:30 -07003740 Keys->defaultIndex = (u8)key_index;
3741 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
3742 setKey.keyId = key_index;
3743 setKey.keyLength = Keys->KeyLength[key_index];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303744
3745 vos_mem_copy(&setKey.Key[0],
3746 &Keys->KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -07003747 Keys->KeyLength[key_index]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303748
Jeff Johnson295189b2012-06-20 16:38:30 -07003749 setKey.keyDirection = eSIR_TX_ONLY;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303750
3751 vos_mem_copy(setKey.peerMac,
Jeff Johnson295189b2012-06-20 16:38:30 -07003752 &pHddStaCtx->conn_info.bssId[0],
3753 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303754
3755 setKey.encType =
Jeff Johnson295189b2012-06-20 16:38:30 -07003756 pWextState->roamProfile.EncryptionType.encryptionType[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303757
Jeff Johnson295189b2012-06-20 16:38:30 -07003758 /* issue set key request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303759 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07003760 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303761
Jeff Johnson295189b2012-06-20 16:38:30 -07003762 if ( 0 != status )
3763 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303764 hddLog(VOS_TRACE_LEVEL_ERROR,
3765 "%s: sme_RoamSetKey failed, returned %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07003766 status);
3767 return -EINVAL;
3768 }
3769 }
3770 }
3771
3772 /* In SoftAp mode setting key direction for default mode */
3773 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
3774 {
3775 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
3776 pWextState->roamProfile.EncryptionType.encryptionType[0]) &&
3777 (eCSR_ENCRYPT_TYPE_AES !=
3778 pWextState->roamProfile.EncryptionType.encryptionType[0])
3779 )
3780 {
3781 /* Saving key direction for default key index to TX default */
3782 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
3783 pAPCtx->wepKey[key_index].keyDirection = eSIR_TX_DEFAULT;
3784 }
3785 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303786
Jeff Johnson295189b2012-06-20 16:38:30 -07003787 return status;
3788}
3789
Jeff Johnson295189b2012-06-20 16:38:30 -07003790/*
3791 * FUNCTION: wlan_hdd_cfg80211_inform_bss
3792 * This function is used to inform the BSS details to nl80211 interface.
3793 */
3794static struct cfg80211_bss* wlan_hdd_cfg80211_inform_bss(
3795 hdd_adapter_t *pAdapter, tCsrRoamConnectedProfile *roamProfile)
3796{
3797 struct net_device *dev = pAdapter->dev;
3798 struct wireless_dev *wdev = dev->ieee80211_ptr;
3799 struct wiphy *wiphy = wdev->wiphy;
3800 tSirBssDescription *pBssDesc = roamProfile->pBssDesc;
3801 int chan_no;
3802 int ie_length;
3803 const char *ie;
3804 unsigned int freq;
3805 struct ieee80211_channel *chan;
3806 int rssi = 0;
3807 struct cfg80211_bss *bss = NULL;
3808
3809 ENTER();
3810
3811 if( NULL == pBssDesc )
3812 {
3813 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pBssDesc is NULL\n", __func__);
3814 return bss;
3815 }
3816
3817 chan_no = pBssDesc->channelId;
3818 ie_length = GET_IE_LEN_IN_BSS_DESC( pBssDesc->length );
3819 ie = ((ie_length != 0) ? (const char *)&pBssDesc->ieFields: NULL);
3820
3821 if( NULL == ie )
3822 {
3823 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: IE of BSS descriptor is NULL\n", __func__);
3824 return bss;
3825 }
3826
3827#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
3828 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
3829 {
3830 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
3831 }
3832 else
3833 {
3834 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
3835 }
3836#else
3837 freq = ieee80211_channel_to_frequency(chan_no);
3838#endif
3839
3840 chan = __ieee80211_get_channel(wiphy, freq);
3841
3842 bss = cfg80211_get_bss(wiphy, chan, pBssDesc->bssId,
3843 &roamProfile->SSID.ssId[0], roamProfile->SSID.length,
3844 WLAN_CAPABILITY_ESS, WLAN_CAPABILITY_ESS);
3845 if (bss == NULL)
3846 {
3847 rssi = (VOS_MIN ((pBssDesc->rssi + pBssDesc->sinr), 0))*100;
3848
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303849 return (cfg80211_inform_bss(wiphy, chan, pBssDesc->bssId,
3850 le64_to_cpu(*(__le64 *)pBssDesc->timeStamp),
Jeff Johnson295189b2012-06-20 16:38:30 -07003851 pBssDesc->capabilityInfo,
3852 pBssDesc->beaconInterval, ie, ie_length,
3853 rssi, GFP_KERNEL ));
3854}
3855 else
3856 {
3857 return bss;
3858 }
3859}
3860
3861
3862
3863/*
3864 * FUNCTION: wlan_hdd_cfg80211_inform_bss_frame
3865 * This function is used to inform the BSS details to nl80211 interface.
3866 */
3867struct cfg80211_bss*
3868wlan_hdd_cfg80211_inform_bss_frame( hdd_adapter_t *pAdapter,
3869 tSirBssDescription *bss_desc
3870 )
3871{
3872 /*
3873 cfg80211_inform_bss() is not updating ie field of bss entry, if entry
3874 already exists in bss data base of cfg80211 for that particular BSS ID.
3875 Using cfg80211_inform_bss_frame to update the bss entry instead of
3876 cfg80211_inform_bss, But this call expects mgmt packet as input. As of
3877 now there is no possibility to get the mgmt(probe response) frame from PE,
3878 converting bss_desc to ieee80211_mgmt(probe response) and passing to
3879 cfg80211_inform_bss_frame.
3880 */
3881 struct net_device *dev = pAdapter->dev;
3882 struct wireless_dev *wdev = dev->ieee80211_ptr;
3883 struct wiphy *wiphy = wdev->wiphy;
3884 int chan_no = bss_desc->channelId;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08003885#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
3886 qcom_ie_age *qie_age = NULL;
3887 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length ) + sizeof(qcom_ie_age);
3888#else
Jeff Johnson295189b2012-06-20 16:38:30 -07003889 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length );
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08003890#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07003891 const char *ie =
3892 ((ie_length != 0) ? (const char *)&bss_desc->ieFields: NULL);
3893 unsigned int freq;
3894 struct ieee80211_channel *chan;
3895 struct ieee80211_mgmt *mgmt =
3896 kzalloc((sizeof (struct ieee80211_mgmt) + ie_length), GFP_KERNEL);
3897 struct cfg80211_bss *bss_status = NULL;
3898 size_t frame_len = sizeof (struct ieee80211_mgmt) + ie_length;
3899 int rssi = 0;
Jeff Johnsone7245742012-09-05 17:12:55 -07003900#ifdef WLAN_OPEN_SOURCE
3901 struct timespec ts;
3902#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07003903
3904 ENTER();
3905
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -07003906 if (!mgmt)
3907 return NULL;
3908
Jeff Johnson295189b2012-06-20 16:38:30 -07003909 memcpy(mgmt->bssid, bss_desc->bssId, ETH_ALEN);
Jeff Johnsone7245742012-09-05 17:12:55 -07003910
3911#ifdef WLAN_OPEN_SOURCE
3912 /* Android does not want the timestamp from the frame.
3913 Instead it wants a monotonic increasing value */
3914 get_monotonic_boottime(&ts);
3915 mgmt->u.probe_resp.timestamp =
3916 ((u64)ts.tv_sec * 1000000) + (ts.tv_nsec / 1000);
3917#else
3918 /* keep old behavior for non-open source (for now) */
Jeff Johnson295189b2012-06-20 16:38:30 -07003919 memcpy(&mgmt->u.probe_resp.timestamp, bss_desc->timeStamp,
3920 sizeof (bss_desc->timeStamp));
Jeff Johnsone7245742012-09-05 17:12:55 -07003921
3922#endif
3923
Jeff Johnson295189b2012-06-20 16:38:30 -07003924 mgmt->u.probe_resp.beacon_int = bss_desc->beaconInterval;
3925 mgmt->u.probe_resp.capab_info = bss_desc->capabilityInfo;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08003926
3927#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
3928 /* GPS Requirement: need age ie per entry. Using vendor specific. */
3929 /* Assuming this is the last IE, copy at the end */
3930 ie_length -=sizeof(qcom_ie_age);
3931 qie_age = (qcom_ie_age *)(mgmt->u.probe_resp.variable + ie_length);
3932 qie_age->element_id = QCOM_VENDOR_IE_ID;
3933 qie_age->len = QCOM_VENDOR_IE_AGE_LEN;
3934 qie_age->oui_1 = QCOM_OUI1;
3935 qie_age->oui_2 = QCOM_OUI2;
3936 qie_age->oui_3 = QCOM_OUI3;
3937 qie_age->type = QCOM_VENDOR_IE_AGE_TYPE;
3938 qie_age->age = vos_timer_get_system_ticks() - bss_desc->nReceivedTime;
3939#endif
3940
Jeff Johnson295189b2012-06-20 16:38:30 -07003941 memcpy(mgmt->u.probe_resp.variable, ie, ie_length);
3942
3943 mgmt->frame_control |=
3944 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_RESP);
3945
3946#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303947 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ) &&
Jeff Johnson295189b2012-06-20 16:38:30 -07003948 (wiphy->bands[IEEE80211_BAND_2GHZ] != NULL))
3949 {
3950 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
3951 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303952 else if ((chan_no > ARRAY_SIZE(hdd_channels_2_4_GHZ)) &&
Jeff Johnson295189b2012-06-20 16:38:30 -07003953 (wiphy->bands[IEEE80211_BAND_5GHZ] != NULL))
3954
3955 {
3956 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
3957 }
3958 else
3959 {
3960 kfree(mgmt);
3961 return NULL;
3962 }
3963#else
3964 freq = ieee80211_channel_to_frequency(chan_no);
3965#endif
3966 chan = __ieee80211_get_channel(wiphy, freq);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -08003967 /*when the band is changed on the fly using the GUI, three things are done
3968 * 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)
3969 * as part of the scan abort, message willbe queued to PE and we proceed with flushing and changinh the band.
3970 * pe will stop the scanning further and report back the results what ever it had till now by calling the call back function.
3971 * if the time between update band and scandone call back is sufficent enough the band change reflects in SME, SME validates the channels
3972 * and discards the channels correponding to previous band and calls back with zero bss results.
3973 * 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
3974 * all the channels correponding to previous band.this is due to race condition.but those channels are invalid to the new band and so
3975 * this function __ieee80211_get_channel will return NULL.Each time we report scan result with this pointer null warning kernel trace is printed.
3976 * if the scan results contain large number of APs continuosly kernel warning trace is printed and it will lead to apps watch dog bark.
3977 * So drop the bss and continue to next bss.
3978 */
3979 if(chan == NULL)
3980 {
3981 hddLog(VOS_TRACE_LEVEL_INFO, "%s chan pointer is NULL", __func__);
Chilam Ngc4244af2013-04-01 15:37:32 -07003982 kfree(mgmt);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -08003983 return NULL;
3984 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003985 /*To keep the rssi icon of the connected AP in the scan window
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303986 *and the rssi icon of the wireless networks in sync
Jeff Johnson295189b2012-06-20 16:38:30 -07003987 * */
3988 if (( eConnectionState_Associated ==
3989 pAdapter->sessionCtx.station.conn_info.connState ) &&
3990 ( VOS_TRUE == vos_mem_compare(bss_desc->bssId,
3991 pAdapter->sessionCtx.station.conn_info.bssId,
3992 WNI_CFG_BSSID_LEN)))
3993 {
3994 /* supplicant takes the signal strength in terms of mBm(100*dBm) */
3995 rssi = (pAdapter->rssi * 100);
3996 }
3997 else
3998 {
3999 rssi = (VOS_MIN ((bss_desc->rssi + bss_desc->sinr), 0))*100;
4000 }
4001
4002 bss_status = cfg80211_inform_bss_frame(wiphy, chan, mgmt,
4003 frame_len, rssi, GFP_KERNEL);
4004 kfree(mgmt);
4005 return bss_status;
4006}
4007
4008/*
4009 * FUNCTION: wlan_hdd_cfg80211_update_bss_db
4010 * This function is used to update the BSS data base of CFG8011
4011 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304012struct cfg80211_bss* wlan_hdd_cfg80211_update_bss_db( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07004013 tCsrRoamInfo *pRoamInfo
4014 )
4015{
4016 tCsrRoamConnectedProfile roamProfile;
4017 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
4018 struct cfg80211_bss *bss = NULL;
4019
4020 ENTER();
4021
4022 memset(&roamProfile, 0, sizeof(tCsrRoamConnectedProfile));
4023 sme_RoamGetConnectProfile(hHal, pAdapter->sessionId, &roamProfile);
4024
4025 if (NULL != roamProfile.pBssDesc)
4026 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304027 bss = wlan_hdd_cfg80211_inform_bss(pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07004028 &roamProfile);
4029
4030 if (NULL == bss)
4031 {
4032 hddLog(VOS_TRACE_LEVEL_INFO, "%s: cfg80211_inform_bss return NULL",
4033 __func__);
4034 }
4035
4036 sme_RoamFreeConnectProfile(hHal, &roamProfile);
4037 }
4038 else
4039 {
4040 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: roamProfile.pBssDesc is NULL",
4041 __func__);
4042 }
4043 return bss;
4044}
4045
4046/*
4047 * FUNCTION: wlan_hdd_cfg80211_update_bss
4048 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304049static int wlan_hdd_cfg80211_update_bss( struct wiphy *wiphy,
4050 hdd_adapter_t *pAdapter
Jeff Johnson295189b2012-06-20 16:38:30 -07004051 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304052{
Jeff Johnson295189b2012-06-20 16:38:30 -07004053 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
4054 tCsrScanResultInfo *pScanResult;
4055 eHalStatus status = 0;
4056 tScanResultHandle pResult;
4057 struct cfg80211_bss *bss_status = NULL;
4058
4059 ENTER();
4060
4061 if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress)
4062 {
4063 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:LOGP in Progress. Ignore!!!",__func__);
4064 return -EAGAIN;
4065 }
4066
4067 /*
4068 * start getting scan results and populate cgf80211 BSS database
4069 */
4070 status = sme_ScanGetResult(hHal, pAdapter->sessionId, NULL, &pResult);
4071
4072 /* no scan results */
4073 if (NULL == pResult)
4074 {
4075 hddLog(VOS_TRACE_LEVEL_INFO, "%s: No scan result\n", __func__);
4076 return status;
4077 }
4078
4079 pScanResult = sme_ScanResultGetFirst(hHal, pResult);
4080
4081 while (pScanResult)
4082 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304083 /*
4084 * cfg80211_inform_bss() is not updating ie field of bss entry, if
4085 * entry already exists in bss data base of cfg80211 for that
4086 * particular BSS ID. Using cfg80211_inform_bss_frame to update the
4087 * bss entry instead of cfg80211_inform_bss, But this call expects
4088 * mgmt packet as input. As of now there is no possibility to get
4089 * the mgmt(probe response) frame from PE, converting bss_desc to
Jeff Johnson295189b2012-06-20 16:38:30 -07004090 * ieee80211_mgmt(probe response) and passing to c
4091 * fg80211_inform_bss_frame.
4092 * */
4093
4094 bss_status = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
4095 &pScanResult->BssDescriptor);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304096
Jeff Johnson295189b2012-06-20 16:38:30 -07004097
4098 if (NULL == bss_status)
4099 {
4100 hddLog(VOS_TRACE_LEVEL_INFO,
4101 "%s: NULL returned by cfg80211_inform_bss\n", __func__);
4102 }
4103 else
4104 {
4105 cfg80211_put_bss(bss_status);
4106 }
4107
4108 pScanResult = sme_ScanResultGetNext(hHal, pResult);
4109 }
4110
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304111 sme_ScanResultPurge(hHal, pResult);
Jeff Johnson295189b2012-06-20 16:38:30 -07004112
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304113 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07004114}
4115
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004116void
4117hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel)
4118{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304119 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07004120 "%02X:%02X:%02X:%02X:%02X:%02X\n",
4121 macAddr[0], macAddr[1], macAddr[2], macAddr[3], macAddr[4],
4122 macAddr[5]);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004123} /****** end hddPrintMacAddr() ******/
4124
4125void
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07004126hddPrintPmkId(tANI_U8 *pmkId, tANI_U8 logLevel)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004127{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304128 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07004129 "%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X\n",
4130 pmkId[0], pmkId[1], pmkId[2], pmkId[3], pmkId[4],
4131 pmkId[5], pmkId[6], pmkId[7], pmkId[8], pmkId[9], pmkId[10],
4132 pmkId[11], pmkId[12], pmkId[13], pmkId[14], pmkId[15]);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004133} /****** end hddPrintPmkId() ******/
4134
4135//hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel);
4136//hddPrintMacAddr(macAddr, VOS_TRACE_LEVEL_FATAL);
4137
4138//void sirDumpBuf(tpAniSirGlobal pMac, tANI_U8 modId, tANI_U32 level, tANI_U8 *buf, tANI_U32 size);
4139//sirDumpBuf(pMac, VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, pmkid, 16);
4140
4141#define dump_bssid(bssid) \
4142 { \
Jeff Johnsone7245742012-09-05 17:12:55 -07004143 hddLog(VOS_TRACE_LEVEL_INFO, "BSSID (MAC) address:\t"); \
4144 hddPrintMacAddr(bssid, VOS_TRACE_LEVEL_INFO);\
4145 hddLog(VOS_TRACE_LEVEL_INFO, "\n"); \
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004146 }
4147
4148#define dump_pmkid(pMac, pmkid) \
4149 { \
Jeff Johnsone7245742012-09-05 17:12:55 -07004150 hddLog(VOS_TRACE_LEVEL_INFO, "PMKSA-ID:\t"); \
4151 hddPrintPmkId(pmkid, VOS_TRACE_LEVEL_INFO);\
4152 hddLog(VOS_TRACE_LEVEL_INFO, "\n"); \
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004153 }
4154
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -07004155#if defined(FEATURE_WLAN_LFR) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004156/*
4157 * FUNCTION: wlan_hdd_cfg80211_pmksa_candidate_notify
4158 * This function is used to notify the supplicant of a new PMKSA candidate.
4159 */
4160int wlan_hdd_cfg80211_pmksa_candidate_notify(
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304161 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004162 int index, bool preauth )
4163{
Jeff Johnsone7245742012-09-05 17:12:55 -07004164#ifdef FEATURE_WLAN_OKC
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004165 struct net_device *dev = pAdapter->dev;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004166 hdd_context_t *pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004167
4168 ENTER();
Jeff Johnsone7245742012-09-05 17:12:55 -07004169 hddLog(VOS_TRACE_LEVEL_INFO, "%s is going to notify supplicant of:", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004170
4171 if( NULL == pRoamInfo )
4172 {
4173 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pRoamInfo is NULL\n", __func__);
4174 return -EINVAL;
4175 }
4176
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004177 if (eANI_BOOLEAN_TRUE == hdd_is_okc_mode_enabled(pHddCtx))
4178 {
4179 dump_bssid(pRoamInfo->bssid);
4180 cfg80211_pmksa_candidate_notify(dev, index,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004181 pRoamInfo->bssid, preauth, GFP_KERNEL);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004182 }
Jeff Johnsone7245742012-09-05 17:12:55 -07004183#endif /* FEATURE_WLAN_OKC */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304184 return 0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004185}
4186#endif //FEATURE_WLAN_LFR
4187
Jeff Johnson295189b2012-06-20 16:38:30 -07004188/*
4189 * FUNCTION: hdd_cfg80211_scan_done_callback
4190 * scanning callback function, called after finishing scan
4191 *
4192 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304193static eHalStatus hdd_cfg80211_scan_done_callback(tHalHandle halHandle,
Jeff Johnson295189b2012-06-20 16:38:30 -07004194 void *pContext, tANI_U32 scanId, eCsrScanStatus status)
4195{
4196 struct net_device *dev = (struct net_device *) pContext;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304197 //struct wireless_dev *wdev = dev->ieee80211_ptr;
Jeff Johnson295189b2012-06-20 16:38:30 -07004198 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07004199 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
4200 hdd_scaninfo_t *pScanInfo = &pHddCtx->scan_info;
Jeff Johnson295189b2012-06-20 16:38:30 -07004201 struct cfg80211_scan_request *req = NULL;
4202 int ret = 0;
4203
4204 ENTER();
4205
4206 hddLog(VOS_TRACE_LEVEL_INFO,
4207 "%s called with halHandle = %p, pContext = %p,"
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304208 "scanID = %d, returned status = %d\n",
Jeff Johnson295189b2012-06-20 16:38:30 -07004209 __func__, halHandle, pContext, (int) scanId, (int) status);
4210
4211 //Block on scan req completion variable. Can't wait forever though.
4212 ret = wait_for_completion_interruptible_timeout(
4213 &pScanInfo->scan_req_completion_event,
4214 msecs_to_jiffies(WLAN_WAIT_TIME_SCAN_REQ));
4215 if (!ret)
4216 {
4217 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -07004218 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -07004219 }
4220
4221 if(pScanInfo->mScanPending != VOS_TRUE)
4222 {
4223 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -07004224 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -07004225 }
4226
4227 /* Check the scanId */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304228 if (pScanInfo->scanId != scanId)
Jeff Johnson295189b2012-06-20 16:38:30 -07004229 {
4230 hddLog(VOS_TRACE_LEVEL_INFO,
4231 "%s called with mismatched scanId pScanInfo->scanId = %d "
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304232 "scanId = %d \n", __func__, (int) pScanInfo->scanId,
Jeff Johnson295189b2012-06-20 16:38:30 -07004233 (int) scanId);
4234 }
4235
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304236 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07004237 pAdapter);
4238
4239 if (0 > ret)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304240 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004241
4242
4243 /* If any client wait scan result through WEXT
4244 * send scan done event to client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07004245 if (pHddCtx->scan_info.waitScanResult)
Jeff Johnson295189b2012-06-20 16:38:30 -07004246 {
4247 /* The other scan request waiting for current scan finish
4248 * Send event to notify current scan finished */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07004249 if(WEXT_SCAN_PENDING_DELAY == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -07004250 {
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07004251 vos_event_set(&pHddCtx->scan_info.scan_finished_event);
Jeff Johnson295189b2012-06-20 16:38:30 -07004252 }
4253 /* Send notify to WEXT client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07004254 else if(WEXT_SCAN_PENDING_PIGGYBACK == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -07004255 {
4256 struct net_device *dev = pAdapter->dev;
4257 union iwreq_data wrqu;
4258 int we_event;
4259 char *msg;
4260
4261 memset(&wrqu, '\0', sizeof(wrqu));
4262 we_event = SIOCGIWSCAN;
4263 msg = NULL;
4264 wireless_send_event(dev, we_event, &wrqu, msg);
4265 }
4266 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07004267 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07004268
4269 /* Get the Scan Req */
4270 req = pAdapter->request;
4271
4272 if (!req)
4273 {
4274 hddLog(VOS_TRACE_LEVEL_ERROR, "request is became NULL\n");
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07004275 pScanInfo->mScanPending = VOS_FALSE;
Jeff Johnsone7245742012-09-05 17:12:55 -07004276 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -07004277 }
4278
4279 /*
4280 * setting up 0, just in case.
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304281 */
Jeff Johnson295189b2012-06-20 16:38:30 -07004282 req->n_ssids = 0;
4283 req->n_channels = 0;
4284 req->ie = 0;
4285
Jeff Johnson295189b2012-06-20 16:38:30 -07004286 pAdapter->request = NULL;
Jeff Johnsone7245742012-09-05 17:12:55 -07004287 /* Scan is no longer pending */
4288 pScanInfo->mScanPending = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07004289
Madan Mohan Koyyalamudib764bf82012-10-11 16:38:51 -07004290 /*
4291 * cfg80211_scan_done informing NL80211 about completion
4292 * of scanning
4293 */
4294 cfg80211_scan_done(req, false);
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -08004295 complete(&pScanInfo->abortscan_event_var);
Jeff Johnson295189b2012-06-20 16:38:30 -07004296
Jeff Johnsone7245742012-09-05 17:12:55 -07004297allow_suspend:
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07004298 /* release the wake lock at the end of the scan*/
4299 hdd_allow_suspend();
Jeff Johnsone7245742012-09-05 17:12:55 -07004300
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -07004301 /* Acquire wakelock to handle the case where APP's tries to suspend
4302 * immediatly after the driver gets connect request(i.e after scan)
4303 * from supplicant, this result in app's is suspending and not able
4304 * to process the connect request to AP */
4305 hdd_allow_suspend_timeout(100);
4306
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07004307#ifdef FEATURE_WLAN_TDLS
4308 wlan_hdd_tdls_scan_done_callback(pAdapter);
4309#endif
4310
Jeff Johnson295189b2012-06-20 16:38:30 -07004311 EXIT();
4312 return 0;
4313}
4314
4315/*
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08004316 * FUNCTION: hdd_isScanAllowed
4317 * Go through each adapter and check if scan allowed
4318 *
4319 */
4320v_BOOL_t hdd_isScanAllowed( hdd_context_t *pHddCtx )
4321{
4322 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
4323 hdd_station_ctx_t *pHddStaCtx = NULL;
4324 hdd_adapter_t *pAdapter = NULL;
4325 VOS_STATUS status = 0;
4326 v_U8_t staId = 0;
4327 v_U8_t *staMac = NULL;
4328
4329 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
4330
4331 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
4332 {
4333 pAdapter = pAdapterNode->pAdapter;
4334
4335 if( pAdapter )
4336 {
4337 hddLog(VOS_TRACE_LEVEL_INFO,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304338 "%s: Adapter with device mode %d exists",
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08004339 __func__, pAdapter->device_mode);
4340 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
4341 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
4342 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
4343 {
4344 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4345 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
4346 (VOS_FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
4347 {
4348 staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]);
4349 hddLog(VOS_TRACE_LEVEL_ERROR,
4350 "%s: client %02x:%02x:%02x:%02x:%02x:%02x is in the "
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304351 "middle of WPS/EAPOL exchange.", __func__,
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08004352 staMac[0], staMac[1], staMac[2],
4353 staMac[3], staMac[4], staMac[5]);
4354 return VOS_FALSE;
4355 }
4356 }
4357 else if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) ||
4358 (WLAN_HDD_P2P_GO == pAdapter->device_mode))
4359 {
4360 for (staId = 0; staId < WLAN_MAX_STA_COUNT; staId++)
4361 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304362 if ((pAdapter->aStaInfo[staId].isUsed) &&
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08004363 (WLANTL_STA_CONNECTED == pAdapter->aStaInfo[staId].tlSTAState))
4364 {
4365 staMac = (v_U8_t *) &(pAdapter->aStaInfo[staId].macAddrSTA.bytes[0]);
4366
4367 hddLog(VOS_TRACE_LEVEL_ERROR,
4368 "%s: client %02x:%02x:%02x:%02x:%02x:%02x of SoftAP/P2P-GO is in the "
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304369 "middle of WPS/EAPOL exchange.", __func__,
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08004370 staMac[0], staMac[1], staMac[2],
4371 staMac[3], staMac[4], staMac[5]);
4372 return VOS_FALSE;
4373 }
4374 }
4375 }
4376 }
4377 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
4378 pAdapterNode = pNext;
4379 }
4380 hddLog(VOS_TRACE_LEVEL_INFO,
4381 "%s: Scan allowed", __func__);
4382 return VOS_TRUE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304383}
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08004384
4385/*
Jeff Johnson295189b2012-06-20 16:38:30 -07004386 * FUNCTION: wlan_hdd_cfg80211_scan
4387 * this scan respond to scan trigger and update cfg80211 scan database
4388 * later, scan dump command can be used to recieve scan results
4389 */
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -08004390int wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
4391#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
4392 struct net_device *dev,
4393#endif
4394 struct cfg80211_scan_request *request)
4395{
4396#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
4397 struct net_device *dev = request->wdev->netdev;
4398#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304399 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Jeff Johnson295189b2012-06-20 16:38:30 -07004400 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
4401 hdd_wext_state_t *pwextBuf = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
4402 hdd_config_t *cfg_param = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
4403 tCsrScanRequest scanRequest;
4404 tANI_U8 *channelList = NULL, i;
4405 v_U32_t scanId = 0;
4406 int status = 0;
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07004407 hdd_scaninfo_t *pScanInfo = &pHddCtx->scan_info;
Jeff Johnson295189b2012-06-20 16:38:30 -07004408 v_U8_t* pP2pIe = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07004409
4410 ENTER();
4411
4412 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",
4413 __func__,pAdapter->device_mode);
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08004414
Gopichand Nakkala681989c2013-03-06 22:27:48 -08004415 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08004416 (eConnectionState_Connecting ==
Gopichand Nakkala681989c2013-03-06 22:27:48 -08004417 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08004418 {
4419 hddLog(VOS_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08004420 "%s: %p(%d) Connection in progress: Scan request denied (EBUSY)", __func__, \
4421 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08004422 return -EBUSY;
4423 }
4424
Jeff Johnson295189b2012-06-20 16:38:30 -07004425#ifdef WLAN_BTAMP_FEATURE
4426 //Scan not supported when AMP traffic is on.
Gopichand Nakkala681989c2013-03-06 22:27:48 -08004427 if (VOS_TRUE == WLANBAP_AmpSessionOn())
Jeff Johnson295189b2012-06-20 16:38:30 -07004428 {
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08004429 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07004430 "%s: No scanning when AMP is on", __func__);
4431 return -EOPNOTSUPP;
4432 }
4433#endif
4434 //Scan on any other interface is not supported.
Gopichand Nakkala681989c2013-03-06 22:27:48 -08004435 if (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07004436 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -08004437 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07004438 "%s: Not scanning on device_mode = %d",
4439 __func__, pAdapter->device_mode);
4440 return -EOPNOTSUPP;
4441 }
4442
4443 if (TRUE == pScanInfo->mScanPending)
4444 {
4445 hddLog(VOS_TRACE_LEVEL_INFO, "%s: mScanPending is TRUE", __func__);
Gopichand Nakkala681989c2013-03-06 22:27:48 -08004446 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -07004447 }
4448
4449 if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress)
4450 {
4451 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
4452 "%s:LOGP in Progress. Ignore!!!", __func__);
4453 return -EAGAIN;
4454 }
4455
Mohit Khanna6c52bbf2012-09-11 15:10:12 -07004456 if ((WLAN_HDD_GET_CTX(pAdapter))->isLoadUnloadInProgress)
4457 {
4458 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
4459 "%s:Unloading/Loading in Progress. Ignore!!!", __func__);
4460 return -EAGAIN;
4461 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304462 //Don't Allow Scan and return busy if Remain On
Jeff Johnson32d95a32012-09-10 13:15:23 -07004463 //Channel and action frame is pending
4464 //Otherwise Cancel Remain On Channel and allow Scan
4465 //If no action frame pending
Gopichand Nakkala681989c2013-03-06 22:27:48 -08004466 if (0 != wlan_hdd_check_remain_on_channel(pAdapter))
Jeff Johnson32d95a32012-09-10 13:15:23 -07004467 {
4468 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Remain On Channel Pending", __func__);
4469 return -EBUSY;
4470 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08004471#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07004472 /* if tdls disagree scan right now, return immediately.
4473 tdls will schedule the scan when scan is allowed. (return SUCCESS)
4474 or will reject the scan if any TDLS is in progress. (return -EBUSY)
4475 */
4476 status = wlan_hdd_tdls_scan_callback (pAdapter,
4477 wiphy,
4478#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
4479 dev,
Gopichand Nakkalac3c42b92013-03-20 19:42:34 -07004480#endif
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07004481 request);
4482 if(status <= 0)
4483 {
4484 hddLog(VOS_TRACE_LEVEL_INFO, "%s: TDLS Pending %d", __func__, status);
4485 return status;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08004486 }
4487#endif
Jeff Johnson32d95a32012-09-10 13:15:23 -07004488
Jeff Johnson295189b2012-06-20 16:38:30 -07004489 if (mutex_lock_interruptible(&pHddCtx->tmInfo.tmOperationLock))
4490 {
4491 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_ERROR,
Jeff Johnson1250df42012-12-10 14:31:52 -08004492 "%s: Acquire lock fail", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004493 return -EAGAIN;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304494 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004495 if (TRUE == pHddCtx->tmInfo.tmAction.enterImps)
4496 {
4497 hddLog(VOS_TRACE_LEVEL_WARN,
4498 "%s: MAX TM Level Scan not allowed", __func__);
4499 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304500 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -07004501 }
4502 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
4503
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08004504 /* Check if scan is allowed at this point of time.
4505 */
4506 if (!hdd_isScanAllowed(pHddCtx))
4507 {
4508 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Scan not allowed", __func__);
4509 return -EBUSY;
4510 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304511
Jeff Johnson295189b2012-06-20 16:38:30 -07004512 vos_mem_zero( &scanRequest, sizeof(scanRequest));
4513
4514 if (NULL != request)
4515 {
4516 hddLog(VOS_TRACE_LEVEL_INFO, "scan request for ssid = %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304517 (int)request->n_ssids);
Jeff Johnson295189b2012-06-20 16:38:30 -07004518
4519 /* Even though supplicant doesn't provide any SSIDs, n_ssids is set to 1.
4520 * Becasue of this, driver is assuming that this is not wildcard scan and so
4521 * is not aging out the scan results.
4522 */
Jeff Johnson32d95a32012-09-10 13:15:23 -07004523 if (request->ssids && '\0' == request->ssids->ssid[0])
Jeff Johnson295189b2012-06-20 16:38:30 -07004524 {
4525 request->n_ssids = 0;
4526 }
4527
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07004528 if ((request->ssids) && (0 < request->n_ssids))
Jeff Johnson295189b2012-06-20 16:38:30 -07004529 {
4530 tCsrSSIDInfo *SsidInfo;
4531 int j;
4532 scanRequest.SSIDs.numOfSSIDs = request->n_ssids;
4533 /* Allocate num_ssid tCsrSSIDInfo structure */
4534 SsidInfo = scanRequest.SSIDs.SSIDList =
4535 ( tCsrSSIDInfo *)vos_mem_malloc(
4536 request->n_ssids*sizeof(tCsrSSIDInfo));
4537
4538 if(NULL == scanRequest.SSIDs.SSIDList)
4539 {
4540 hddLog(VOS_TRACE_LEVEL_ERROR,
4541 "memory alloc failed SSIDInfo buffer");
4542 return -ENOMEM;
4543 }
4544
4545 /* copy all the ssid's and their length */
4546 for(j = 0; j < request->n_ssids; j++, SsidInfo++)
4547 {
4548 /* get the ssid length */
4549 SsidInfo->SSID.length = request->ssids[j].ssid_len;
4550 vos_mem_copy(SsidInfo->SSID.ssId, &request->ssids[j].ssid[0],
4551 SsidInfo->SSID.length);
4552 SsidInfo->SSID.ssId[SsidInfo->SSID.length] = '\0';
4553 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "SSID number %d: %s",
4554 j, SsidInfo->SSID.ssId);
4555 }
4556 /* set the scan type to active */
4557 scanRequest.scanType = eSIR_ACTIVE_SCAN;
4558 }
4559 else if(WLAN_HDD_P2P_GO == pAdapter->device_mode)
4560 {
4561 /* set the scan type to active */
4562 scanRequest.scanType = eSIR_ACTIVE_SCAN;
4563 }
4564 else
4565 {
4566 /*Set the scan type to default type, in this case it is ACTIVE*/
4567 scanRequest.scanType = pScanInfo->scan_mode;
4568 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304569 scanRequest.minChnTime = cfg_param->nActiveMinChnTime;
Jeff Johnson295189b2012-06-20 16:38:30 -07004570 scanRequest.maxChnTime = cfg_param->nActiveMaxChnTime;
4571 }
4572 else
4573 {
4574 /* set the scan type to active */
4575 scanRequest.scanType = eSIR_ACTIVE_SCAN;
4576 vos_mem_set( scanRequest.bssid, sizeof( tCsrBssid ), 0xff );
4577
4578 /* set min and max channel time to zero */
4579 scanRequest.minChnTime = 0;
4580 scanRequest.maxChnTime = 0;
4581 }
4582
4583 /* set BSSType to default type */
4584 scanRequest.BSSType = eCSR_BSS_TYPE_ANY;
4585
4586 /*TODO: scan the requested channels only*/
4587
4588 /*Right now scanning all the channels */
4589 if( request )
4590 {
4591 if( request->n_channels )
4592 {
4593 channelList = vos_mem_malloc( request->n_channels );
4594 if( NULL == channelList )
4595 {
4596 status = -ENOMEM;
4597 goto free_mem;
4598 }
4599
4600 for( i = 0 ; i < request->n_channels ; i++ )
4601 channelList[i] = request->channels[i]->hw_value;
4602 }
4603
4604 scanRequest.ChannelInfo.numOfChannels = request->n_channels;
4605 scanRequest.ChannelInfo.ChannelList = channelList;
4606
4607 /* set requestType to full scan */
4608 scanRequest.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304609
4610 /* Flush the scan results(only p2p beacons) for STA scan and P2P
Madan Mohan Koyyalamudi8d50f312012-11-27 15:48:57 -08004611 * search (Flush on both full scan and social scan but not on single
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304612 * channel scan).P2P search happens on 3 social channels (1, 6, 11)
Madan Mohan Koyyalamudi8d50f312012-11-27 15:48:57 -08004613 */
4614
4615 /* Supplicant does single channel scan after 8-way handshake
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304616 * and in that case driver shoudnt flush scan results. If
4617 * driver flushes the scan results here and unfortunately if
4618 * the AP doesnt respond to our probe req then association
Madan Mohan Koyyalamudi8d50f312012-11-27 15:48:57 -08004619 * fails which is not desired
4620 */
4621
4622 if( request->n_channels != WLAN_HDD_P2P_SINGLE_CHANNEL_SCAN )
4623 {
4624 sme_ScanFlushP2PResult( WLAN_HDD_GET_HAL_CTX(pAdapter),
4625 pAdapter->sessionId );
4626 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004627
4628 if( request->ie_len )
4629 {
4630 /* save this for future association (join requires this) */
4631 memset( &pScanInfo->scanAddIE, 0, sizeof(pScanInfo->scanAddIE) );
4632 memcpy( pScanInfo->scanAddIE.addIEdata, request->ie, request->ie_len);
4633 pScanInfo->scanAddIE.length = request->ie_len;
4634
4635 if((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Jeff Johnsone7245742012-09-05 17:12:55 -07004636 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
4637 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -07004638 )
4639 {
4640 pwextBuf->roamProfile.pAddIEScan = pScanInfo->scanAddIE.addIEdata;
4641 pwextBuf->roamProfile.nAddIEScanLength = pScanInfo->scanAddIE.length;
4642 }
4643
4644 scanRequest.uIEFieldLen = pScanInfo->scanAddIE.length;
4645 scanRequest.pIEField = pScanInfo->scanAddIE.addIEdata;
4646
Jeff Johnson295189b2012-06-20 16:38:30 -07004647 pP2pIe = wlan_hdd_get_p2p_ie_ptr((v_U8_t*)request->ie,
4648 request->ie_len);
4649 if (pP2pIe != NULL)
4650 {
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07004651#ifdef WLAN_FEATURE_P2P_DEBUG
4652 if (((globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED) ||
4653 (globalP2PConnectionStatus == P2P_GO_NEG_PROCESS)) &&
4654 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
4655 {
4656 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_1;
4657 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
4658 "Go nego completed to Connection is started");
4659 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
4660 "for 8way Handshake");
4661 }
4662 else if((globalP2PConnectionStatus == P2P_CLIENT_DISCONNECTED_STATE) &&
4663 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
4664 {
4665 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_2;
4666 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
4667 "Disconnected state to Connection is started");
4668 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
4669 "for 4way Handshake");
4670 }
4671#endif
4672
Jeff Johnsone7245742012-09-05 17:12:55 -07004673 /* no_cck will be set during p2p find to disable 11b rates */
4674 if(TRUE == request->no_cck)
Jeff Johnson295189b2012-06-20 16:38:30 -07004675 {
Jeff Johnson295189b2012-06-20 16:38:30 -07004676 hddLog(VOS_TRACE_LEVEL_INFO,
4677 "%s: This is a P2P Search", __func__);
4678 scanRequest.p2pSearch = 1;
Jeff Johnsone7245742012-09-05 17:12:55 -07004679
Jeff Johnsone7245742012-09-05 17:12:55 -07004680 if( request->n_channels == WLAN_HDD_P2P_SOCIAL_CHANNELS )
4681 {
Madan Mohan Koyyalamudi1b1d9e82012-10-21 11:38:33 -07004682 /* set requestType to P2P Discovery */
4683 scanRequest.requestType = eCSR_SCAN_P2P_DISCOVERY;
Jeff Johnsone7245742012-09-05 17:12:55 -07004684 }
4685
4686 /*
4687 Skip Dfs Channel in case of P2P Search
4688 if it is set in ini file
4689 */
4690 if(cfg_param->skipDfsChnlInP2pSearch)
4691 {
4692 scanRequest.skipDfsChnlInP2pSearch = 1;
4693 }
4694 else
4695 {
4696 scanRequest.skipDfsChnlInP2pSearch = 0;
4697 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004698
Jeff Johnson295189b2012-06-20 16:38:30 -07004699 }
4700 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004701 }
4702 }
4703
4704 INIT_COMPLETION(pScanInfo->scan_req_completion_event);
4705
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07004706 /* acquire the wakelock to avoid the apps suspend during the scan. To
4707 * address the following issues.
4708 * 1) Disconnected scenario: we are not allowing the suspend as WLAN is not in
4709 * BMPS/IMPS this result in android trying to suspend aggressively and backing off
4710 * for long time, this result in apps running at full power for long time.
4711 * 2) Connected scenario: If we allow the suspend during the scan, RIVA will
4712 * be stuck in full power because of resume BMPS
4713 */
4714 hdd_prevent_suspend();
Jeff Johnsone7245742012-09-05 17:12:55 -07004715
4716 status = sme_ScanRequest( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07004717 pAdapter->sessionId, &scanRequest, &scanId,
4718 &hdd_cfg80211_scan_done_callback, dev );
Jeff Johnsone7245742012-09-05 17:12:55 -07004719
Jeff Johnson295189b2012-06-20 16:38:30 -07004720 if (eHAL_STATUS_SUCCESS != status)
4721 {
4722 hddLog(VOS_TRACE_LEVEL_ERROR,
4723 "%s: sme_ScanRequest returned error %d", __func__, status);
4724 complete(&pScanInfo->scan_req_completion_event);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -07004725 if(eHAL_STATUS_RESOURCES == status)
4726 {
Madan Mohan Koyyalamudia3fcf142012-10-18 15:01:20 -07004727 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 -07004728 status = -EBUSY;
4729 } else {
4730 status = -EIO;
4731 }
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07004732 hdd_allow_suspend();
Jeff Johnson295189b2012-06-20 16:38:30 -07004733 goto free_mem;
4734 }
4735
4736 pScanInfo->mScanPending = TRUE;
4737 pAdapter->request = request;
4738 pScanInfo->scanId = scanId;
4739
4740 complete(&pScanInfo->scan_req_completion_event);
4741
4742free_mem:
4743 if( scanRequest.SSIDs.SSIDList )
4744 {
4745 vos_mem_free(scanRequest.SSIDs.SSIDList);
4746 }
4747
4748 if( channelList )
4749 vos_mem_free( channelList );
4750
4751 EXIT();
4752
4753 return status;
4754}
4755
4756/*
4757 * FUNCTION: wlan_hdd_cfg80211_connect_start
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304758 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -07004759 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304760int wlan_hdd_cfg80211_connect_start( hdd_adapter_t *pAdapter,
Jeff Johnson32d95a32012-09-10 13:15:23 -07004761 const u8 *ssid, size_t ssid_len, const u8 *bssid, u8 operatingChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -07004762{
4763 int status = 0;
4764 hdd_wext_state_t *pWextState;
4765 v_U32_t roamId;
4766 tCsrRoamProfile *pRoamProfile;
4767 eMib_dot11DesiredBssType connectedBssType;
4768 eCsrAuthType RSNAuthType;
4769
4770 ENTER();
4771
4772 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304773
Jeff Johnson295189b2012-06-20 16:38:30 -07004774 if (SIR_MAC_MAX_SSID_LENGTH < ssid_len)
4775 {
4776 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wrong SSID len", __func__);
4777 return -EINVAL;
4778 }
4779
4780 pRoamProfile = &pWextState->roamProfile;
4781
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304782 if (pRoamProfile)
Jeff Johnson295189b2012-06-20 16:38:30 -07004783 {
Jeff Johnsone7245742012-09-05 17:12:55 -07004784 int ret = 0;
4785 hdd_station_ctx_t *pHddStaCtx;
4786 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4787 hdd_connGetConnectedBssType(pHddStaCtx,&connectedBssType );
4788
4789 if((eMib_dot11DesiredBssType_independent == connectedBssType) ||
4790 (eConnectionState_Associated == pHddStaCtx->conn_info.connState) ||
4791 (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState))
Jeff Johnson295189b2012-06-20 16:38:30 -07004792 {
4793 /* Issue disconnect to CSR */
4794 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304795 if( eHAL_STATUS_SUCCESS ==
Jeff Johnson295189b2012-06-20 16:38:30 -07004796 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
4797 pAdapter->sessionId,
4798 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
4799 {
Jeff Johnsone7245742012-09-05 17:12:55 -07004800 ret = wait_for_completion_interruptible_timeout(
4801 &pAdapter->disconnect_comp_var,
4802 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
4803 if (0 == ret)
4804 {
4805 VOS_ASSERT(0);
4806 }
4807 }
4808 }
4809 else if(eConnectionState_Disconnecting == pHddStaCtx->conn_info.connState)
4810 {
4811 ret = wait_for_completion_interruptible_timeout(
4812 &pAdapter->disconnect_comp_var,
4813 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
4814 if (0 == ret)
4815 {
4816 VOS_ASSERT(0);
Jeff Johnson295189b2012-06-20 16:38:30 -07004817 }
4818 }
4819
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304820 if (HDD_WMM_USER_MODE_NO_QOS ==
Jeff Johnson295189b2012-06-20 16:38:30 -07004821 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->WmmMode)
4822 {
4823 /*QoS not enabled in cfg file*/
4824 pRoamProfile->uapsd_mask = 0;
4825 }
4826 else
4827 {
4828 /*QoS enabled, update uapsd mask from cfg file*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304829 pRoamProfile->uapsd_mask =
Jeff Johnson295189b2012-06-20 16:38:30 -07004830 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask;
4831 }
4832
4833 pRoamProfile->SSIDs.numOfSSIDs = 1;
4834 pRoamProfile->SSIDs.SSIDList->SSID.length = ssid_len;
4835 vos_mem_zero(pRoamProfile->SSIDs.SSIDList->SSID.ssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304836 sizeof(pRoamProfile->SSIDs.SSIDList->SSID.ssId));
Jeff Johnson295189b2012-06-20 16:38:30 -07004837 vos_mem_copy((void *)(pRoamProfile->SSIDs.SSIDList->SSID.ssId),
4838 ssid, ssid_len);
4839
4840 if (bssid)
4841 {
4842 pRoamProfile->BSSIDs.numOfBSSIDs = 1;
4843 vos_mem_copy((void *)(pRoamProfile->BSSIDs.bssid), bssid,
4844 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304845 /* Save BSSID in seperate variable as well, as RoamProfile
4846 BSSID is getting zeroed out in the association process. And in
Jeff Johnson295189b2012-06-20 16:38:30 -07004847 case of join failure we should send valid BSSID to supplicant
4848 */
4849 vos_mem_copy((void *)(pWextState->req_bssId), bssid,
4850 WNI_CFG_BSSID_LEN);
4851 }
4852
4853 if ((IW_AUTH_WPA_VERSION_WPA == pWextState->wpaVersion) ||
4854 (IW_AUTH_WPA_VERSION_WPA2 == pWextState->wpaVersion))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304855 {
Jeff Johnson295189b2012-06-20 16:38:30 -07004856 /*set gen ie*/
4857 hdd_SetGENIEToCsr(pAdapter, &RSNAuthType);
4858 /*set auth*/
4859 hdd_set_csr_auth_type(pAdapter, RSNAuthType);
4860 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304861 else if ( (pWextState->roamProfile.AuthType.authType[0] ==
Jeff Johnson295189b2012-06-20 16:38:30 -07004862 eCSR_AUTH_TYPE_OPEN_SYSTEM)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304863 && ((pWextState->roamProfile.EncryptionType.encryptionType[0] ==
4864 eCSR_ENCRYPT_TYPE_WEP40_STATICKEY)
4865 || (pWextState->roamProfile.EncryptionType.encryptionType[0] ==
Jeff Johnson295189b2012-06-20 16:38:30 -07004866 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY))
4867 )
4868 {
4869 /*Android UI not having any option to configure the Authentication type to OPEN/SHARED;
4870 * The authentication type will be always eCSR_AUTH_TYPE_OPEN_SYSTEM when WEP is used
4871 * Use eCSR_AUTH_TYPE_AUTOSWITCH when WEP encryption used*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304872 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.authType =
Jeff Johnson295189b2012-06-20 16:38:30 -07004873 eCSR_AUTH_TYPE_AUTOSWITCH;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304874 pWextState->roamProfile.AuthType.authType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -07004875 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.authType;
4876 }
4877#ifdef FEATURE_WLAN_WAPI
4878 if (pAdapter->wapi_info.nWapiMode)
4879 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004880 hddLog(LOG1, "%s: Setting WAPI AUTH Type and Encryption Mode values", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004881 switch (pAdapter->wapi_info.wapiAuthMode)
4882 {
4883 case WAPI_AUTH_MODE_PSK:
4884 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004885 hddLog(LOG1, "%s: WAPI AUTH TYPE: PSK: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07004886 pAdapter->wapi_info.wapiAuthMode);
4887 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_PSK;
4888 break;
4889 }
4890 case WAPI_AUTH_MODE_CERT:
4891 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004892 hddLog(LOG1, "%s: WAPI AUTH TYPE: CERT: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07004893 pAdapter->wapi_info.wapiAuthMode);
4894 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE;
4895 break;
4896 }
4897 } // End of switch
4898 if ( pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_PSK ||
4899 pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_CERT)
4900 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004901 hddLog(LOG1, "%s: WAPI PAIRWISE/GROUP ENCRYPTION: WPI", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004902 pRoamProfile->AuthType.numEntries = 1;
4903 pRoamProfile->EncryptionType.numEntries = 1;
4904 pRoamProfile->EncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
4905 pRoamProfile->mcEncryptionType.numEntries = 1;
4906 pRoamProfile->mcEncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
4907 }
4908 }
4909#endif /* FEATURE_WLAN_WAPI */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05304910#ifdef WLAN_FEATURE_GTK_OFFLOAD
4911 /* Initializing gtkOffloadRequestParams */
4912 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
4913 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
4914 {
4915 pHddStaCtx->gtkOffloadRequestParams.requested = FALSE;
4916 memset(&pHddStaCtx->gtkOffloadRequestParams.gtkOffloadReqParams,
4917 0, sizeof (tSirGtkOffloadParams));
4918 }
4919#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07004920 pRoamProfile->csrPersona = pAdapter->device_mode;
4921
Jeff Johnson32d95a32012-09-10 13:15:23 -07004922 if( operatingChannel )
4923 {
4924 pRoamProfile->ChannelInfo.ChannelList = &operatingChannel;
4925 pRoamProfile->ChannelInfo.numOfChannels = 1;
4926 }
Chet Lanctot186b5732013-03-18 10:26:30 -07004927 else
4928 {
4929 pRoamProfile->ChannelInfo.ChannelList = NULL;
4930 pRoamProfile->ChannelInfo.numOfChannels = 0;
4931 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07004932
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08004933 /* change conn_state to connecting before sme_RoamConnect(), because sme_RoamConnect()
4934 * has a direct path to call hdd_smeRoamCallback(), which will change the conn_state
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304935 * If direct path, conn_state will be accordingly changed to NotConnected or Associated
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08004936 * by either hdd_AssociationCompletionHandler() or hdd_DisConnectHandler() in sme_RoamCallback()
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -08004937 * if sme_RomConnect is to be queued, Connecting state will remain until it is completed.
4938 */
4939 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode)
4940 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
4941 eConnectionState_Connecting);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304942
4943 status = sme_RoamConnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07004944 pAdapter->sessionId, pRoamProfile, &roamId);
4945
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08004946 if( (eHAL_STATUS_SUCCESS != status) &&
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +05304947 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) )
4948
4949 {
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08004950 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: sme_RoamConnect (session %d) failed with "
4951 "status %d. -> NotConnected", __func__, pAdapter->sessionId, status);
4952 /* change back to NotAssociated */
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +05304953 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08004954 eConnectionState_NotConnected);
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +05304955 }
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -08004956
4957 pRoamProfile->ChannelInfo.ChannelList = NULL;
4958 pRoamProfile->ChannelInfo.numOfChannels = 0;
4959
Jeff Johnson295189b2012-06-20 16:38:30 -07004960 }
4961 else
4962 {
4963 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid Roam profile", __func__);
4964 return -EINVAL;
4965 }
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08004966 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07004967 return status;
4968}
4969
4970/*
4971 * FUNCTION: wlan_hdd_set_cfg80211_auth_type
4972 * This function is used to set the authentication type (OPEN/SHARED).
4973 *
4974 */
4975static int wlan_hdd_cfg80211_set_auth_type(hdd_adapter_t *pAdapter,
4976 enum nl80211_auth_type auth_type)
4977{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304978 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07004979 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4980
4981 ENTER();
4982
4983 /*set authentication type*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304984 switch (auth_type)
Jeff Johnson295189b2012-06-20 16:38:30 -07004985 {
4986 case NL80211_AUTHTYPE_OPEN_SYSTEM:
4987 case NL80211_AUTHTYPE_AUTOMATIC:
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07004988#ifdef WLAN_FEATURE_VOWIFI_11R
4989 case NL80211_AUTHTYPE_FT:
4990#endif /* WLAN_FEATURE_VOWIFI_11R */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304991 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -07004992 "%s: set authentication type to OPEN", __func__);
4993 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
4994 break;
4995
4996 case NL80211_AUTHTYPE_SHARED_KEY:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304997 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -07004998 "%s: set authentication type to SHARED", __func__);
4999 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_SHARED_KEY;
5000 break;
5001#ifdef FEATURE_WLAN_CCX
5002 case NL80211_AUTHTYPE_NETWORK_EAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305003 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -07005004 "%s: set authentication type to CCKM WPA", __func__);
5005 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_CCKM_WPA;//eCSR_AUTH_TYPE_CCKM_RSN needs to be handled as well if required.
5006 break;
5007#endif
5008
5009
5010 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305011 hddLog(VOS_TRACE_LEVEL_ERROR,
5012 "%s: Unsupported authentication type %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07005013 auth_type);
5014 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_UNKNOWN;
5015 return -EINVAL;
5016 }
5017
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305018 pWextState->roamProfile.AuthType.authType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -07005019 pHddStaCtx->conn_info.authType;
5020 return 0;
5021}
5022
5023/*
5024 * FUNCTION: wlan_hdd_set_akm_suite
5025 * This function is used to set the key mgmt type(PSK/8021x).
5026 *
5027 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305028static int wlan_hdd_set_akm_suite( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07005029 u32 key_mgmt
5030 )
5031{
5032 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
5033 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305034
Jeff Johnson295189b2012-06-20 16:38:30 -07005035 /*set key mgmt type*/
5036 switch(key_mgmt)
5037 {
5038 case WLAN_AKM_SUITE_PSK:
Gopichand Nakkala356fb102013-03-06 12:34:04 +05305039#ifdef WLAN_FEATURE_VOWIFI_11R
5040 case WLAN_AKM_SUITE_FT_PSK:
5041#endif
5042 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to PSK",
Jeff Johnson295189b2012-06-20 16:38:30 -07005043 __func__);
5044 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_PSK;
5045 break;
5046
5047 case WLAN_AKM_SUITE_8021X:
Gopichand Nakkala356fb102013-03-06 12:34:04 +05305048#ifdef WLAN_FEATURE_VOWIFI_11R
5049 case WLAN_AKM_SUITE_FT_8021X:
5050#endif
5051 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to 8021x",
Jeff Johnson295189b2012-06-20 16:38:30 -07005052 __func__);
5053 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
5054 break;
5055#ifdef FEATURE_WLAN_CCX
5056#define WLAN_AKM_SUITE_CCKM 0x00409600 /* Should be in ieee802_11_defs.h */
5057#define IW_AUTH_KEY_MGMT_CCKM 8 /* Should be in linux/wireless.h */
5058 case WLAN_AKM_SUITE_CCKM:
5059 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to CCKM",
5060 __func__);
5061 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_CCKM;
5062 break;
5063#endif
5064
5065 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305066 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported key mgmt type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07005067 __func__, key_mgmt);
5068 return -EINVAL;
5069
5070 }
5071 return 0;
5072}
5073
5074/*
5075 * FUNCTION: wlan_hdd_cfg80211_set_cipher
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305076 * This function is used to set the encryption type
Jeff Johnson295189b2012-06-20 16:38:30 -07005077 * (NONE/WEP40/WEP104/TKIP/CCMP).
5078 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305079static int wlan_hdd_cfg80211_set_cipher( hdd_adapter_t *pAdapter,
5080 u32 cipher,
Jeff Johnson295189b2012-06-20 16:38:30 -07005081 bool ucast
5082 )
5083{
5084 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305085 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07005086 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
5087
5088 ENTER();
5089
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305090 if (!cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -07005091 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305092 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: received cipher %d - considering none",
Jeff Johnson295189b2012-06-20 16:38:30 -07005093 __func__, cipher);
5094 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
5095 }
5096 else
5097 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305098
Jeff Johnson295189b2012-06-20 16:38:30 -07005099 /*set encryption method*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305100 switch (cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -07005101 {
5102 case IW_AUTH_CIPHER_NONE:
5103 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
5104 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305105
Jeff Johnson295189b2012-06-20 16:38:30 -07005106 case WLAN_CIPHER_SUITE_WEP40:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305107 if ((IW_AUTH_KEY_MGMT_802_1X == pWextState->authKeyMgmt) &&
Jeff Johnson295189b2012-06-20 16:38:30 -07005108 (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType))
5109 encryptionType = eCSR_ENCRYPT_TYPE_WEP40;
5110 else
5111 encryptionType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
5112 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305113
Jeff Johnson295189b2012-06-20 16:38:30 -07005114 case WLAN_CIPHER_SUITE_WEP104:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305115 if ((IW_AUTH_KEY_MGMT_802_1X == pWextState->authKeyMgmt) &&
Jeff Johnson295189b2012-06-20 16:38:30 -07005116 (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType))
5117 encryptionType = eCSR_ENCRYPT_TYPE_WEP104;
5118 else
5119 encryptionType = eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
5120 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305121
Jeff Johnson295189b2012-06-20 16:38:30 -07005122 case WLAN_CIPHER_SUITE_TKIP:
5123 encryptionType = eCSR_ENCRYPT_TYPE_TKIP;
5124 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305125
Jeff Johnson295189b2012-06-20 16:38:30 -07005126 case WLAN_CIPHER_SUITE_CCMP:
5127 encryptionType = eCSR_ENCRYPT_TYPE_AES;
5128 break;
5129#ifdef FEATURE_WLAN_WAPI
5130 case WLAN_CIPHER_SUITE_SMS4:
5131 encryptionType = eCSR_ENCRYPT_TYPE_WPI;
5132 break;
5133#endif
5134
5135#ifdef FEATURE_WLAN_CCX
5136 case WLAN_CIPHER_SUITE_KRK:
5137 encryptionType = eCSR_ENCRYPT_TYPE_KRK;
5138 break;
5139#endif
5140 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305141 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported cipher type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07005142 __func__, cipher);
5143 return -EOPNOTSUPP;
5144 }
5145 }
5146
5147 if (ucast)
5148 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305149 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting unicast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07005150 __func__, encryptionType);
5151 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
5152 pWextState->roamProfile.EncryptionType.numEntries = 1;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305153 pWextState->roamProfile.EncryptionType.encryptionType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -07005154 encryptionType;
5155 }
5156 else
5157 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305158 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting mcast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07005159 __func__, encryptionType);
5160 pHddStaCtx->conn_info.mcEncryptionType = encryptionType;
5161 pWextState->roamProfile.mcEncryptionType.numEntries = 1;
5162 pWextState->roamProfile.mcEncryptionType.encryptionType[0] = encryptionType;
5163 }
5164
5165 return 0;
5166}
5167
5168
5169/*
5170 * FUNCTION: wlan_hdd_cfg80211_set_ie
5171 * This function is used to parse WPA/RSN IE's.
5172 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305173int wlan_hdd_cfg80211_set_ie( hdd_adapter_t *pAdapter,
5174 u8 *ie,
Jeff Johnson295189b2012-06-20 16:38:30 -07005175 size_t ie_len
5176 )
5177{
5178 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
5179 u8 *genie = ie;
5180 v_U16_t remLen = ie_len;
5181#ifdef FEATURE_WLAN_WAPI
5182 v_U32_t akmsuite[MAX_NUM_AKM_SUITES];
5183 u16 *tmp;
5184 v_U16_t akmsuiteCount;
5185 int *akmlist;
5186#endif
5187 ENTER();
5188
5189 /* clear previous assocAddIE */
5190 pWextState->assocAddIE.length = 0;
5191 pWextState->roamProfile.bWPSAssociation = VOS_FALSE;
5192
5193 while (remLen >= 2)
5194 {
5195 v_U16_t eLen = 0;
5196 v_U8_t elementId;
5197 elementId = *genie++;
5198 eLen = *genie++;
5199 remLen -= 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305200
5201 hddLog(VOS_TRACE_LEVEL_INFO, "%s: IE[0x%X], LEN[%d]\n",
Jeff Johnson295189b2012-06-20 16:38:30 -07005202 __func__, elementId, eLen);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305203
5204 switch ( elementId )
Jeff Johnson295189b2012-06-20 16:38:30 -07005205 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305206 case DOT11F_EID_WPA:
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005207 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 -07005208 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305209 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07005210 "%s: Invalid WPA IE", __func__);
5211 return -EINVAL;
5212 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305213 else if (0 == memcmp(&genie[0], "\x00\x50\xf2\x04", 4))
Jeff Johnson295189b2012-06-20 16:38:30 -07005214 {
5215 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305216 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPS IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -07005217 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305218
Jeff Johnson295189b2012-06-20 16:38:30 -07005219 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
5220 {
Jeff Johnson902c9832012-12-10 14:28:09 -08005221 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE. "
5222 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -07005223 VOS_ASSERT(0);
5224 return -ENOMEM;
5225 }
5226 // WSC IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
5227 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
5228 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305229
Jeff Johnson295189b2012-06-20 16:38:30 -07005230 pWextState->roamProfile.bWPSAssociation = VOS_TRUE;
5231 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
5232 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
5233 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305234 else if (0 == memcmp(&genie[0], "\x00\x50\xf2", 3))
5235 {
Jeff Johnson295189b2012-06-20 16:38:30 -07005236 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPA IE (len %d)",__func__, eLen + 2);
5237 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
5238 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2) /*ie_len*/);
5239 pWextState->roamProfile.pWPAReqIE = pWextState->WPARSNIE;
5240 pWextState->roamProfile.nWPAReqIELength = eLen + 2;//ie_len;
5241 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305242 else if ( (0 == memcmp(&genie[0], P2P_OUI_TYPE,
5243 P2P_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07005244 /*Consider P2P IE, only for P2P Client */
5245 && (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
5246 {
5247 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305248 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set P2P IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -07005249 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305250
Jeff Johnson295189b2012-06-20 16:38:30 -07005251 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
5252 {
Jeff Johnson902c9832012-12-10 14:28:09 -08005253 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
5254 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -07005255 VOS_ASSERT(0);
5256 return -ENOMEM;
5257 }
5258 // P2P IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
5259 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
5260 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305261
Jeff Johnson295189b2012-06-20 16:38:30 -07005262 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
5263 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
5264 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005265#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305266 else if ( (0 == memcmp(&genie[0], WFD_OUI_TYPE,
5267 WFD_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07005268 /*Consider WFD IE, only for P2P Client */
5269 && (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
5270 {
5271 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305272 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WFD IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -07005273 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305274
Jeff Johnson295189b2012-06-20 16:38:30 -07005275 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
5276 {
Jeff Johnson902c9832012-12-10 14:28:09 -08005277 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
5278 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -07005279 VOS_ASSERT(0);
5280 return -ENOMEM;
5281 }
5282 // WFD IE is saved to Additional IE ; it should be accumulated to handle
5283 // WPS IE + P2P IE + WFD IE
5284 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
5285 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305286
Jeff Johnson295189b2012-06-20 16:38:30 -07005287 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
5288 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
5289 }
5290#endif
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005291 /* Appending HS 2.0 Indication Element in Assiciation Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305292 else if ( (0 == memcmp(&genie[0], HS20_OUI_TYPE,
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07005293 HS20_OUI_TYPE_SIZE)) )
5294 {
5295 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305296 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set HS20 IE(len %d)",
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07005297 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005298
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07005299 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
5300 {
Jeff Johnson902c9832012-12-10 14:28:09 -08005301 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
5302 "Need bigger buffer space");
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07005303 VOS_ASSERT(0);
5304 return -ENOMEM;
5305 }
5306 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
5307 pWextState->assocAddIE.length += eLen + 2;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005308
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07005309 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
5310 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
5311 }
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005312
Jeff Johnson295189b2012-06-20 16:38:30 -07005313 break;
5314 case DOT11F_EID_RSN:
5315 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set RSN IE(len %d)",__func__, eLen + 2);
5316 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
5317 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2)/*ie_len*/);
5318 pWextState->roamProfile.pRSNReqIE = pWextState->WPARSNIE;
5319 pWextState->roamProfile.nRSNReqIELength = eLen + 2; //ie_len;
5320 break;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005321 /* Appending Extended Capabilities with Interworking bit set in Assoc Req */
5322 case DOT11F_EID_EXTCAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305323 {
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005324 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305325 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set Extended CAPS IE(len %d)",
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005326 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305327
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005328 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
5329 {
Jeff Johnson902c9832012-12-10 14:28:09 -08005330 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
5331 "Need bigger buffer space");
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005332 VOS_ASSERT(0);
5333 return -ENOMEM;
5334 }
5335 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
5336 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305337
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005338 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
5339 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
5340 break;
5341 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005342#ifdef FEATURE_WLAN_WAPI
5343 case WLAN_EID_WAPI:
5344 pAdapter->wapi_info.nWapiMode = 1; //Setting WAPI Mode to ON=1
5345 hddLog(VOS_TRACE_LEVEL_INFO,"WAPI MODE IS %lu \n",
5346 pAdapter->wapi_info.nWapiMode);
5347 tmp = (u16 *)ie;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305348 tmp = tmp + 2; // Skip element Id and Len, Version
Jeff Johnson295189b2012-06-20 16:38:30 -07005349 akmsuiteCount = WPA_GET_LE16(tmp);
5350 tmp = tmp + 1;
5351 akmlist = (int *)(tmp);
5352 if(akmsuiteCount <= MAX_NUM_AKM_SUITES)
5353 {
5354 memcpy(akmsuite, akmlist, (4*akmsuiteCount));
5355 }
5356 else
5357 {
5358 hddLog(VOS_TRACE_LEVEL_FATAL, "Invalid akmSuite count\n");
5359 VOS_ASSERT(0);
5360 return -EINVAL;
5361 }
5362
5363 if (WAPI_PSK_AKM_SUITE == akmsuite[0])
5364 {
5365 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO PSK",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005366 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005367 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_PSK;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305368 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005369 if (WAPI_CERT_AKM_SUITE == akmsuite[0])
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305370 {
Jeff Johnson295189b2012-06-20 16:38:30 -07005371 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO CERTIFICATE",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005372 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005373 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_CERT;
5374 }
5375 break;
5376#endif
5377 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305378 hddLog (VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07005379 "%s Set UNKNOWN IE %X", __func__, elementId);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005380 /* when Unknown IE is received we should break and continue
5381 * to the next IE in the buffer instead we were returning
5382 * so changing this to break */
5383 break;
Jeff Johnson295189b2012-06-20 16:38:30 -07005384 }
5385 genie += eLen;
5386 remLen -= eLen;
5387 }
5388 EXIT();
5389 return 0;
5390}
5391
5392/*
5393 * FUNCTION: wlan_hdd_cfg80211_set_privacy
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305394 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -07005395 * parameters during connect operation.
5396 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305397int wlan_hdd_cfg80211_set_privacy( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07005398 struct cfg80211_connect_params *req
5399 )
5400{
5401 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305402 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07005403 ENTER();
5404
5405 /*set wpa version*/
5406 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
5407
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305408 if (req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -07005409 {
5410 if ( (NL80211_WPA_VERSION_1 == req->crypto.wpa_versions)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305411 && ( (req->ie_len)
5412 && (0 == memcmp( &req->ie[2], "\x00\x50\xf2",3) ) ) )
Jeff Johnson295189b2012-06-20 16:38:30 -07005413 // Make sure that it is including a WPA IE.
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305414 /* Currently NL is putting WPA version 1 even for open,
Jeff Johnson295189b2012-06-20 16:38:30 -07005415 * since p2p ie is also put in same buffer.
5416 * */
5417 {
5418 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
5419 }
5420 else if (NL80211_WPA_VERSION_2 == req->crypto.wpa_versions)
5421 {
5422 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
5423 }
5424 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305425
5426 hddLog(VOS_TRACE_LEVEL_INFO, "%s: set wpa version to %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07005427 pWextState->wpaVersion);
5428
5429 /*set authentication type*/
5430 status = wlan_hdd_cfg80211_set_auth_type(pAdapter, req->auth_type);
5431
5432 if (0 > status)
5433 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305434 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07005435 "%s: failed to set authentication type ", __func__);
5436 return status;
5437 }
5438
5439 /*set key mgmt type*/
5440 if (req->crypto.n_akm_suites)
5441 {
5442 status = wlan_hdd_set_akm_suite(pAdapter, req->crypto.akm_suites[0]);
5443 if (0 > status)
5444 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305445 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set akm suite",
Jeff Johnson295189b2012-06-20 16:38:30 -07005446 __func__);
5447 return status;
5448 }
5449 }
5450
5451 /*set pairwise cipher type*/
5452 if (req->crypto.n_ciphers_pairwise)
5453 {
5454 status = wlan_hdd_cfg80211_set_cipher(pAdapter,
5455 req->crypto.ciphers_pairwise[0], true);
5456 if (0 > status)
5457 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305458 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07005459 "%s: failed to set unicast cipher type", __func__);
5460 return status;
5461 }
5462 }
5463 else
5464 {
5465 /*Reset previous cipher suite to none*/
5466 status = wlan_hdd_cfg80211_set_cipher(pAdapter, 0, true);
5467 if (0 > status)
5468 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305469 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07005470 "%s: failed to set unicast cipher type", __func__);
5471 return status;
5472 }
5473 }
5474
5475 /*set group cipher type*/
5476 status = wlan_hdd_cfg80211_set_cipher(pAdapter, req->crypto.cipher_group,
5477 false);
5478
5479 if (0 > status)
5480 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305481 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set mcast cipher type",
Jeff Johnson295189b2012-06-20 16:38:30 -07005482 __func__);
5483 return status;
5484 }
5485
Chet Lanctot186b5732013-03-18 10:26:30 -07005486#ifdef WLAN_FEATURE_11W
5487 pWextState->roamProfile.MFPEnabled = (req->mfp == NL80211_MFP_REQUIRED);
5488#endif
5489
Jeff Johnson295189b2012-06-20 16:38:30 -07005490 /*parse WPA/RSN IE, and set the correspoing fileds in Roam profile*/
5491 if (req->ie_len)
5492 {
5493 status = wlan_hdd_cfg80211_set_ie(pAdapter, req->ie, req->ie_len);
5494 if ( 0 > status)
5495 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305496 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse the WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -07005497 __func__);
5498 return status;
5499 }
5500 }
5501
5502 /*incase of WEP set default key information*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305503 if (req->key && req->key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -07005504 {
5505 if ( (WLAN_CIPHER_SUITE_WEP40 == req->crypto.ciphers_pairwise[0])
5506 || (WLAN_CIPHER_SUITE_WEP104 == req->crypto.ciphers_pairwise[0])
5507 )
5508 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305509 if ( IW_AUTH_KEY_MGMT_802_1X
Jeff Johnson295189b2012-06-20 16:38:30 -07005510 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X ))
5511 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305512 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Dynamic WEP not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -07005513 __func__);
5514 return -EOPNOTSUPP;
5515 }
5516 else
5517 {
5518 u8 key_len = req->key_len;
5519 u8 key_idx = req->key_idx;
5520
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305521 if ((eCSR_SECURITY_WEP_KEYSIZE_MAX_BYTES >= key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -07005522 && (CSR_MAX_NUM_KEY > key_idx)
5523 )
5524 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305525 hddLog(VOS_TRACE_LEVEL_INFO,
5526 "%s: setting default wep key, key_idx = %hu key_len %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07005527 __func__, key_idx, key_len);
5528 vos_mem_copy(
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305529 &pWextState->roamProfile.Keys.KeyMaterial[key_idx][0],
Jeff Johnson295189b2012-06-20 16:38:30 -07005530 req->key, key_len);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305531 pWextState->roamProfile.Keys.KeyLength[key_idx] =
Jeff Johnson295189b2012-06-20 16:38:30 -07005532 (u8)key_len;
5533 pWextState->roamProfile.Keys.defaultIndex = (u8)key_idx;
5534 }
5535 }
5536 }
5537 }
5538
5539 return status;
5540}
5541
5542/*
5543 * FUNCTION: wlan_hdd_cfg80211_set_privacy
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305544 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -07005545 * parameters during connect operation.
5546 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305547static int wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07005548 struct net_device *ndev,
5549 struct cfg80211_connect_params *req
5550 )
5551{
5552 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305553 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -07005554 VOS_STATUS exitbmpsStatus = VOS_STATUS_E_INVAL;
5555 hdd_context_t *pHddCtx = NULL;
5556
5557 ENTER();
5558
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305559 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -07005560 "%s: device_mode = %d\n",__func__,pAdapter->device_mode);
5561
5562 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
5563 {
5564 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5565 "%s:LOGP in Progress. Ignore!!!", __func__);
5566 return -EAGAIN;
5567 }
5568
5569#ifdef WLAN_BTAMP_FEATURE
5570 //Infra connect not supported when AMP traffic is on.
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305571 if( VOS_TRUE == WLANBAP_AmpSessionOn() )
Jeff Johnson295189b2012-06-20 16:38:30 -07005572 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305573 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07005574 "%s: No connection when AMP is on", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08005575 return -ECONNREFUSED;
Jeff Johnson295189b2012-06-20 16:38:30 -07005576 }
5577#endif
5578 /*initialise security parameters*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305579 status = wlan_hdd_cfg80211_set_privacy(pAdapter, req);
Jeff Johnson295189b2012-06-20 16:38:30 -07005580
5581 if ( 0 > status)
5582 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305583 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security params",
Jeff Johnson295189b2012-06-20 16:38:30 -07005584 __func__);
5585 return status;
5586 }
5587
5588 //If Device Mode is Station Concurrent Sessions Exit BMps
Jeff Johnsona8a1a482012-12-12 16:49:33 -08005589 //P2P Mode will be taken care in Open/close adapter
Jeff Johnson295189b2012-06-20 16:38:30 -07005590 if((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
5591 (vos_concurrent_sessions_running()))
5592 {
5593 v_CONTEXT_t pVosContext = vos_get_global_context( VOS_MODULE_ID_HDD, NULL );
5594
5595 if (NULL != pVosContext)
5596 {
5597 pHddCtx = vos_get_context( VOS_MODULE_ID_HDD, pVosContext);
5598 if(NULL != pHddCtx)
5599 {
5600 exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
5601 }
5602 }
5603 }
5604
Mohit Khanna765234a2012-09-11 15:08:35 -07005605 if ( req->channel )
5606 {
5607 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
5608 req->ssid_len, req->bssid,
5609 req->channel->hw_value);
5610 }
5611 else
5612 {
5613 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
5614 req->ssid_len, req->bssid,
5615 0);
5616 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005617
5618 if (0 > status)
5619 {
5620 //ReEnable BMPS if disabled
5621 if((VOS_STATUS_SUCCESS == exitbmpsStatus) &&
5622 (NULL != pHddCtx))
5623 {
5624 //ReEnable Bmps and Imps back
5625 hdd_enable_bmps_imps(pHddCtx);
5626 }
5627
5628 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: connect failed", __func__);
5629 return status;
5630 }
5631 (WLAN_HDD_GET_CTX(pAdapter))->isAmpAllowed = VOS_FALSE;
5632 EXIT();
5633 return status;
5634}
5635
5636
5637/*
5638 * FUNCTION: wlan_hdd_cfg80211_disconnect
5639 * This function is used to issue a disconnect request to SME
5640 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305641static int wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07005642 struct net_device *dev,
5643 u16 reason
5644 )
5645{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305646 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
5647 tCsrRoamProfile *pRoamProfile =
Jeff Johnson295189b2012-06-20 16:38:30 -07005648 &(WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter))->roamProfile;
5649 int status = 0;
5650 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08005651#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala4327a152013-03-04 23:22:42 -08005652 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08005653 tANI_U8 staIdx;
5654#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305655
Jeff Johnson295189b2012-06-20 16:38:30 -07005656 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305657
5658 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",
Jeff Johnson295189b2012-06-20 16:38:30 -07005659 __func__,pAdapter->device_mode);
5660
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305661 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Disconnect called with reason code %d",
5662 __func__, reason);
Jeff Johnson295189b2012-06-20 16:38:30 -07005663
5664 if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress)
5665 {
5666 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5667 "%s:LOGP in Progress. Ignore!!!",__func__);
5668 return -EAGAIN;
5669 }
5670 if (NULL != pRoamProfile)
5671 {
5672 /*issue disconnect request to SME, if station is in connected state*/
5673 if (pHddStaCtx->conn_info.connState == eConnectionState_Associated)
5674 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305675 eCsrRoamDisconnectReason reasonCode =
Jeff Johnson295189b2012-06-20 16:38:30 -07005676 eCSR_DISCONNECT_REASON_UNSPECIFIED;
5677 switch(reason)
5678 {
5679 case WLAN_REASON_MIC_FAILURE:
5680 reasonCode = eCSR_DISCONNECT_REASON_MIC_ERROR;
5681 break;
5682
5683 case WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY:
5684 case WLAN_REASON_DISASSOC_AP_BUSY:
5685 case WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA:
5686 reasonCode = eCSR_DISCONNECT_REASON_DISASSOC;
5687 break;
5688
5689 case WLAN_REASON_PREV_AUTH_NOT_VALID:
5690 case WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA:
5691 reasonCode = eCSR_DISCONNECT_REASON_DEAUTH;
5692 break;
5693
5694 case WLAN_REASON_DEAUTH_LEAVING:
5695 default:
5696 reasonCode = eCSR_DISCONNECT_REASON_UNSPECIFIED;
5697 break;
5698 }
5699 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
5700 (WLAN_HDD_GET_CTX(pAdapter))->isAmpAllowed = VOS_TRUE;
5701 INIT_COMPLETION(pAdapter->disconnect_comp_var);
5702
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08005703#ifdef FEATURE_WLAN_TDLS
5704 /* First clean up the tdls peers if any */
Gopichand Nakkala4327a152013-03-04 23:22:42 -08005705 for (staIdx = 0 ; staIdx < HDD_MAX_NUM_TDLS_STA; staIdx++)
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08005706 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -08005707 if ((pHddCtx->tdlsConnInfo[staIdx].sessionId == pAdapter->sessionId) &&
5708 (pHddCtx->tdlsConnInfo[staIdx].staId))
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08005709 {
Hoonki Lee11f7dda2013-02-14 16:55:44 -08005710 uint8 *mac;
Gopichand Nakkala4327a152013-03-04 23:22:42 -08005711 mac = pHddCtx->tdlsConnInfo[staIdx].peerMac.bytes;
Hoonki Lee11f7dda2013-02-14 16:55:44 -08005712 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07005713 "%s: call sme_DeleteTdlsPeerSta staId %d sessionId %d " MAC_ADDRESS_STR,
Gopichand Nakkala4327a152013-03-04 23:22:42 -08005714 __func__, pHddCtx->tdlsConnInfo[staIdx].staId, pAdapter->sessionId,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07005715 MAC_ADDR_ARRAY(mac));
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08005716 sme_DeleteTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala4327a152013-03-04 23:22:42 -08005717 pAdapter->sessionId,
5718 mac);
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08005719 }
5720 }
5721#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005722 /*issue disconnect*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305723 status = sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07005724 pAdapter->sessionId, reasonCode);
5725
5726 if ( 0 != status)
5727 {
5728 hddLog(VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305729 "%s csrRoamDisconnect failure, returned %d \n",
Jeff Johnson295189b2012-06-20 16:38:30 -07005730 __func__, (int)status );
5731 return -EINVAL;
5732 }
5733
5734 wait_for_completion_interruptible_timeout(
5735 &pAdapter->disconnect_comp_var,
5736 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
5737
5738
5739 /*stop tx queues*/
5740 netif_tx_disable(dev);
5741 netif_carrier_off(dev);
5742 }
5743 }
5744 else
5745 {
5746 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid roam profile", __func__);
5747 }
5748
5749 return status;
5750}
5751
5752/*
5753 * FUNCTION: wlan_hdd_cfg80211_set_privacy_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305754 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -07005755 * settings in IBSS mode.
5756 */
5757static int wlan_hdd_cfg80211_set_privacy_ibss(
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305758 hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07005759 struct cfg80211_ibss_params *params
5760 )
5761{
5762 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305763 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07005764 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
5765 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305766
Jeff Johnson295189b2012-06-20 16:38:30 -07005767 ENTER();
5768
5769 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
5770
5771 if (params->ie_len && ( NULL != params->ie) )
5772 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305773 if (WLAN_EID_RSN == params->ie[0])
Jeff Johnson295189b2012-06-20 16:38:30 -07005774 {
5775 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
5776 encryptionType = eCSR_ENCRYPT_TYPE_AES;
5777 }
5778 else
5779 {
5780 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
5781 encryptionType = eCSR_ENCRYPT_TYPE_TKIP;
5782 }
5783 status = wlan_hdd_cfg80211_set_ie(pAdapter, params->ie, params->ie_len);
5784
5785 if (0 > status)
5786 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305787 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -07005788 __func__);
5789 return status;
5790 }
5791 }
5792
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305793 pWextState->roamProfile.AuthType.authType[0] =
5794 pHddStaCtx->conn_info.authType =
Jeff Johnson295189b2012-06-20 16:38:30 -07005795 eCSR_AUTH_TYPE_OPEN_SYSTEM;
5796
5797 if (params->privacy)
5798 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305799 /* Security enabled IBSS, At this time there is no information available
5800 * about the security paramters, so initialise the encryption type to
Jeff Johnson295189b2012-06-20 16:38:30 -07005801 * eCSR_ENCRYPT_TYPE_WEP40_STATICKEY.
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305802 * The correct security parameters will be updated later in
Jeff Johnson295189b2012-06-20 16:38:30 -07005803 * wlan_hdd_cfg80211_add_key */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305804 /* Hal expects encryption type to be set inorder
Jeff Johnson295189b2012-06-20 16:38:30 -07005805 *enable privacy bit in beacons */
5806
5807 encryptionType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
5808 }
5809
5810 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
5811 pWextState->roamProfile.EncryptionType.numEntries = 1;
5812 pWextState->roamProfile.EncryptionType.encryptionType[0] = encryptionType;
5813
5814 return status;
5815}
5816
5817/*
5818 * FUNCTION: wlan_hdd_cfg80211_join_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305819 * This function is used to create/join an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -07005820 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305821static int wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07005822 struct net_device *dev,
5823 struct cfg80211_ibss_params *params
5824 )
5825{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305826 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Jeff Johnson295189b2012-06-20 16:38:30 -07005827 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
5828 tCsrRoamProfile *pRoamProfile;
5829 int status;
5830 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
5831
5832 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305833
5834 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -07005835 "%s: device_mode = %d\n",__func__,pAdapter->device_mode);
5836
5837 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
5838 {
5839 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5840 "%s:LOGP in Progress. Ignore!!!", __func__);
5841 return -EAGAIN;
5842 }
5843
5844 if (NULL == pWextState)
5845 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305846 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption\n",
Jeff Johnson295189b2012-06-20 16:38:30 -07005847 __func__);
5848 return -EIO;
5849 }
5850
5851 pRoamProfile = &pWextState->roamProfile;
5852
5853 if ( eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType )
5854 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305855 hddLog (VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07005856 "%s Interface type is not set to IBSS \n", __func__);
5857 return -EINVAL;
5858 }
5859
5860 /* Set Channel */
5861 if (NULL != params->channel)
5862 {
5863 u8 channelNum;
5864 if (IEEE80211_BAND_5GHZ == params->channel->band)
5865 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305866 hddLog(VOS_TRACE_LEVEL_ERROR,
5867 "%s: IBSS join is called with unsupported band %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07005868 __func__, params->channel->band);
5869 return -EOPNOTSUPP;
5870 }
5871
5872 /* Get channel number */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305873 channelNum =
Jeff Johnson295189b2012-06-20 16:38:30 -07005874 ieee80211_frequency_to_channel(params->channel->center_freq);
5875
5876 /*TODO: use macro*/
5877 if (14 >= channelNum)
5878 {
5879 v_U32_t numChans = WNI_CFG_VALID_CHANNEL_LIST_LEN;
5880 v_U8_t validChan[WNI_CFG_VALID_CHANNEL_LIST_LEN];
5881 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
5882 int indx;
5883
5884 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
5885 validChan, &numChans))
5886 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305887 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid channel list",
Jeff Johnson295189b2012-06-20 16:38:30 -07005888 __func__);
5889 return -EOPNOTSUPP;
5890 }
5891
5892 for (indx = 0; indx < numChans; indx++)
5893 {
5894 if (channelNum == validChan[indx])
5895 {
5896 break;
5897 }
5898 }
5899 if (indx >= numChans)
5900 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305901 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Not valid Channel %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07005902 __func__, channelNum);
5903 return -EINVAL;
5904 }
5905 /* Set the Operational Channel */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305906 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: set channel %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07005907 channelNum);
5908 pRoamProfile->ChannelInfo.numOfChannels = 1;
5909 pHddStaCtx->conn_info.operationChannel = channelNum;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305910 pRoamProfile->ChannelInfo.ChannelList =
Jeff Johnson295189b2012-06-20 16:38:30 -07005911 &pHddStaCtx->conn_info.operationChannel;
5912 }
5913 else
5914 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305915 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Not valid Channel %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07005916 __func__, channelNum);
5917 return -EINVAL;
5918 }
5919 }
5920
5921 /* Initialize security parameters */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305922 status = wlan_hdd_cfg80211_set_privacy_ibss(pAdapter, params);
Jeff Johnson295189b2012-06-20 16:38:30 -07005923 if (status < 0)
5924 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305925 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security parameters",
Jeff Johnson295189b2012-06-20 16:38:30 -07005926 __func__);
5927 return status;
5928 }
5929
5930 /* Issue connect start */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305931 status = wlan_hdd_cfg80211_connect_start(pAdapter, params->ssid,
Jeff Johnson32d95a32012-09-10 13:15:23 -07005932 params->ssid_len, params->bssid, 0);
Jeff Johnson295189b2012-06-20 16:38:30 -07005933
5934 if (0 > status)
5935 {
5936 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: connect failed", __func__);
5937 return status;
5938 }
5939
5940 return 0;
5941}
5942
5943/*
5944 * FUNCTION: wlan_hdd_cfg80211_leave_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305945 * This function is used to leave an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -07005946 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305947static int wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07005948 struct net_device *dev
5949 )
5950{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305951 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Jeff Johnson295189b2012-06-20 16:38:30 -07005952 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
5953 tCsrRoamProfile *pRoamProfile;
5954
5955 ENTER();
5956
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005957 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
5958 {
5959 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5960 "%s:LOGP in Progress. Ignore!!!", __func__);
5961 return -EAGAIN;
5962 }
5963
Jeff Johnson295189b2012-06-20 16:38:30 -07005964 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",__func__,pAdapter->device_mode);
5965 if (NULL == pWextState)
5966 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305967 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption\n",
Jeff Johnson295189b2012-06-20 16:38:30 -07005968 __func__);
5969 return -EIO;
5970 }
5971
5972 pRoamProfile = &pWextState->roamProfile;
5973
5974 /* Issue disconnect only if interface type is set to IBSS */
5975 if (eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType)
5976 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305977 hddLog (VOS_TRACE_LEVEL_ERROR, "%s: BSS Type is not set to IBSS",
Jeff Johnson295189b2012-06-20 16:38:30 -07005978 __func__);
5979 return -EINVAL;
5980 }
5981
5982 /* Issue Disconnect request */
5983 INIT_COMPLETION(pAdapter->disconnect_comp_var);
5984 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
5985 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
5986
5987 return 0;
5988}
5989
5990/*
5991 * FUNCTION: wlan_hdd_cfg80211_set_wiphy_params
5992 * This function is used to set the phy parameters
5993 * (RTS Threshold/FRAG Threshold/Retry Count etc ...)
5994 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305995static int wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07005996 u32 changed)
5997{
5998 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5999 tHalHandle hHal = pHddCtx->hHal;
6000
6001 ENTER();
6002
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006003 if ( pHddCtx->isLogpInProgress )
6004 {
6005 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6006 "%s:LOGP in Progress. Ignore!!!", __func__);
6007 return -EAGAIN;
6008 }
6009
Jeff Johnson295189b2012-06-20 16:38:30 -07006010 if (changed & WIPHY_PARAM_RTS_THRESHOLD)
6011 {
6012 u16 rts_threshold = (wiphy->rts_threshold == -1) ?
6013 WNI_CFG_RTS_THRESHOLD_STAMAX :
6014 wiphy->rts_threshold;
6015
6016 if ((WNI_CFG_RTS_THRESHOLD_STAMIN > rts_threshold) ||
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306017 (WNI_CFG_RTS_THRESHOLD_STAMAX < rts_threshold))
Jeff Johnson295189b2012-06-20 16:38:30 -07006018 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306019 hddLog(VOS_TRACE_LEVEL_ERROR,
6020 "%s: Invalid RTS Threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07006021 __func__, rts_threshold);
6022 return -EINVAL;
6023 }
6024
6025 if (0 != ccmCfgSetInt(hHal, WNI_CFG_RTS_THRESHOLD,
6026 rts_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306027 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -07006028 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306029 hddLog(VOS_TRACE_LEVEL_ERROR,
6030 "%s: ccmCfgSetInt failed for rts_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07006031 __func__, rts_threshold);
6032 return -EIO;
6033 }
6034
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306035 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set rts threshold %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07006036 rts_threshold);
6037 }
6038
6039 if (changed & WIPHY_PARAM_FRAG_THRESHOLD)
6040 {
6041 u16 frag_threshold = (wiphy->frag_threshold == -1) ?
6042 WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX :
6043 wiphy->frag_threshold;
6044
6045 if ((WNI_CFG_FRAGMENTATION_THRESHOLD_STAMIN > frag_threshold)||
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306046 (WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX < frag_threshold) )
Jeff Johnson295189b2012-06-20 16:38:30 -07006047 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306048 hddLog(VOS_TRACE_LEVEL_ERROR,
6049 "%s: Invalid frag_threshold value %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07006050 frag_threshold);
6051 return -EINVAL;
6052 }
6053
6054 if (0 != ccmCfgSetInt(hHal, WNI_CFG_FRAGMENTATION_THRESHOLD,
6055 frag_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306056 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -07006057 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306058 hddLog(VOS_TRACE_LEVEL_ERROR,
6059 "%s: ccmCfgSetInt failed for frag_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07006060 __func__, frag_threshold);
6061 return -EIO;
6062 }
6063
6064 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set frag threshold %hu", __func__,
6065 frag_threshold);
6066 }
6067
6068 if ((changed & WIPHY_PARAM_RETRY_SHORT)
6069 || (changed & WIPHY_PARAM_RETRY_LONG))
6070 {
6071 u8 retry_value = (changed & WIPHY_PARAM_RETRY_SHORT) ?
6072 wiphy->retry_short :
6073 wiphy->retry_long;
6074
6075 if ((WNI_CFG_LONG_RETRY_LIMIT_STAMIN > retry_value) ||
6076 (WNI_CFG_LONG_RETRY_LIMIT_STAMAX < retry_value))
6077 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306078 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07006079 __func__, retry_value);
6080 return -EINVAL;
6081 }
6082
6083 if (changed & WIPHY_PARAM_RETRY_SHORT)
6084 {
6085 if (0 != ccmCfgSetInt(hHal, WNI_CFG_LONG_RETRY_LIMIT,
6086 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306087 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -07006088 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306089 hddLog(VOS_TRACE_LEVEL_ERROR,
6090 "%s: ccmCfgSetInt failed for long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07006091 __func__, retry_value);
6092 return -EIO;
6093 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306094 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07006095 __func__, retry_value);
6096 }
6097 else if (changed & WIPHY_PARAM_RETRY_SHORT)
6098 {
6099 if (0 != ccmCfgSetInt(hHal, WNI_CFG_SHORT_RETRY_LIMIT,
6100 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306101 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -07006102 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306103 hddLog(VOS_TRACE_LEVEL_ERROR,
6104 "%s: ccmCfgSetInt failed for short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07006105 __func__, retry_value);
6106 return -EIO;
6107 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306108 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07006109 __func__, retry_value);
6110 }
6111 }
6112
6113 return 0;
6114}
6115
6116/*
6117 * FUNCTION: wlan_hdd_cfg80211_set_txpower
6118 * This function is used to set the txpower
6119 */
6120static int wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
6121#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306122 enum tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -07006123#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306124 enum nl80211_tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -07006125#endif
6126 int dbm)
6127{
6128 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
6129 tHalHandle hHal = pHddCtx->hHal;
6130 tSirMacAddr bssid = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
6131 tSirMacAddr selfMac = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
6132
6133 ENTER();
6134
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306135 if (0 != ccmCfgSetInt(hHal, WNI_CFG_CURRENT_TX_POWER_LEVEL,
6136 dbm, ccmCfgSetCallback,
6137 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -07006138 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306139 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07006140 "%s: ccmCfgSetInt failed for tx power %hu", __func__, dbm);
6141 return -EIO;
6142 }
6143
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006144 if ( pHddCtx->isLogpInProgress )
6145 {
6146 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6147 "%s:LOGP in Progress. Ignore!!!", __func__);
6148 return -EAGAIN;
6149 }
6150
Jeff Johnson295189b2012-06-20 16:38:30 -07006151 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set tx power level %d dbm", __func__,
6152 dbm);
6153
6154 switch(type)
6155 {
6156 case NL80211_TX_POWER_AUTOMATIC: /*automatically determine transmit power*/
6157 /* Fall through */
6158 case NL80211_TX_POWER_LIMITED: /*limit TX power by the mBm parameter*/
6159 if( sme_SetMaxTxPower(hHal, bssid, selfMac, dbm) != eHAL_STATUS_SUCCESS )
6160 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306161 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Setting maximum tx power failed",
6162 __func__);
6163 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -07006164 }
6165 break;
6166 case NL80211_TX_POWER_FIXED: /*fix TX power to the mBm parameter*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306167 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: NL80211_TX_POWER_FIXED not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -07006168 __func__);
6169 return -EOPNOTSUPP;
6170 break;
6171 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306172 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid power setting type %d",
6173 __func__, type);
Jeff Johnson295189b2012-06-20 16:38:30 -07006174 return -EIO;
6175 }
6176
6177 return 0;
6178}
6179
6180/*
6181 * FUNCTION: wlan_hdd_cfg80211_get_txpower
6182 * This function is used to read the txpower
6183 */
6184static int wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy, int *dbm)
6185{
6186
6187 hdd_adapter_t *pAdapter;
6188 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
6189
Jeff Johnsone7245742012-09-05 17:12:55 -07006190 ENTER();
6191
Jeff Johnson295189b2012-06-20 16:38:30 -07006192 if (NULL == pHddCtx)
6193 {
6194 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD context is Null",__func__);
6195 *dbm = 0;
6196 return -ENOENT;
6197 }
6198
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006199 if ( pHddCtx->isLogpInProgress )
6200 {
6201 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6202 "%s:LOGP in Progress. Ignore!!!", __func__);
6203 return -EAGAIN;
6204 }
6205
Jeff Johnson295189b2012-06-20 16:38:30 -07006206 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
6207 if (NULL == pAdapter)
6208 {
6209 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Not in station context " ,__func__);
6210 return -ENOENT;
6211 }
6212
6213 wlan_hdd_get_classAstats(pAdapter);
6214 *dbm = pAdapter->hdd_stats.ClassA_stat.max_pwr;
6215
Jeff Johnsone7245742012-09-05 17:12:55 -07006216 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07006217 return 0;
6218}
6219
6220static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
6221 u8* mac, struct station_info *sinfo)
6222{
6223 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
6224 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6225 int ssidlen = pHddStaCtx->conn_info.SSID.SSID.length;
6226 tANI_U8 rate_flags;
6227
6228 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
6229 hdd_config_t *pCfg = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -07006230
6231 tANI_U8 OperationalRates[CSR_DOT11_SUPPORTED_RATES_MAX];
6232 tANI_U32 ORLeng = CSR_DOT11_SUPPORTED_RATES_MAX;
6233 tANI_U8 ExtendedRates[CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX];
6234 tANI_U32 ERLeng = CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX;
6235 tANI_U8 MCSRates[SIZE_OF_BASIC_MCS_SET];
6236 tANI_U32 MCSLeng = SIZE_OF_BASIC_MCS_SET;
6237 tANI_U16 maxRate = 0;
6238 tANI_U16 myRate;
6239 tANI_U16 currentRate = 0;
6240 tANI_U8 maxSpeedMCS = 0;
6241 tANI_U8 maxMCSIdx = 0;
6242 tANI_U8 rateFlag = 1;
6243 tANI_U8 i, j, rssidx;
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07006244 tANI_U16 temp;
Jeff Johnson295189b2012-06-20 16:38:30 -07006245
Leo Chang6f8870f2013-03-26 18:11:36 -07006246#ifdef WLAN_FEATURE_11AC
6247 tANI_U32 vht_mcs_map;
6248 eDataRate11ACMaxMcs vhtMaxMcs;
6249#endif /* WLAN_FEATURE_11AC */
6250
Jeff Johnsone7245742012-09-05 17:12:55 -07006251 ENTER();
6252
Jeff Johnson295189b2012-06-20 16:38:30 -07006253 if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) ||
6254 (0 == ssidlen))
6255 {
6256 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Not associated or"
6257 " Invalid ssidlen, %d", __func__, ssidlen);
6258 /*To keep GUI happy*/
6259 return 0;
6260 }
6261
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006262 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
6263 {
6264 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6265 "%s:LOGP in Progress. Ignore!!!", __func__);
6266 return -EAGAIN;
6267 }
6268
Jeff Johnson295189b2012-06-20 16:38:30 -07006269 wlan_hdd_get_rssi(pAdapter, &sinfo->signal);
6270 sinfo->filled |= STATION_INFO_SIGNAL;
6271
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -07006272 wlan_hdd_get_station_stats(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07006273 rate_flags = pAdapter->hdd_stats.ClassA_stat.tx_rate_flags;
6274
6275 //convert to the UI units of 100kbps
6276 myRate = pAdapter->hdd_stats.ClassA_stat.tx_rate * 5;
6277
6278#ifdef LINKSPEED_DEBUG_ENABLED
Leo Chang6f8870f2013-03-26 18:11:36 -07006279 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 -07006280 sinfo->signal,
6281 pCfg->reportMaxLinkSpeed,
6282 myRate,
6283 (int) pCfg->linkSpeedRssiHigh,
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07006284 (int) pCfg->linkSpeedRssiMid,
6285 (int) pCfg->linkSpeedRssiLow,
Leo Chang6f8870f2013-03-26 18:11:36 -07006286 (int) rate_flags,
6287 (int) pAdapter->hdd_stats.ClassA_stat.mcs_index);
Jeff Johnson295189b2012-06-20 16:38:30 -07006288#endif //LINKSPEED_DEBUG_ENABLED
6289
6290 if (eHDD_LINK_SPEED_REPORT_ACTUAL != pCfg->reportMaxLinkSpeed)
6291 {
6292 // we do not want to necessarily report the current speed
6293 if (eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed)
6294 {
6295 // report the max possible speed
6296 rssidx = 0;
6297 }
6298 else if (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed)
6299 {
6300 // report the max possible speed with RSSI scaling
6301 if (sinfo->signal >= pCfg->linkSpeedRssiHigh)
6302 {
6303 // report the max possible speed
6304 rssidx = 0;
6305 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07006306 else if (sinfo->signal >= pCfg->linkSpeedRssiMid)
Jeff Johnson295189b2012-06-20 16:38:30 -07006307 {
6308 // report middle speed
6309 rssidx = 1;
6310 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07006311 else if (sinfo->signal >= pCfg->linkSpeedRssiLow)
6312 {
6313 // report middle speed
6314 rssidx = 2;
6315 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006316 else
6317 {
6318 // report actual speed
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07006319 rssidx = 3;
Jeff Johnson295189b2012-06-20 16:38:30 -07006320 }
6321 }
6322 else
6323 {
6324 // unknown, treat as eHDD_LINK_SPEED_REPORT_MAX
6325 hddLog(VOS_TRACE_LEVEL_ERROR,
6326 "%s: Invalid value for reportMaxLinkSpeed: %u",
6327 __func__, pCfg->reportMaxLinkSpeed);
6328 rssidx = 0;
6329 }
6330
6331 maxRate = 0;
6332
6333 /* Get Basic Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +05306334 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_OPERATIONAL_RATE_SET,
6335 OperationalRates, &ORLeng))
6336 {
6337 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
6338 /*To keep GUI happy*/
6339 return 0;
6340 }
6341
Jeff Johnson295189b2012-06-20 16:38:30 -07006342 for (i = 0; i < ORLeng; i++)
6343 {
Jeff Johnsone7245742012-09-05 17:12:55 -07006344 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -07006345 {
6346 /* Validate Rate Set */
6347 if (supported_data_rate[j].beacon_rate_index == (OperationalRates[i] & 0x7F))
6348 {
6349 currentRate = supported_data_rate[j].supported_rate[rssidx];
6350 break;
6351 }
6352 }
6353 /* Update MAX rate */
6354 maxRate = (currentRate > maxRate)?currentRate:maxRate;
6355 }
6356
6357 /* Get Extended Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +05306358 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET,
6359 ExtendedRates, &ERLeng))
6360 {
6361 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
6362 /*To keep GUI happy*/
6363 return 0;
6364 }
6365
Jeff Johnson295189b2012-06-20 16:38:30 -07006366 for (i = 0; i < ERLeng; i++)
6367 {
Jeff Johnsone7245742012-09-05 17:12:55 -07006368 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -07006369 {
6370 if (supported_data_rate[j].beacon_rate_index == (ExtendedRates[i] & 0x7F))
6371 {
6372 currentRate = supported_data_rate[j].supported_rate[rssidx];
6373 break;
6374 }
6375 }
6376 /* Update MAX rate */
6377 maxRate = (currentRate > maxRate)?currentRate:maxRate;
6378 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006379 /* Get MCS Rate Set -- but only if we are connected at MCS
6380 rates or if we are always reporting max speed or if we have
6381 good rssi */
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07006382 if ((0 == rssidx) && !(rate_flags & eHAL_TX_RATE_LEGACY))
Jeff Johnson295189b2012-06-20 16:38:30 -07006383 {
Gopichand Nakkala05ab1322013-02-15 11:28:38 +05306384 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_CURRENT_MCS_SET,
6385 MCSRates, &MCSLeng))
6386 {
6387 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
6388 /*To keep GUI happy*/
6389 return 0;
6390 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006391 rateFlag = 0;
Leo Chang6f8870f2013-03-26 18:11:36 -07006392#ifdef WLAN_FEATURE_11AC
6393 /* VHT80 rate has seperate rate table */
Gopichand Nakkala4c705372013-04-24 13:20:33 +05306394 if (rate_flags & (eHAL_TX_RATE_VHT20|eHAL_TX_RATE_VHT40|eHAL_TX_RATE_VHT80))
Jeff Johnson295189b2012-06-20 16:38:30 -07006395 {
Leo Chang6f8870f2013-03-26 18:11:36 -07006396 ccmCfgGetInt(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_VHT_TX_MCS_MAP, &vht_mcs_map);
Gopichand Nakkala4c705372013-04-24 13:20:33 +05306397 vhtMaxMcs = (eDataRate11ACMaxMcs)(vht_mcs_map & DATA_RATE_11AC_MCS_MASK );
Leo Chang6f8870f2013-03-26 18:11:36 -07006398 if (rate_flags & eHAL_TX_RATE_SGI)
Jeff Johnson295189b2012-06-20 16:38:30 -07006399 {
Leo Chang6f8870f2013-03-26 18:11:36 -07006400 rateFlag |= 1;
Jeff Johnson295189b2012-06-20 16:38:30 -07006401 }
Leo Chang6f8870f2013-03-26 18:11:36 -07006402 if (DATA_RATE_11AC_MAX_MCS_7 == vhtMaxMcs)
Jeff Johnson295189b2012-06-20 16:38:30 -07006403 {
Leo Chang6f8870f2013-03-26 18:11:36 -07006404 maxMCSIdx = 7;
6405 }
6406 else if (DATA_RATE_11AC_MAX_MCS_8 == vhtMaxMcs)
6407 {
6408 maxMCSIdx = 8;
6409 }
6410 else if (DATA_RATE_11AC_MAX_MCS_9 == vhtMaxMcs)
6411 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +05306412 //VHT20 is supporting 0~8
6413 if (rate_flags & eHAL_TX_RATE_VHT20)
6414 maxMCSIdx = 8;
6415 else
6416 maxMCSIdx = 9;
Leo Chang6f8870f2013-03-26 18:11:36 -07006417 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +05306418
6419 if (rate_flags & eHAL_TX_RATE_VHT80)
6420 {
6421 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT80_rate[rateFlag];
6422 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT80_rate[rateFlag];
6423 }
6424 else if (rate_flags & eHAL_TX_RATE_VHT40)
6425 {
6426 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT40_rate[rateFlag];
6427 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT40_rate[rateFlag];
6428 }
6429 else if (rate_flags & eHAL_TX_RATE_VHT20)
6430 {
6431 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT20_rate[rateFlag];
6432 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT20_rate[rateFlag];
6433 }
6434
Leo Chang6f8870f2013-03-26 18:11:36 -07006435 maxSpeedMCS = 1;
6436 if (currentRate > maxRate)
6437 {
6438 maxRate = currentRate;
6439 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +05306440
Leo Chang6f8870f2013-03-26 18:11:36 -07006441 }
6442 else
6443#endif /* WLAN_FEATURE_11AC */
6444 {
6445 if (rate_flags & eHAL_TX_RATE_HT40)
6446 {
6447 rateFlag |= 1;
6448 }
6449 if (rate_flags & eHAL_TX_RATE_SGI)
6450 {
6451 rateFlag |= 2;
6452 }
6453
6454 for (i = 0; i < MCSLeng; i++)
6455 {
6456 temp = sizeof(supported_mcs_rate) / sizeof(supported_mcs_rate[0]);
6457 for (j = 0; j < temp; j++)
6458 {
6459 if (supported_mcs_rate[j].beacon_rate_index == MCSRates[i])
6460 {
6461 currentRate = supported_mcs_rate[j].supported_rate[rateFlag];
6462 break;
6463 }
6464 }
6465 if ((j < temp) && (currentRate > maxRate))
6466 {
6467 maxRate = currentRate;
6468 maxSpeedMCS = 1;
6469 maxMCSIdx = supported_mcs_rate[j].beacon_rate_index;
6470 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006471 }
6472 }
6473 }
6474
Gopichand Nakkala4c705372013-04-24 13:20:33 +05306475 else if (!(rate_flags & eHAL_TX_RATE_LEGACY))
6476 {
6477 maxRate = myRate;
6478 maxSpeedMCS = 1;
6479 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
6480 }
6481
Jeff Johnson295189b2012-06-20 16:38:30 -07006482 // make sure we report a value at least as big as our current rate
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07006483 if (((maxRate < myRate) && (0 == rssidx)) ||
6484 (0 == maxRate))
Jeff Johnson295189b2012-06-20 16:38:30 -07006485 {
6486 maxRate = myRate;
6487 if (rate_flags & eHAL_TX_RATE_LEGACY)
6488 {
6489 maxSpeedMCS = 0;
6490 }
6491 else
6492 {
6493 maxSpeedMCS = 1;
6494 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
6495 }
6496 }
6497
Gopichand Nakkala4c705372013-04-24 13:20:33 +05306498 if (rate_flags & eHAL_TX_RATE_LEGACY)
Jeff Johnson295189b2012-06-20 16:38:30 -07006499 {
6500 sinfo->txrate.legacy = maxRate;
6501#ifdef LINKSPEED_DEBUG_ENABLED
6502 pr_info("Reporting legacy rate %d\n", sinfo->txrate.legacy);
6503#endif //LINKSPEED_DEBUG_ENABLED
6504 }
6505 else
6506 {
6507 sinfo->txrate.mcs = maxMCSIdx;
Leo Chang6f8870f2013-03-26 18:11:36 -07006508#ifdef WLAN_FEATURE_11AC
6509 sinfo->txrate.nss = 1;
6510 if (rate_flags & eHAL_TX_RATE_VHT80)
6511 {
6512 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
Gopichand Nakkala4c705372013-04-24 13:20:33 +05306513 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
Leo Chang6f8870f2013-03-26 18:11:36 -07006514 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +05306515 else if (rate_flags & eHAL_TX_RATE_VHT40)
Leo Chang6f8870f2013-03-26 18:11:36 -07006516 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +05306517 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
6518 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
6519 }
6520 else if (rate_flags & eHAL_TX_RATE_VHT20)
6521 {
6522 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
6523 }
6524#endif /* WLAN_FEATURE_11AC */
6525 if (rate_flags & (eHAL_TX_RATE_HT20 | eHAL_TX_RATE_HT40))
6526 {
6527 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
6528 if (rate_flags & eHAL_TX_RATE_HT40)
6529 {
6530 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
6531 }
Leo Chang6f8870f2013-03-26 18:11:36 -07006532 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006533 if (rate_flags & eHAL_TX_RATE_SGI)
6534 {
6535 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
6536 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +05306537
Jeff Johnson295189b2012-06-20 16:38:30 -07006538#ifdef LINKSPEED_DEBUG_ENABLED
6539 pr_info("Reporting MCS rate %d flags %x\n",
6540 sinfo->txrate.mcs,
6541 sinfo->txrate.flags );
6542#endif //LINKSPEED_DEBUG_ENABLED
6543 }
6544 }
6545 else
6546 {
6547 // report current rate instead of max rate
6548
6549 if (rate_flags & eHAL_TX_RATE_LEGACY)
6550 {
6551 //provide to the UI in units of 100kbps
6552 sinfo->txrate.legacy = myRate;
6553#ifdef LINKSPEED_DEBUG_ENABLED
6554 pr_info("Reporting actual legacy rate %d\n", sinfo->txrate.legacy);
6555#endif //LINKSPEED_DEBUG_ENABLED
6556 }
6557 else
6558 {
6559 //must be MCS
6560 sinfo->txrate.mcs = pAdapter->hdd_stats.ClassA_stat.mcs_index;
Leo Chang6f8870f2013-03-26 18:11:36 -07006561#ifdef WLAN_FEATURE_11AC
6562 sinfo->txrate.nss = 1;
6563 if (rate_flags & eHAL_TX_RATE_VHT80)
6564 {
6565 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
6566 }
6567 else
6568#endif /* WLAN_FEATURE_11AC */
6569 {
6570 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
6571 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006572 if (rate_flags & eHAL_TX_RATE_SGI)
6573 {
6574 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
6575 }
6576 if (rate_flags & eHAL_TX_RATE_HT40)
6577 {
6578 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
6579 }
Leo Chang6f8870f2013-03-26 18:11:36 -07006580#ifdef WLAN_FEATURE_11AC
6581 else if (rate_flags & eHAL_TX_RATE_VHT80)
6582 {
6583 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
6584 }
6585#endif /* WLAN_FEATURE_11AC */
Jeff Johnson295189b2012-06-20 16:38:30 -07006586#ifdef LINKSPEED_DEBUG_ENABLED
6587 pr_info("Reporting actual MCS rate %d flags %x\n",
6588 sinfo->txrate.mcs,
6589 sinfo->txrate.flags );
6590#endif //LINKSPEED_DEBUG_ENABLED
6591 }
6592 }
6593 sinfo->filled |= STATION_INFO_TX_BITRATE;
6594
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -07006595 sinfo->tx_packets =
6596 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[0] +
6597 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[1] +
6598 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[2] +
6599 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[3];
6600
6601 sinfo->tx_retries =
6602 pAdapter->hdd_stats.summary_stat.retry_cnt[0] +
6603 pAdapter->hdd_stats.summary_stat.retry_cnt[1] +
6604 pAdapter->hdd_stats.summary_stat.retry_cnt[2] +
6605 pAdapter->hdd_stats.summary_stat.retry_cnt[3];
6606
6607 sinfo->tx_failed =
6608 pAdapter->hdd_stats.summary_stat.fail_cnt[0] +
6609 pAdapter->hdd_stats.summary_stat.fail_cnt[1] +
6610 pAdapter->hdd_stats.summary_stat.fail_cnt[2] +
6611 pAdapter->hdd_stats.summary_stat.fail_cnt[3];
6612
6613 sinfo->filled |=
6614 STATION_INFO_TX_PACKETS |
6615 STATION_INFO_TX_RETRIES |
6616 STATION_INFO_TX_FAILED;
6617
6618 EXIT();
6619 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07006620}
6621
6622static int wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
6623 struct net_device *dev, bool mode, v_SINT_t timeout)
6624{
6625 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +05306626 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07006627 VOS_STATUS vos_status;
6628
Jeff Johnsone7245742012-09-05 17:12:55 -07006629 ENTER();
6630
Jeff Johnson295189b2012-06-20 16:38:30 -07006631 if (NULL == pAdapter)
6632 {
6633 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL\n", __func__);
6634 return -ENODEV;
6635 }
6636
Gopichand Nakkala20c4c042013-04-19 22:08:55 +05306637 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
6638 if (NULL == pHddCtx)
6639 {
6640 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: HDD context is NULL\n", __func__);
6641 return -ENODEV;
6642 }
6643
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306644 if ( pHddCtx->isLogpInProgress )
6645 {
6646 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6647 "%s:LOGP in Progress. Ignore!!!", __func__);
6648 return -EAGAIN;
6649 }
6650
Gopichand Nakkala20c4c042013-04-19 22:08:55 +05306651 if ((DRIVER_POWER_MODE_AUTO == !mode) &&
6652 (TRUE == pHddCtx->hdd_wlan_suspended) &&
6653 (pHddCtx->cfg_ini->fhostArpOffload) &&
6654 (eConnectionState_Associated ==
6655 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
6656 {
6657 vos_status = hdd_conf_hostarpoffload(pAdapter, TRUE);
6658 if (!VOS_IS_STATUS_SUCCESS(vos_status))
6659 {
6660 hddLog(VOS_TRACE_LEVEL_INFO,
6661 "%s:Failed to enable ARPOFFLOAD Feature %d\n",
6662 __func__, vos_status);
6663 }
6664 }
6665
Jeff Johnson295189b2012-06-20 16:38:30 -07006666 /**The get power cmd from the supplicant gets updated by the nl only
6667 *on successful execution of the function call
6668 *we are oppositely mapped w.r.t mode in the driver
6669 **/
6670 vos_status = wlan_hdd_enter_bmps(pAdapter, !mode);
6671
Jeff Johnsone7245742012-09-05 17:12:55 -07006672 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07006673 if (VOS_STATUS_E_FAILURE == vos_status)
6674 {
6675 return -EINVAL;
6676 }
6677 return 0;
6678}
6679
6680
6681#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
6682static int wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
6683 struct net_device *netdev,
6684 u8 key_index)
6685{
Jeff Johnsone7245742012-09-05 17:12:55 -07006686 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07006687 return 0;
6688}
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306689#endif //LINUX_VERSION_CODE
Jeff Johnson295189b2012-06-20 16:38:30 -07006690
6691#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
6692static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
6693 struct net_device *dev,
6694 struct ieee80211_txq_params *params)
6695{
Jeff Johnsone7245742012-09-05 17:12:55 -07006696 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07006697 return 0;
6698}
6699#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
6700static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
6701 struct ieee80211_txq_params *params)
6702{
Jeff Johnsone7245742012-09-05 17:12:55 -07006703 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07006704 return 0;
6705}
6706#endif //LINUX_VERSION_CODE
6707
6708static int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
6709 struct net_device *dev, u8 *mac)
6710{
6711 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08006712 VOS_STATUS vos_status;
6713 v_U8_t staId;
Jeff Johnson295189b2012-06-20 16:38:30 -07006714
Jeff Johnsone7245742012-09-05 17:12:55 -07006715 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07006716 if ( NULL == pAdapter || NULL == pAdapter->pHddCtx)
6717 {
6718 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Invalid Adapter or HDD Context " ,__func__);
6719 return -EINVAL;
6720 }
6721
6722 if (((hdd_context_t*)pAdapter->pHddCtx)->isLoadUnloadInProgress)
6723 {
6724 hddLog( LOGE,
6725 "%s: Wlan Load/Unload is in progress", __func__);
6726 return -EBUSY;
6727 }
6728
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006729 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
6730 {
6731 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6732 "%s:LOGP in Progress. Ignore!!!", __func__);
6733 return -EAGAIN;
6734 }
6735
Jeff Johnson295189b2012-06-20 16:38:30 -07006736 if ( (WLAN_HDD_SOFTAP == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -07006737 || (WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -07006738 )
6739 {
6740 if( NULL == mac )
6741 {
6742 v_U16_t i;
6743 for(i = 0; i < WLAN_MAX_STA_COUNT; i++)
6744 {
6745 if(pAdapter->aStaInfo[i].isUsed)
6746 {
6747 u8 *macAddr = pAdapter->aStaInfo[i].macAddrSTA.bytes;
6748 hddLog(VOS_TRACE_LEVEL_INFO,
6749 "%s: Delete STA with MAC::"
6750 "%02x:%02x:%02x:%02x:%02x:%02x",
6751 __func__,
6752 macAddr[0], macAddr[1], macAddr[2],
6753 macAddr[3], macAddr[4], macAddr[5]);
6754 hdd_softap_sta_deauth(pAdapter, macAddr);
6755 }
6756 }
6757 }
6758 else
6759 {
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08006760
6761 vos_status = hdd_softap_GetStaId(pAdapter,(v_MACADDR_t *)mac, &staId);
6762 if (!VOS_IS_STATUS_SUCCESS(vos_status))
6763 {
6764 hddLog(VOS_TRACE_LEVEL_INFO,
6765 "%s: Skip this DEL STA as this is not used::"
6766 "%02x:%02x:%02x:%02x:%02x:%02x",
6767 __func__,
6768 mac[0], mac[1], mac[2],
6769 mac[3], mac[4], mac[5]);
6770 return -ENOENT;
6771 }
6772
6773 if( pAdapter->aStaInfo[staId].isDeauthInProgress == TRUE)
6774 {
6775 hddLog(VOS_TRACE_LEVEL_INFO,
6776 "%s: Skip this DEL STA as deauth is in progress::"
6777 "%02x:%02x:%02x:%02x:%02x:%02x",
6778 __func__,
6779 mac[0], mac[1], mac[2],
6780 mac[3], mac[4], mac[5]);
6781 return -ENOENT;
6782 }
6783
6784 pAdapter->aStaInfo[staId].isDeauthInProgress = TRUE;
6785
Jeff Johnson295189b2012-06-20 16:38:30 -07006786 hddLog(VOS_TRACE_LEVEL_INFO,
6787 "%s: Delete STA with MAC::"
6788 "%02x:%02x:%02x:%02x:%02x:%02x",
6789 __func__,
6790 mac[0], mac[1], mac[2],
6791 mac[3], mac[4], mac[5]);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08006792
6793 vos_status = hdd_softap_sta_deauth(pAdapter, mac);
6794 if (!VOS_IS_STATUS_SUCCESS(vos_status))
6795 {
6796 pAdapter->aStaInfo[staId].isDeauthInProgress = FALSE;
6797 hddLog(VOS_TRACE_LEVEL_INFO,
6798 "%s: STA removal failed for ::"
6799 "%02x:%02x:%02x:%02x:%02x:%02x",
6800 __func__,
6801 mac[0], mac[1], mac[2],
6802 mac[3], mac[4], mac[5]);
6803 return -ENOENT;
6804 }
6805
Jeff Johnson295189b2012-06-20 16:38:30 -07006806 }
6807 }
6808
6809 EXIT();
6810
6811 return 0;
6812}
6813
Hoonki Lee11f7dda2013-02-14 16:55:44 -08006814static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
6815 struct net_device *dev, u8 *mac, struct station_parameters *params)
6816{
Gopichand Nakkalab977a972013-02-18 19:15:09 -08006817 int status = -EPERM;
Hoonki Lee11f7dda2013-02-14 16:55:44 -08006818#ifdef FEATURE_WLAN_TDLS
6819 u32 mask, set;
Hoonki Lee11f7dda2013-02-14 16:55:44 -08006820 ENTER();
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006821 mask = params->sta_flags_mask;
6822
6823 set = params->sta_flags_set;
6824
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07006825#ifdef WLAN_FEATURE_TDLS_DEBUG
6826 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6827 "%s: mask 0x%x set 0x%x " MAC_ADDRESS_STR,
6828 __func__, mask, set, MAC_ADDR_ARRAY(mac));
6829#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006830
6831 if (mask & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
6832 if (set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006833 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 0, NULL);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006834 }
6835 }
6836#endif
Gopichand Nakkalab977a972013-02-18 19:15:09 -08006837 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -07006838}
6839
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006840
6841#ifdef FEATURE_WLAN_LFR
6842static int wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
Jeff Johnsond13512a2012-07-17 11:42:19 -07006843 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006844{
6845#define MAX_PMKSAIDS_IN_CACHE 8
6846 static tPmkidCacheInfo PMKIDCache[MAX_PMKSAIDS_IN_CACHE]; // HDD Local cache
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306847 static tANI_U32 i; // HDD Local Cache index
6848 tANI_U32 j=0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006849 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6850 tHalHandle halHandle;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306851 eHalStatus result;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006852 tANI_U8 BSSIDMatched = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306853
Jeff Johnsone7245742012-09-05 17:12:55 -07006854 ENTER();
6855
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306856 // Validate pAdapter
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006857 if ( NULL == pAdapter || NULL == pAdapter->pHddCtx)
6858 {
6859 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Invalid Adapter or HDD Context " ,__func__);
6860 return -EINVAL;
6861 }
6862
6863 if (((hdd_context_t*)pAdapter->pHddCtx)->isLoadUnloadInProgress)
6864 {
6865 hddLog( LOGE,
6866 "%s: Wlan Load/Unload is in progress", __func__);
6867 return -EBUSY;
6868 }
6869
6870 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
6871 {
6872 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6873 "%s:LOGP in Progress. Ignore!!!", __func__);
6874 return -EAGAIN;
6875 }
6876
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306877 // Retrieve halHandle
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006878 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
6879
6880 for (j = 0; j < i; j++)
6881 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306882 if(vos_mem_compare(PMKIDCache[j].BSSID,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006883 pmksa->bssid, WNI_CFG_BSSID_LEN))
6884 {
6885 /* BSSID matched previous entry. Overwrite it. */
6886 BSSIDMatched = 1;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306887 vos_mem_copy(PMKIDCache[j].BSSID,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006888 pmksa->bssid, WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306889 vos_mem_copy(PMKIDCache[j].PMKID,
6890 pmksa->pmkid,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006891 CSR_RSN_PMKID_SIZE);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306892 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Reusing cache entry %d.",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006893 __func__, j );
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006894 dump_bssid(pmksa->bssid);
6895 dump_pmkid(halHandle, pmksa->pmkid);
6896 break;
6897 }
6898 }
6899
Madan Mohan Koyyalamudic4b317d2012-10-18 19:43:08 -07006900 /* Check we compared all entries,if then take the first slot now */
6901 if(j == MAX_PMKSAIDS_IN_CACHE) i=0;
6902
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006903 if (!BSSIDMatched)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306904 {
6905 // Now, we DON'T have a BSSID match, so take a new entry in the cache.
6906 vos_mem_copy(PMKIDCache[i].BSSID,
6907 pmksa->bssid, ETHER_ADDR_LEN);
6908 vos_mem_copy(PMKIDCache[i].PMKID,
6909 pmksa->pmkid,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006910 CSR_RSN_PMKID_SIZE);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306911 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Adding a new cache entry %d.",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006912 __func__, i );
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006913 dump_bssid(pmksa->bssid);
6914 dump_pmkid(halHandle, pmksa->pmkid);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306915 // Increment the HDD Local Cache index
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006916 // The "i=0" doesn't work for the call to sme_RoamSetPMKIDCache() - LFR FIXME
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306917 if (i<=(MAX_PMKSAIDS_IN_CACHE-1)) i++; else i=0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006918 }
6919
6920
6921 // Calling csrRoamSetPMKIDCache to configure the PMKIDs into the cache
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306922 //hddLog(LOG1, FL("%s: Calling csrRoamSetPMKIDCache with %d cache entries."),
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006923 // __func__, i );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306924 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Calling csrRoamSetPMKIDCache with %d cache entries.",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006925 __func__, i );
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006926 // Finally set the PMKSA ID Cache in CSR
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306927 result = sme_RoamSetPMKIDCache(halHandle,pAdapter->sessionId,
6928 PMKIDCache,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006929 i );
6930 return 0;
6931}
6932
6933
6934static int wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
Jeff Johnsond13512a2012-07-17 11:42:19 -07006935 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006936{
Jeff Johnsone7245742012-09-05 17:12:55 -07006937 ENTER();
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006938 // TODO: Implement this later.
6939 return 0;
6940}
6941
6942static int wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
6943{
Jeff Johnsone7245742012-09-05 17:12:55 -07006944 ENTER();
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006945 // TODO: Implement this later.
6946 return 0;
6947}
6948#endif
6949
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07006950#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306951static int wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07006952 struct net_device *dev, struct cfg80211_update_ft_ies_params *ftie)
6953{
6954 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6955 hdd_station_ctx_t *pHddStaCtx;
6956
6957 if (NULL == pAdapter)
6958 {
6959 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL\n", __func__);
6960 return -ENODEV;
6961 }
6962
6963 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6964
6965 // Added for debug on reception of Re-assoc Req.
6966 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
6967 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306968 hddLog(LOGE, FL("Called with Ie of length = %d when not associated\n"),
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07006969 ftie->ie_len);
6970 hddLog(LOGE, FL("Should be Re-assoc Req IEs\n"));
6971 }
6972
6973#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306974 hddLog(LOGE, FL("%s called with Ie of length = %d\n"), __func__,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07006975 ftie->ie_len);
6976#endif
6977
6978 // Pass the received FT IEs to SME
Gopichand Nakkala356fb102013-03-06 12:34:04 +05306979 sme_SetFTIEs( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
6980 (const u8 *)ftie->ie,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07006981 ftie->ie_len);
6982 return 0;
6983}
6984#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006985
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006986#ifdef FEATURE_WLAN_TDLS
6987static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
6988 u8 *peer, u8 action_code, u8 dialog_token,
6989 u16 status_code, const u8 *buf, size_t len)
6990{
6991
6992 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6993 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006994 u8 peerMac[6];
6995 VOS_STATUS status;
Gopichand Nakkala05922802013-03-14 12:23:19 -07006996 int max_sta_failed = 0;
Hoonki Leea34dd892013-02-05 22:56:02 -08006997 int responder;
Hoonki Leed37cbb32013-04-20 00:31:14 -07006998 long rc;
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006999
Hoonki Lee11f7dda2013-02-14 16:55:44 -08007000 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007001 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307002 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007003 "Invalid arguments");
7004 return -EINVAL;
7005 }
7006
Sameer Thalappil75ea31a2013-02-21 19:38:16 -08007007 if (pHddCtx->isLogpInProgress)
7008 {
7009 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7010 "%s:LOGP in Progress. Ignore!!!", __func__);
Gopichand Nakkala05922802013-03-14 12:23:19 -07007011 wlan_hdd_tdls_set_link_status(pAdapter, peer, eTDLS_LINK_IDLE);
Sameer Thalappil75ea31a2013-02-21 19:38:16 -08007012 return -EBUSY;
7013 }
7014
Hoonki Lee27511902013-03-14 18:19:06 -07007015 if (eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode)
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007016 {
Hoonki Lee27511902013-03-14 18:19:06 -07007017 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
7018 "%s: TDLS mode is disabled OR not enabled in FW."
7019 MAC_ADDRESS_STR " action %d declined.",
7020 __func__, MAC_ADDR_ARRAY(peer), action_code);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007021 return -ENOTSUPP;
7022 }
Lee Hoonkic1262f22013-01-24 21:59:00 -08007023
Hoonki Lee27511902013-03-14 18:19:06 -07007024 /* other than teardown frame, other mgmt frames are not sent if disabled */
7025 if (SIR_MAC_TDLS_TEARDOWN != action_code)
7026 {
7027 /* if tdls_mode is disabled to respond to peer's request */
7028 if (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode)
7029 {
7030 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
7031 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07007032 " TDLS mode is disabled. action %d declined.",
7033 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee27511902013-03-14 18:19:06 -07007034
7035 return -ENOTSUPP;
7036 }
7037 }
7038
Gopichand Nakkalab977a972013-02-18 19:15:09 -08007039 if (WLAN_IS_TDLS_SETUP_ACTION(action_code))
7040 {
Hoonki Leefb8df672013-04-10 18:20:34 -07007041 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, peer, TRUE, TRUE))
Gopichand Nakkalab977a972013-02-18 19:15:09 -08007042 {
7043 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007044 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07007045 " TDLS setup is ongoing. action %d declined.",
7046 __func__, MAC_ADDR_ARRAY(peer), action_code);
7047 return -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -08007048 }
7049 }
7050
Hoonki Lee11f7dda2013-02-14 16:55:44 -08007051 if (SIR_MAC_TDLS_SETUP_REQ == action_code ||
7052 SIR_MAC_TDLS_SETUP_RSP == action_code )
Lee Hoonkic1262f22013-01-24 21:59:00 -08007053 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -08007054 if (HDD_MAX_NUM_TDLS_STA <= wlan_hdd_tdlsConnectedPeers(pAdapter))
Lee Hoonkic1262f22013-01-24 21:59:00 -08007055 {
7056 /* supplicant still sends tdls_mgmt(SETUP_REQ) even after
7057 we return error code at 'add_station()'. Hence we have this
7058 check again in addtion to add_station().
7059 Anyway, there is no hard to double-check. */
Hoonki Lee11f7dda2013-02-14 16:55:44 -08007060 if (SIR_MAC_TDLS_SETUP_REQ == action_code)
Lee Hoonkic1262f22013-01-24 21:59:00 -08007061 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007062 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7063 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07007064 " TDLS Max peer already connected. action %d declined.",
7065 __func__, MAC_ADDR_ARRAY(peer), action_code);
Gopichand Nakkala05922802013-03-14 12:23:19 -07007066 goto error;
Lee Hoonkic1262f22013-01-24 21:59:00 -08007067 }
7068 else
7069 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -08007070 /* maximum reached. tweak to send error code to peer and return
7071 error code to supplicant */
Lee Hoonkic1262f22013-01-24 21:59:00 -08007072 status_code = eSIR_MAC_UNSPEC_FAILURE_STATUS;
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007073 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7074 "%s: " MAC_ADDRESS_STR
7075 " TDLS Max peer already connected send response status %d",
7076 __func__, MAC_ADDR_ARRAY(peer), status_code);
Gopichand Nakkala05922802013-03-14 12:23:19 -07007077 max_sta_failed = -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -08007078 /* fall through to send setup resp with failure status
7079 code */
Lee Hoonkic1262f22013-01-24 21:59:00 -08007080 }
7081 }
Hoonki Lee11f7dda2013-02-14 16:55:44 -08007082 else
7083 {
7084 hddTdlsPeer_t *pTdlsPeer;
Gopichand Nakkala4327a152013-03-04 23:22:42 -08007085 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007086 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Hoonki Lee11f7dda2013-02-14 16:55:44 -08007087 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007088 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07007089 "%s:" MAC_ADDRESS_STR " already connected. action %d declined.",
7090 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee11f7dda2013-02-14 16:55:44 -08007091 return -EPERM;
7092 }
7093 }
Lee Hoonkic1262f22013-01-24 21:59:00 -08007094 }
Hoonki Lee11f7dda2013-02-14 16:55:44 -08007095 vos_mem_copy(peerMac, peer, 6);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007096
Hoonki Lee1090c6a2013-01-16 17:40:54 -08007097#ifdef WLAN_FEATURE_TDLS_DEBUG
7098 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007099 "%s: " MAC_ADDRESS_STR " action %d, dialog_token %d status %d, len = %d",
7100 "tdls_mgmt", MAC_ADDR_ARRAY(peer),
7101 action_code, dialog_token, status_code, len);
Hoonki Lee1090c6a2013-01-16 17:40:54 -08007102#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007103
Hoonki Leea34dd892013-02-05 22:56:02 -08007104 /*Except teardown responder will not be used so just make 0*/
7105 responder = 0;
Hoonki Lee11f7dda2013-02-14 16:55:44 -08007106 if (SIR_MAC_TDLS_TEARDOWN == action_code)
Hoonki Leea34dd892013-02-05 22:56:02 -08007107 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -07007108
7109 hddTdlsPeer_t *pTdlsPeer;
7110 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peerMac);
7111
7112 if(pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
7113 responder = pTdlsPeer->is_responder;
7114 else
Hoonki Leea34dd892013-02-05 22:56:02 -08007115 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -07007116 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7117 "%s: " MAC_ADDRESS_STR " peer doesn't exist or not connected %d dialog_token %d status %d, len = %d",
7118 __func__, MAC_ADDR_ARRAY(peer), (NULL == pTdlsPeer) ? -1 : pTdlsPeer->link_status,
7119 dialog_token, status_code, len);
7120 return -EPERM;
Hoonki Leea34dd892013-02-05 22:56:02 -08007121 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007122 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007123
Hoonki Lee14621352013-04-16 17:51:19 -07007124 if ((SIR_MAC_TDLS_SETUP_RSP == action_code) ||
7125 (SIR_MAC_TDLS_DIS_RSP == action_code))
7126 {
7127 if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter)))
7128 {
7129 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
7130 "%s: Sending Disc/Setup Rsp Frame.Disable BMPS", __func__);
7131 hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
7132 }
7133 wlan_hdd_tdls_set_cap(pAdapter, peerMac, eTDLS_CAP_SUPPORTED);
7134 }
7135
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007136 /* make sure doesn't call send_mgmt() while it is pending */
7137 if (TDLS_CTX_MAGIC == pAdapter->mgmtTxCompletionStatus)
7138 {
7139 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7140 "%s: " MAC_ADDRESS_STR " action %d couldn't sent, as one is pending. return EBUSY\n",
7141 __func__, MAC_ADDR_ARRAY(peer), action_code);
7142 return -EBUSY;
7143 }
7144
7145 pAdapter->mgmtTxCompletionStatus = TDLS_CTX_MAGIC;
Gopichand Nakkalab977a972013-02-18 19:15:09 -08007146 INIT_COMPLETION(pAdapter->tdls_mgmt_comp);
7147
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007148 status = sme_SendTdlsMgmtFrame(WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
Hoonki Leea34dd892013-02-05 22:56:02 -08007149 peerMac, action_code, dialog_token, status_code, (tANI_U8 *)buf, len, responder);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007150
Gopichand Nakkalab977a972013-02-18 19:15:09 -08007151 if (VOS_STATUS_SUCCESS != status)
7152 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007153 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7154 "%s: sme_SendTdlsMgmtFrame failed!", __func__);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007155 pAdapter->mgmtTxCompletionStatus = FALSE;
Hoonki Lee14621352013-04-16 17:51:19 -07007156 wlan_hdd_tdls_check_bmps(pAdapter);
7157 goto error;
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007158 }
7159
Hoonki Leed37cbb32013-04-20 00:31:14 -07007160 rc = wait_for_completion_interruptible_timeout(&pAdapter->tdls_mgmt_comp,
7161 msecs_to_jiffies(WAIT_TIME_TDLS_MGMT));
7162
7163 if ((rc <= 0) || (TRUE != pAdapter->mgmtTxCompletionStatus))
Gopichand Nakkalab977a972013-02-18 19:15:09 -08007164 {
Hoonki Leed37cbb32013-04-20 00:31:14 -07007165 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7166 "%s: Mgmt Tx Completion failed status %ld TxCompletion %lu",
7167 __func__, rc, pAdapter->mgmtTxCompletionStatus);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007168 pAdapter->mgmtTxCompletionStatus = FALSE;
Hoonki Leed37cbb32013-04-20 00:31:14 -07007169 wlan_hdd_tdls_check_bmps(pAdapter);
7170 goto error;
Gopichand Nakkalab977a972013-02-18 19:15:09 -08007171 }
7172
Gopichand Nakkala05922802013-03-14 12:23:19 -07007173 if (max_sta_failed)
Hoonki Lee14621352013-04-16 17:51:19 -07007174 {
7175 wlan_hdd_tdls_check_bmps(pAdapter);
Gopichand Nakkala05922802013-03-14 12:23:19 -07007176 return max_sta_failed;
Hoonki Lee14621352013-04-16 17:51:19 -07007177 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -08007178
Hoonki Leea34dd892013-02-05 22:56:02 -08007179 if (SIR_MAC_TDLS_SETUP_RSP == action_code)
7180 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -08007181 wlan_hdd_tdls_set_responder(pAdapter, peerMac, TRUE);
Hoonki Leea34dd892013-02-05 22:56:02 -08007182 }
7183 else if (SIR_MAC_TDLS_SETUP_CNF == action_code)
7184 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -08007185 wlan_hdd_tdls_set_responder(pAdapter, peerMac, FALSE);
Hoonki Leea34dd892013-02-05 22:56:02 -08007186 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007187
7188 return 0;
Gopichand Nakkala05922802013-03-14 12:23:19 -07007189error:
7190 /* max_sta_failed ; we didn't set to CONNECTING for this case,
7191 because we already know that this transaction will be failed,
7192 but we weren't sure if supplicant call DISABLE_LINK or not. So,
7193 to be safe, do not change the state mahine.
7194 */
7195 if(max_sta_failed == 0 &&
7196 (WLAN_IS_TDLS_SETUP_ACTION(action_code)))
7197 wlan_hdd_tdls_set_link_status(pAdapter, peerMac, eTDLS_LINK_IDLE);
7198 return -EPERM;
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007199}
7200
7201static int wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
7202 u8 *peer, enum nl80211_tdls_operation oper)
7203{
7204 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
7205 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Hoonki Lee1090c6a2013-01-16 17:40:54 -08007206#ifdef WLAN_FEATURE_TDLS_DEBUG
7207 const char *tdls_oper_str[]= {
7208 "NL80211_TDLS_DISCOVERY_REQ",
7209 "NL80211_TDLS_SETUP",
7210 "NL80211_TDLS_TEARDOWN",
7211 "NL80211_TDLS_ENABLE_LINK",
7212 "NL80211_TDLS_DISABLE_LINK",
7213 "NL80211_TDLS_UNKONW_OPER"};
7214#endif
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007215 hddTdlsPeer_t *pTdlsPeer;
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007216
Chilam Ngc4244af2013-04-01 15:37:32 -07007217 if ( NULL == pHddCtx || NULL == pHddCtx->cfg_ini || NULL == peer )
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007218 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -08007219 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chilam Ngc4244af2013-04-01 15:37:32 -07007220 "%s: Invalid arguments", __func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007221 return -EINVAL;
7222 }
Hoonki Lee1090c6a2013-01-16 17:40:54 -08007223
Sameer Thalappil75ea31a2013-02-21 19:38:16 -08007224 if (pHddCtx->isLogpInProgress)
7225 {
7226 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7227 "%s:LOGP in Progress. Ignore!!!", __func__);
7228 return -EBUSY;
7229 }
7230
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007231 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer);
7232
7233 if ( NULL == pTdlsPeer ) {
7234 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR " (oper %d) not exsting. ignored",
7235 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
7236 return -EINVAL;
7237 }
7238
Hoonki Lee1090c6a2013-01-16 17:40:54 -08007239#ifdef WLAN_FEATURE_TDLS_DEBUG
7240 if((int)oper > 4)
7241 oper = 5;
7242
7243 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007244 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
7245 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007246 tdls_oper_str[(int)oper]);
Hoonki Lee1090c6a2013-01-16 17:40:54 -08007247#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007248
7249 if( FALSE == pHddCtx->cfg_ini->fEnableTDLSSupport ||
Hoonki Lee1090c6a2013-01-16 17:40:54 -08007250 FALSE == sme_IsFeatureSupportedByFW(TDLS))
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007251 {
Hoonki Lee1090c6a2013-01-16 17:40:54 -08007252 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chilam Ngc4244af2013-04-01 15:37:32 -07007253 "TDLS Disabled in INI OR not enabled in FW. "
7254 "Cannot process TDLS commands");
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007255 return -ENOTSUPP;
7256 }
7257
7258 switch (oper) {
7259 case NL80211_TDLS_ENABLE_LINK:
7260 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007261 VOS_STATUS status;
7262
Gopichand Nakkala2f4a2822013-04-17 11:22:01 -07007263 if (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
7264 {
7265 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Staion Index %u "
7266 MAC_ADDRESS_STR " failed",
7267 __func__, pTdlsPeer->staId, MAC_ADDR_ARRAY(peer));
7268 return -EINVAL;
7269 }
7270
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007271 if (eTDLS_LINK_CONNECTED != pTdlsPeer->link_status)
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007272 {
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -07007273 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer, eTDLS_LINK_CONNECTED);
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007274 /* start TDLS client registration with TL */
7275 status = hdd_roamRegisterTDLSSTA( pAdapter, peer, pTdlsPeer->staId, pTdlsPeer->signature);
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -07007276 if (VOS_STATUS_SUCCESS == status)
7277 {
Hoonki Lee14621352013-04-16 17:51:19 -07007278 if (pTdlsPeer->is_responder == 0)
7279 {
7280 v_U8_t staId = (v_U8_t)pTdlsPeer->staId;
7281
7282 wlan_hdd_tdls_timer_restart(pAdapter,
7283 &pTdlsPeer->initiatorWaitTimeoutTimer,
7284 WAIT_TIME_TDLS_INITIATOR);
7285 /* suspend initiator TX until it receives direct packet from the
7286 reponder or WAIT_TIME_TDLS_INITIATOR timer expires */
7287 WLANTL_SuspendDataTx( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
7288 &staId, NULL);
7289 }
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -07007290 wlan_hdd_tdls_increment_peer_count(pAdapter);
7291 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007292 wlan_hdd_tdls_check_bmps(pAdapter);
7293 }
7294
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007295 }
7296 break;
7297 case NL80211_TDLS_DISABLE_LINK:
Lee Hoonkic1262f22013-01-24 21:59:00 -08007298 {
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007299 if(TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
Lee Hoonkic1262f22013-01-24 21:59:00 -08007300 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007301 long status;
7302
7303 INIT_COMPLETION(pAdapter->tdls_del_station_comp);
7304
Lee Hoonkic1262f22013-01-24 21:59:00 -08007305 sme_DeleteTdlsPeerSta( WLAN_HDD_GET_HAL_CTX(pAdapter),
7306 pAdapter->sessionId, peer );
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007307
7308 status = wait_for_completion_interruptible_timeout(&pAdapter->tdls_del_station_comp,
7309 msecs_to_jiffies(WAIT_TIME_TDLS_DEL_STA));
7310 if (status <= 0)
7311 {
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007312 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer, eTDLS_LINK_IDLE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007313 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7314 "%s: Del station failed status %ld",
7315 __func__, status);
7316 return -EPERM;
7317 }
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007318 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer, eTDLS_LINK_IDLE);
Lee Hoonkic1262f22013-01-24 21:59:00 -08007319 }
7320 else
7321 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007322 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7323 "%s: TDLS Peer Station doesn't exist.", __func__);
Lee Hoonkic1262f22013-01-24 21:59:00 -08007324 }
Lee Hoonkic1262f22013-01-24 21:59:00 -08007325 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007326 break;
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007327 case NL80211_TDLS_TEARDOWN:
7328 case NL80211_TDLS_SETUP:
7329 case NL80211_TDLS_DISCOVERY_REQ:
7330 /* We don't support in-driver setup/teardown/discovery */
7331 return -ENOTSUPP;
7332 default:
7333 return -ENOTSUPP;
7334 }
7335 return 0;
7336}
Chilam NG571c65a2013-01-19 12:27:36 +05307337
7338int wlan_hdd_cfg80211_send_tdls_discover_req(struct wiphy *wiphy,
7339 struct net_device *dev, u8 *peer)
7340{
7341 hddLog(VOS_TRACE_LEVEL_INFO, "tdls send discover req: %x %x %x %x %x %x",
7342 peer[0], peer[1], peer[2], peer[3], peer[4], peer[5]);
7343
7344 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
7345 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, NULL, 0);
7346}
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007347#endif
7348
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05307349#ifdef WLAN_FEATURE_GTK_OFFLOAD
7350/*
7351 * FUNCTION: wlan_hdd_cfg80211_update_replayCounterCallback
7352 * Callback rountine called upon receiving response for
7353 * get offload info
7354 */
7355void wlan_hdd_cfg80211_update_replayCounterCallback(void *callbackContext,
7356 tpSirGtkOffloadGetInfoRspParams pGtkOffloadGetInfoRsp)
7357{
7358
7359 hdd_adapter_t *pAdapter = (hdd_adapter_t *)callbackContext;
7360
7361 ENTER();
7362
7363 if (NULL == pAdapter)
7364 {
7365 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
7366 "%s: HDD adapter is Null", __func__);
7367 return ;
7368 }
7369
7370 if (NULL == pGtkOffloadGetInfoRsp)
7371 {
7372 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7373 "%s: pGtkOffloadGetInfoRsp is Null", __func__);
7374 return ;
7375 }
7376
7377 if (VOS_STATUS_SUCCESS != pGtkOffloadGetInfoRsp->ulStatus)
7378 {
7379 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7380 "%s: wlan Failed to get replay counter value",
7381 __func__);
7382 return ;
7383 }
7384
7385 /* Update replay counter to NL */
7386 cfg80211_gtk_rekey_notify(pAdapter->dev, pGtkOffloadGetInfoRsp->bssId,
7387 (tANI_U8 *)&pGtkOffloadGetInfoRsp->ullKeyReplayCounter, GFP_KERNEL);
7388}
7389
7390/*
7391 * FUNCTION: wlan_hdd_cfg80211_set_rekey_data
7392 * This function is used to offload GTK rekeying job to the firmware.
7393 */
7394int wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
7395 struct cfg80211_gtk_rekey_data *data)
7396{
7397 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
7398 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
7399 hdd_station_ctx_t *pHddStaCtx;
7400 tHalHandle hHal;
7401 tpSirGtkOffloadParams pGtkOffloadReqParams;
7402 eHalStatus status = eHAL_STATUS_FAILURE;
7403
7404 ENTER();
7405
7406 if (NULL == pAdapter)
7407 {
7408 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
7409 "%s: HDD adapter is Null", __func__);
7410 return -ENODEV;
7411 }
7412
7413 if (NULL == pHddCtx)
7414 {
7415 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7416 "%s: HDD context is Null!!!", __func__);
7417 return -ENODEV;
7418 }
7419
7420 if (pHddCtx->isLogpInProgress)
7421 {
7422 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
7423 "%s: LOGP in Progress. Ignore!!!", __func__);
7424 return -EAGAIN;
7425 }
7426
7427 if (pHddCtx->isLoadUnloadInProgress)
7428 {
7429 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
7430 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
7431 return -EAGAIN;
7432 }
7433
7434 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7435 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
7436 if (NULL == hHal)
7437 {
7438 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7439 "%s: HAL context is Null!!!", __func__);
7440 return -EAGAIN;
7441 }
7442
7443 pGtkOffloadReqParams =
7444 &pHddStaCtx->gtkOffloadRequestParams.gtkOffloadReqParams;
7445
7446 pGtkOffloadReqParams->ulFlags = GTK_OFFLOAD_ENABLE;
7447 memcpy(pGtkOffloadReqParams->aKCK, data->kck, NL80211_KCK_LEN);
7448 memcpy(pGtkOffloadReqParams->aKEK, data->kek, NL80211_KEK_LEN);
7449 memcpy(pGtkOffloadReqParams->bssId, &pHddStaCtx->conn_info.bssId,
7450 WNI_CFG_BSSID_LEN);
7451 memcpy(&pGtkOffloadReqParams->ullKeyReplayCounter, &data->replay_ctr,
7452 sizeof (tANI_U64));
7453
7454 if (TRUE == pHddCtx->hdd_wlan_suspended)
7455 {
7456 /* if wlan is suspended, enable GTK offload directly from here */
7457 status = sme_SetGTKOffload(hHal, pGtkOffloadReqParams,
7458 pAdapter->sessionId);
7459
7460 if (eHAL_STATUS_SUCCESS != status)
7461 {
7462 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7463 "%s: sme_SetGTKOffload failed, returned %d",
7464 __func__, status);
7465 return status;
7466 }
7467 pHddStaCtx->gtkOffloadRequestParams.requested = FALSE;
7468 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
7469 "%s: sme_SetGTKOffload successfull", __func__);
7470 }
7471 else
7472 {
7473 pHddStaCtx->gtkOffloadRequestParams.requested = TRUE;
7474 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
7475 "%s: wlan not suspended GTKOffload request is stored",
7476 __func__);
7477 return eHAL_STATUS_SUCCESS;
7478 }
7479 return status;
7480}
7481#endif /*WLAN_FEATURE_GTK_OFFLOAD*/
7482
Jeff Johnson295189b2012-06-20 16:38:30 -07007483/* cfg80211_ops */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307484static struct cfg80211_ops wlan_hdd_cfg80211_ops =
Jeff Johnson295189b2012-06-20 16:38:30 -07007485{
7486 .add_virtual_intf = wlan_hdd_add_virtual_intf,
7487 .del_virtual_intf = wlan_hdd_del_virtual_intf,
7488 .change_virtual_intf = wlan_hdd_cfg80211_change_iface,
7489 .change_station = wlan_hdd_change_station,
7490#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
7491 .add_beacon = wlan_hdd_cfg80211_add_beacon,
7492 .del_beacon = wlan_hdd_cfg80211_del_beacon,
7493 .set_beacon = wlan_hdd_cfg80211_set_beacon,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007494#else
7495 .start_ap = wlan_hdd_cfg80211_start_ap,
7496 .change_beacon = wlan_hdd_cfg80211_change_beacon,
7497 .stop_ap = wlan_hdd_cfg80211_stop_ap,
Jeff Johnson295189b2012-06-20 16:38:30 -07007498#endif
7499 .change_bss = wlan_hdd_cfg80211_change_bss,
7500 .add_key = wlan_hdd_cfg80211_add_key,
7501 .get_key = wlan_hdd_cfg80211_get_key,
7502 .del_key = wlan_hdd_cfg80211_del_key,
7503 .set_default_key = wlan_hdd_cfg80211_set_default_key,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -08007504#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07007505 .set_channel = wlan_hdd_cfg80211_set_channel,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -08007506#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007507 .scan = wlan_hdd_cfg80211_scan,
7508 .connect = wlan_hdd_cfg80211_connect,
7509 .disconnect = wlan_hdd_cfg80211_disconnect,
7510 .join_ibss = wlan_hdd_cfg80211_join_ibss,
7511 .leave_ibss = wlan_hdd_cfg80211_leave_ibss,
7512 .set_wiphy_params = wlan_hdd_cfg80211_set_wiphy_params,
7513 .set_tx_power = wlan_hdd_cfg80211_set_txpower,
7514 .get_tx_power = wlan_hdd_cfg80211_get_txpower,
Jeff Johnson295189b2012-06-20 16:38:30 -07007515 .remain_on_channel = wlan_hdd_cfg80211_remain_on_channel,
7516 .cancel_remain_on_channel = wlan_hdd_cfg80211_cancel_remain_on_channel,
7517 .mgmt_tx = wlan_hdd_action,
7518#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
7519 .mgmt_tx_cancel_wait = wlan_hdd_cfg80211_mgmt_tx_cancel_wait,
7520 .set_default_mgmt_key = wlan_hdd_set_default_mgmt_key,
7521 .set_txq_params = wlan_hdd_set_txq_params,
7522#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007523 .get_station = wlan_hdd_cfg80211_get_station,
7524 .set_power_mgmt = wlan_hdd_cfg80211_set_power_mgmt,
7525 .del_station = wlan_hdd_cfg80211_del_station,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007526 .add_station = wlan_hdd_cfg80211_add_station,
7527#ifdef FEATURE_WLAN_LFR
7528 .set_pmksa = wlan_hdd_cfg80211_set_pmksa,
7529 .del_pmksa = wlan_hdd_cfg80211_del_pmksa,
7530 .flush_pmksa = wlan_hdd_cfg80211_flush_pmksa,
7531#endif
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07007532#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
7533 .update_ft_ies = wlan_hdd_cfg80211_update_ft_ies,
7534#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007535#ifdef FEATURE_WLAN_TDLS
7536 .tdls_mgmt = wlan_hdd_cfg80211_tdls_mgmt,
7537 .tdls_oper = wlan_hdd_cfg80211_tdls_oper,
7538#endif
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05307539#ifdef WLAN_FEATURE_GTK_OFFLOAD
7540 .set_rekey_data = wlan_hdd_cfg80211_set_rekey_data,
7541#endif /* WLAN_FEATURE_GTK_OFFLOAD */
Jeff Johnson295189b2012-06-20 16:38:30 -07007542};
7543