blob: 519f25e1c85f2480cf2be74c5446b1672c280e61 [file] [log] [blame]
Jeff Johnson295189b2012-06-20 16:38:30 -07001/*
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302 * Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
3 *
4 * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
5 *
6 *
7 * Permission to use, copy, modify, and/or distribute this software for
8 * any purpose with or without fee is hereby granted, provided that the
9 * above copyright notice and this permission notice appear in all
10 * copies.
11 *
12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
13 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
14 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
15 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
16 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
17 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
18 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
19 * PERFORMANCE OF THIS SOFTWARE.
20*/
Jeff Johnson295189b2012-06-20 16:38:30 -070021
22/**========================================================================
23
24 \file wlan_hdd_cfg80211.c
25
26 \brief WLAN Host Device Driver implementation
27
Gopichand Nakkala747461f2013-04-24 19:24:45 +053028 Copyright 2008 (c) Qualcomm Technologies, Inc. All Rights Reserved.
Jeff Johnson295189b2012-06-20 16:38:30 -070029
Gopichand Nakkala747461f2013-04-24 19:24:45 +053030 Qualcomm Technologies Confidential and Proprietary.
Jeff Johnson295189b2012-06-20 16:38:30 -070031
32 ========================================================================*/
33
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070034/**=========================================================================
Jeff Johnson295189b2012-06-20 16:38:30 -070035
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070036 EDIT HISTORY FOR FILE
Jeff Johnson295189b2012-06-20 16:38:30 -070037
38
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070039 This section contains comments describing changes made to the module.
40 Notice that changes are listed in reverse chronological order.
Jeff Johnson295189b2012-06-20 16:38:30 -070041
42
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070043 $Header:$ $DateTime: $ $Author: $
Jeff Johnson295189b2012-06-20 16:38:30 -070044
45
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070046 when who what, where, why
Jeff Johnson295189b2012-06-20 16:38:30 -070047 -------- --- --------------------------------------------------------
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070048 21/12/09 Ashwani Created module.
Jeff Johnson295189b2012-06-20 16:38:30 -070049
50 07/06/10 Kumar Deepak Implemented cfg80211 callbacks for ANDROID
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070051 Ganesh K
Jeff Johnson295189b2012-06-20 16:38:30 -070052 ==========================================================================*/
53
Jeff Johnson295189b2012-06-20 16:38:30 -070054
55#include <linux/version.h>
56#include <linux/module.h>
57#include <linux/kernel.h>
58#include <linux/init.h>
59#include <linux/wireless.h>
60#include <wlan_hdd_includes.h>
61#include <net/arp.h>
62#include <net/cfg80211.h>
63#include <linux/wireless.h>
64#include <wlan_hdd_wowl.h>
65#include <aniGlobal.h>
66#include "ccmApi.h"
67#include "sirParams.h"
68#include "dot11f.h"
69#include "wlan_hdd_assoc.h"
70#include "wlan_hdd_wext.h"
71#include "sme_Api.h"
72#include "wlan_hdd_p2p.h"
73#include "wlan_hdd_cfg80211.h"
74#include "wlan_hdd_hostapd.h"
75#include "sapInternal.h"
76#include "wlan_hdd_softap_tx_rx.h"
77#include "wlan_hdd_main.h"
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053078#include "wlan_hdd_assoc.h"
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053079#include "wlan_hdd_power.h"
Jeff Johnson295189b2012-06-20 16:38:30 -070080#ifdef WLAN_BTAMP_FEATURE
81#include "bap_hdd_misc.h"
82#endif
83#include <qc_sap_ioctl.h>
Mohit Khanna698ba2a2012-12-04 15:08:18 -080084#ifdef FEATURE_WLAN_TDLS
85#include "wlan_hdd_tdls.h"
86#endif
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +053087#include "wlan_nv.h"
Jeff Johnson295189b2012-06-20 16:38:30 -070088
89#define g_mode_rates_size (12)
90#define a_mode_rates_size (8)
91#define FREQ_BASE_80211G (2407)
92#define FREQ_BAND_DIFF_80211G (5)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070093#define MAX_SCAN_SSID 9
Jeff Johnson295189b2012-06-20 16:38:30 -070094#define GET_IE_LEN_IN_BSS_DESC(lenInBss) ( lenInBss + sizeof(lenInBss) - \
95 ((int) OFFSET_OF( tSirBssDescription, ieFields)))
96
97#define HDD2GHZCHAN(freq, chan, flag) { \
98 .band = IEEE80211_BAND_2GHZ, \
99 .center_freq = (freq), \
100 .hw_value = (chan),\
101 .flags = (flag), \
102 .max_antenna_gain = 0 ,\
103 .max_power = 30, \
104}
105
106#define HDD5GHZCHAN(freq, chan, flag) { \
107 .band = IEEE80211_BAND_5GHZ, \
108 .center_freq = (freq), \
109 .hw_value = (chan),\
110 .flags = (flag), \
111 .max_antenna_gain = 0 ,\
112 .max_power = 30, \
113}
114
115#define HDD_G_MODE_RATETAB(rate, rate_id, flag)\
116{\
117 .bitrate = rate, \
118 .hw_value = rate_id, \
119 .flags = flag, \
120}
121
Lee Hoonkic1262f22013-01-24 21:59:00 -0800122#ifndef WLAN_FEATURE_TDLS_DEBUG
123#define TDLS_LOG_LEVEL VOS_TRACE_LEVEL_INFO
124#else
125#define TDLS_LOG_LEVEL VOS_TRACE_LEVEL_ERROR
126#endif
127
Gopichand Nakkala356fb102013-03-06 12:34:04 +0530128#ifdef WLAN_FEATURE_VOWIFI_11R
129#define WLAN_AKM_SUITE_FT_8021X 0x000FAC03
130#define WLAN_AKM_SUITE_FT_PSK 0x000FAC04
131#endif
132
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530133static const u32 hdd_cipher_suites[] =
Jeff Johnson295189b2012-06-20 16:38:30 -0700134{
135 WLAN_CIPHER_SUITE_WEP40,
136 WLAN_CIPHER_SUITE_WEP104,
137 WLAN_CIPHER_SUITE_TKIP,
138#ifdef FEATURE_WLAN_CCX
139#define WLAN_CIPHER_SUITE_KRK 0x004096ff /* use for KRK */
140 WLAN_CIPHER_SUITE_KRK,
141 WLAN_CIPHER_SUITE_CCMP,
142#else
143 WLAN_CIPHER_SUITE_CCMP,
144#endif
145#ifdef FEATURE_WLAN_WAPI
146 WLAN_CIPHER_SUITE_SMS4,
147#endif
Chet Lanctot186b5732013-03-18 10:26:30 -0700148#ifdef WLAN_FEATURE_11W
149 WLAN_CIPHER_SUITE_AES_CMAC,
150#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700151};
152
153static inline int is_broadcast_ether_addr(const u8 *addr)
154{
155 return ((addr[0] == 0xff) && (addr[1] == 0xff) && (addr[2] == 0xff) &&
156 (addr[3] == 0xff) && (addr[4] == 0xff) && (addr[5] == 0xff));
157}
158
159static struct ieee80211_channel hdd_channels_2_4_GHZ[] =
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530160{
Jeff Johnson295189b2012-06-20 16:38:30 -0700161 HDD2GHZCHAN(2412, 1, 0) ,
162 HDD2GHZCHAN(2417, 2, 0) ,
163 HDD2GHZCHAN(2422, 3, 0) ,
164 HDD2GHZCHAN(2427, 4, 0) ,
165 HDD2GHZCHAN(2432, 5, 0) ,
166 HDD2GHZCHAN(2437, 6, 0) ,
167 HDD2GHZCHAN(2442, 7, 0) ,
168 HDD2GHZCHAN(2447, 8, 0) ,
169 HDD2GHZCHAN(2452, 9, 0) ,
170 HDD2GHZCHAN(2457, 10, 0) ,
171 HDD2GHZCHAN(2462, 11, 0) ,
172 HDD2GHZCHAN(2467, 12, 0) ,
173 HDD2GHZCHAN(2472, 13, 0) ,
174 HDD2GHZCHAN(2484, 14, 0) ,
175};
176
Jeff Johnson295189b2012-06-20 16:38:30 -0700177static struct ieee80211_channel hdd_social_channels_2_4_GHZ[] =
178{
179 HDD2GHZCHAN(2412, 1, 0) ,
180 HDD2GHZCHAN(2437, 6, 0) ,
181 HDD2GHZCHAN(2462, 11, 0) ,
182};
Jeff Johnson295189b2012-06-20 16:38:30 -0700183
184static struct ieee80211_channel hdd_channels_5_GHZ[] =
185{
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -0700186 HDD5GHZCHAN(4920, 240, 0) ,
187 HDD5GHZCHAN(4940, 244, 0) ,
188 HDD5GHZCHAN(4960, 248, 0) ,
189 HDD5GHZCHAN(4980, 252, 0) ,
190 HDD5GHZCHAN(5040, 208, 0) ,
191 HDD5GHZCHAN(5060, 212, 0) ,
192 HDD5GHZCHAN(5080, 216, 0) ,
Jeff Johnson295189b2012-06-20 16:38:30 -0700193 HDD5GHZCHAN(5180, 36, 0) ,
194 HDD5GHZCHAN(5200, 40, 0) ,
195 HDD5GHZCHAN(5220, 44, 0) ,
196 HDD5GHZCHAN(5240, 48, 0) ,
197 HDD5GHZCHAN(5260, 52, 0) ,
198 HDD5GHZCHAN(5280, 56, 0) ,
199 HDD5GHZCHAN(5300, 60, 0) ,
200 HDD5GHZCHAN(5320, 64, 0) ,
201 HDD5GHZCHAN(5500,100, 0) ,
202 HDD5GHZCHAN(5520,104, 0) ,
203 HDD5GHZCHAN(5540,108, 0) ,
204 HDD5GHZCHAN(5560,112, 0) ,
205 HDD5GHZCHAN(5580,116, 0) ,
206 HDD5GHZCHAN(5600,120, 0) ,
207 HDD5GHZCHAN(5620,124, 0) ,
208 HDD5GHZCHAN(5640,128, 0) ,
209 HDD5GHZCHAN(5660,132, 0) ,
210 HDD5GHZCHAN(5680,136, 0) ,
211 HDD5GHZCHAN(5700,140, 0) ,
212 HDD5GHZCHAN(5745,149, 0) ,
213 HDD5GHZCHAN(5765,153, 0) ,
214 HDD5GHZCHAN(5785,157, 0) ,
215 HDD5GHZCHAN(5805,161, 0) ,
216 HDD5GHZCHAN(5825,165, 0) ,
217};
218
219static struct ieee80211_rate g_mode_rates[] =
220{
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530221 HDD_G_MODE_RATETAB(10, 0x1, 0),
222 HDD_G_MODE_RATETAB(20, 0x2, 0),
223 HDD_G_MODE_RATETAB(55, 0x4, 0),
224 HDD_G_MODE_RATETAB(110, 0x8, 0),
225 HDD_G_MODE_RATETAB(60, 0x10, 0),
226 HDD_G_MODE_RATETAB(90, 0x20, 0),
227 HDD_G_MODE_RATETAB(120, 0x40, 0),
228 HDD_G_MODE_RATETAB(180, 0x80, 0),
229 HDD_G_MODE_RATETAB(240, 0x100, 0),
230 HDD_G_MODE_RATETAB(360, 0x200, 0),
231 HDD_G_MODE_RATETAB(480, 0x400, 0),
Jeff Johnson295189b2012-06-20 16:38:30 -0700232 HDD_G_MODE_RATETAB(540, 0x800, 0),
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530233};
Jeff Johnson295189b2012-06-20 16:38:30 -0700234
235static struct ieee80211_rate a_mode_rates[] =
236{
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530237 HDD_G_MODE_RATETAB(60, 0x10, 0),
238 HDD_G_MODE_RATETAB(90, 0x20, 0),
239 HDD_G_MODE_RATETAB(120, 0x40, 0),
240 HDD_G_MODE_RATETAB(180, 0x80, 0),
241 HDD_G_MODE_RATETAB(240, 0x100, 0),
242 HDD_G_MODE_RATETAB(360, 0x200, 0),
243 HDD_G_MODE_RATETAB(480, 0x400, 0),
Jeff Johnson295189b2012-06-20 16:38:30 -0700244 HDD_G_MODE_RATETAB(540, 0x800, 0),
245};
246
247static struct ieee80211_supported_band wlan_hdd_band_2_4_GHZ =
248{
249 .channels = hdd_channels_2_4_GHZ,
250 .n_channels = ARRAY_SIZE(hdd_channels_2_4_GHZ),
251 .band = IEEE80211_BAND_2GHZ,
252 .bitrates = g_mode_rates,
253 .n_bitrates = g_mode_rates_size,
254 .ht_cap.ht_supported = 1,
255 .ht_cap.cap = IEEE80211_HT_CAP_SGI_20
256 | IEEE80211_HT_CAP_GRN_FLD
257 | IEEE80211_HT_CAP_DSSSCCK40
258 | IEEE80211_HT_CAP_LSIG_TXOP_PROT,
259 .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
260 .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
261 .ht_cap.mcs.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
262 .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ),
263 .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
264};
265
Jeff Johnson295189b2012-06-20 16:38:30 -0700266static struct ieee80211_supported_band wlan_hdd_band_p2p_2_4_GHZ =
267{
268 .channels = hdd_social_channels_2_4_GHZ,
269 .n_channels = ARRAY_SIZE(hdd_social_channels_2_4_GHZ),
270 .band = IEEE80211_BAND_2GHZ,
271 .bitrates = g_mode_rates,
272 .n_bitrates = g_mode_rates_size,
273 .ht_cap.ht_supported = 1,
274 .ht_cap.cap = IEEE80211_HT_CAP_SGI_20
275 | IEEE80211_HT_CAP_GRN_FLD
276 | IEEE80211_HT_CAP_DSSSCCK40
277 | IEEE80211_HT_CAP_LSIG_TXOP_PROT,
278 .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
279 .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
280 .ht_cap.mcs.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
281 .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ),
282 .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
283};
Jeff Johnson295189b2012-06-20 16:38:30 -0700284
285static struct ieee80211_supported_band wlan_hdd_band_5_GHZ =
286{
287 .channels = hdd_channels_5_GHZ,
288 .n_channels = ARRAY_SIZE(hdd_channels_5_GHZ),
289 .band = IEEE80211_BAND_5GHZ,
290 .bitrates = a_mode_rates,
291 .n_bitrates = a_mode_rates_size,
292 .ht_cap.ht_supported = 1,
293 .ht_cap.cap = IEEE80211_HT_CAP_SGI_20
294 | IEEE80211_HT_CAP_GRN_FLD
295 | IEEE80211_HT_CAP_DSSSCCK40
296 | IEEE80211_HT_CAP_LSIG_TXOP_PROT
297 | IEEE80211_HT_CAP_SGI_40
298 | IEEE80211_HT_CAP_SUP_WIDTH_20_40,
299 .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
300 .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
301 .ht_cap.mcs.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
302 .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ),
303 .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
304};
305
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530306/* This structure contain information what kind of frame are expected in
Jeff Johnson295189b2012-06-20 16:38:30 -0700307 TX/RX direction for each kind of interface */
308static const struct ieee80211_txrx_stypes
309wlan_hdd_txrx_stypes[NUM_NL80211_IFTYPES] = {
310 [NL80211_IFTYPE_STATION] = {
311 .tx = 0xffff,
312 .rx = BIT(SIR_MAC_MGMT_ACTION) |
313 BIT(SIR_MAC_MGMT_PROBE_REQ),
314 },
315 [NL80211_IFTYPE_AP] = {
316 .tx = 0xffff,
317 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
318 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
319 BIT(SIR_MAC_MGMT_PROBE_REQ) |
320 BIT(SIR_MAC_MGMT_DISASSOC) |
321 BIT(SIR_MAC_MGMT_AUTH) |
322 BIT(SIR_MAC_MGMT_DEAUTH) |
323 BIT(SIR_MAC_MGMT_ACTION),
324 },
Jeff Johnsonbc006202013-04-29 14:05:30 -0700325 [NL80211_IFTYPE_ADHOC] = {
326 .tx = 0xffff,
327 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
328 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
329 BIT(SIR_MAC_MGMT_PROBE_REQ) |
330 BIT(SIR_MAC_MGMT_DISASSOC) |
331 BIT(SIR_MAC_MGMT_AUTH) |
332 BIT(SIR_MAC_MGMT_DEAUTH) |
333 BIT(SIR_MAC_MGMT_ACTION),
334 },
Jeff Johnson295189b2012-06-20 16:38:30 -0700335 [NL80211_IFTYPE_P2P_CLIENT] = {
336 .tx = 0xffff,
337 .rx = BIT(SIR_MAC_MGMT_ACTION) |
338 BIT(SIR_MAC_MGMT_PROBE_REQ),
339 },
340 [NL80211_IFTYPE_P2P_GO] = {
341 /* This is also same as for SoftAP */
342 .tx = 0xffff,
343 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
344 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
345 BIT(SIR_MAC_MGMT_PROBE_REQ) |
346 BIT(SIR_MAC_MGMT_DISASSOC) |
347 BIT(SIR_MAC_MGMT_AUTH) |
348 BIT(SIR_MAC_MGMT_DEAUTH) |
349 BIT(SIR_MAC_MGMT_ACTION),
350 },
Jeff Johnson295189b2012-06-20 16:38:30 -0700351};
352
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800353#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800354static const struct ieee80211_iface_limit
355wlan_hdd_iface_limit[] = {
356 {
Sunil Ravia72c3992013-01-31 06:12:22 -0800357 /* max = 3 ; Our driver create two interfaces during driver init
358 * wlan0 and p2p0 interfaces. p2p0 is considered as station
359 * interface until a group is formed. In JB architecture, once the
360 * group is formed, interface type of p2p0 is changed to P2P GO or
361 * Client.
362 * When supplicant remove the group, it first issue a set interface
363 * cmd to change the mode back to Station. In JB this works fine as
364 * we advertize two station type interface during driver init.
365 * Some vendors create separate interface for P2P GO/Client,
366 * after group formation(Third one). But while group remove
367 * supplicant first tries to change the mode(3rd interface) to STATION
368 * But as we advertized only two sta type interfaces nl80211 was
369 * returning error for the third one which was leading to failure in
370 * delete interface. Ideally while removing the group, supplicant
371 * should not try to change the 3rd interface mode to Station type.
372 * Till we get a fix in wpa_supplicant, we advertize max STA
373 * interface type to 3
374 */
375 .max = 3,
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800376 .types = BIT(NL80211_IFTYPE_STATION),
377 },
378 {
379 .max = 1,
Jeff Johnsonbc006202013-04-29 14:05:30 -0700380 .types = BIT(NL80211_IFTYPE_ADHOC) | BIT(NL80211_IFTYPE_AP),
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800381 },
382 {
383 .max = 1,
384 .types = BIT(NL80211_IFTYPE_P2P_GO) |
385 BIT(NL80211_IFTYPE_P2P_CLIENT),
386 },
387};
388
389/* By default, only single channel concurrency is allowed */
390static struct ieee80211_iface_combination
391wlan_hdd_iface_combination = {
392 .limits = wlan_hdd_iface_limit,
393 .num_different_channels = 1,
Sunil Ravia72c3992013-01-31 06:12:22 -0800394 /*
395 * max = WLAN_MAX_INTERFACES ; JellyBean architecture creates wlan0
396 * and p2p0 interfaces during driver init
397 * Some vendors create separate interface for P2P operations.
398 * wlan0: STA interface
399 * p2p0: P2P Device interface, action frames goes
400 * through this interface.
401 * p2p-xx: P2P interface, After GO negotiation this interface is
402 * created for p2p operations(GO/CLIENT interface).
403 */
404 .max_interfaces = WLAN_MAX_INTERFACES,
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800405 .n_limits = ARRAY_SIZE(wlan_hdd_iface_limit),
406 .beacon_int_infra_match = false,
407};
408#endif
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800409
Jeff Johnson295189b2012-06-20 16:38:30 -0700410static struct cfg80211_ops wlan_hdd_cfg80211_ops;
411
412/* Data rate 100KBPS based on IE Index */
413struct index_data_rate_type
414{
415 v_U8_t beacon_rate_index;
416 v_U16_t supported_rate[4];
417};
418
419/* 11B, 11G Rate table include Basic rate and Extended rate
420 The IDX field is the rate index
421 The HI field is the rate when RSSI is strong or being ignored
422 (in this case we report actual rate)
423 The MID field is the rate when RSSI is moderate
424 (in this case we cap 11b rates at 5.5 and 11g rates at 24)
425 The LO field is the rate when RSSI is low
426 (in this case we don't report rates, actual current rate used)
427 */
428static const struct
429{
430 v_U8_t beacon_rate_index;
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -0700431 v_U16_t supported_rate[4];
Jeff Johnson295189b2012-06-20 16:38:30 -0700432} supported_data_rate[] =
433{
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -0700434/* IDX HI HM LM LO (RSSI-based index */
435 {2, { 10, 10, 10, 0}},
436 {4, { 20, 20, 10, 0}},
437 {11, { 55, 20, 10, 0}},
438 {12, { 60, 55, 20, 0}},
439 {18, { 90, 55, 20, 0}},
440 {22, {110, 55, 20, 0}},
441 {24, {120, 90, 60, 0}},
442 {36, {180, 120, 60, 0}},
443 {44, {220, 180, 60, 0}},
444 {48, {240, 180, 90, 0}},
445 {66, {330, 180, 90, 0}},
446 {72, {360, 240, 90, 0}},
447 {96, {480, 240, 120, 0}},
448 {108, {540, 240, 120, 0}}
Jeff Johnson295189b2012-06-20 16:38:30 -0700449};
450
451/* MCS Based rate table */
452static struct index_data_rate_type supported_mcs_rate[] =
453{
454/* MCS L20 L40 S20 S40 */
455 {0, {65, 135, 72, 150}},
456 {1, {130, 270, 144, 300}},
457 {2, {195, 405, 217, 450}},
458 {3, {260, 540, 289, 600}},
459 {4, {390, 810, 433, 900}},
460 {5, {520, 1080, 578, 1200}},
461 {6, {585, 1215, 650, 1350}},
462 {7, {650, 1350, 722, 1500}}
463};
464
Leo Chang6f8870f2013-03-26 18:11:36 -0700465#ifdef WLAN_FEATURE_11AC
466
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530467#define DATA_RATE_11AC_MCS_MASK 0x03
Leo Chang6f8870f2013-03-26 18:11:36 -0700468
469struct index_vht_data_rate_type
470{
471 v_U8_t beacon_rate_index;
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530472 v_U16_t supported_VHT80_rate[2];
473 v_U16_t supported_VHT40_rate[2];
474 v_U16_t supported_VHT20_rate[2];
Leo Chang6f8870f2013-03-26 18:11:36 -0700475};
476
477typedef enum
478{
479 DATA_RATE_11AC_MAX_MCS_7,
480 DATA_RATE_11AC_MAX_MCS_8,
481 DATA_RATE_11AC_MAX_MCS_9,
482 DATA_RATE_11AC_MAX_MCS_NA
483} eDataRate11ACMaxMcs;
484
485/* MCS Based VHT rate table */
486static struct index_vht_data_rate_type supported_vht_mcs_rate[] =
487{
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530488/* MCS L80 S80 L40 S40 L20 S40*/
489 {0, {293, 325}, {135, 150}, {65, 72}},
490 {1, {585, 650}, {270, 300}, {130, 144}},
491 {2, {878, 975}, {405, 450}, {195, 217}},
492 {3, {1170, 1300}, {540, 600}, {260, 289}},
493 {4, {1755, 1950}, {810, 900}, {390, 433}},
494 {5, {2340, 2600}, {1080, 1200}, {520, 578}},
495 {6, {2633, 2925}, {1215, 1350}, {585, 650}},
496 {7, {2925, 3250}, {1350, 1500}, {650, 722}},
497 {8, {3510, 3900}, {1620, 1800}, {780, 867}},
498 {9, {3900, 4333}, {1800, 2000}, {780, 867}}
Leo Chang6f8870f2013-03-26 18:11:36 -0700499};
500#endif /* WLAN_FEATURE_11AC */
501
Jeff Johnson295189b2012-06-20 16:38:30 -0700502extern struct net_device_ops net_ops_struct;
503
504/*
505 * FUNCTION: wlan_hdd_cfg80211_init
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530506 * This function is called by hdd_wlan_startup()
507 * during initialization.
Jeff Johnson295189b2012-06-20 16:38:30 -0700508 * This function is used to initialize and register wiphy structure.
509 */
510struct wiphy *wlan_hdd_cfg80211_init(int priv_size)
511{
512 struct wiphy *wiphy;
513 ENTER();
514
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530515 /*
516 * Create wiphy device
Jeff Johnson295189b2012-06-20 16:38:30 -0700517 */
518 wiphy = wiphy_new(&wlan_hdd_cfg80211_ops, priv_size);
519
520 if (!wiphy)
521 {
522 /* Print error and jump into err label and free the memory */
523 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wiphy init failed", __func__);
524 return NULL;
525 }
526
527 return wiphy;
528}
529
530/*
531 * FUNCTION: wlan_hdd_cfg80211_update_band
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530532 * This function is called from the supplicant through a
Jeff Johnson295189b2012-06-20 16:38:30 -0700533 * private ioctl to change the band value
534 */
535int wlan_hdd_cfg80211_update_band(struct wiphy *wiphy, eCsrBand eBand)
536{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +0530537 int i, j;
538 eNVChannelEnabledType channelEnabledState;
539
Jeff Johnsone7245742012-09-05 17:12:55 -0700540 ENTER();
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +0530541 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
Jeff Johnson295189b2012-06-20 16:38:30 -0700542 {
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +0530543
544 if (NULL == wiphy->bands[i])
545 {
546 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[i] is NULL, i = %d",
547 __func__, i);
548 continue;
549 }
550
551 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
552 {
553 struct ieee80211_supported_band *band = wiphy->bands[i];
554
555 channelEnabledState = vos_nv_getChannelEnabledState(
556 band->channels[j].hw_value);
557
558 if (IEEE80211_BAND_2GHZ == i && eCSR_BAND_5G == eBand) // 5G only
559 {
560 // Enable Social channels for P2P
561 if (WLAN_HDD_IS_SOCIAL_CHANNEL(band->channels[j].center_freq) &&
562 NV_CHANNEL_ENABLE == channelEnabledState)
563 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
564 else
565 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
566 continue;
567 }
568 else if (IEEE80211_BAND_5GHZ == i && eCSR_BAND_24 == eBand) // 2G only
569 {
570 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
571 continue;
572 }
573
574 if (NV_CHANNEL_DISABLE == channelEnabledState ||
575 NV_CHANNEL_INVALID == channelEnabledState)
576 {
577 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
578 }
579 else if (NV_CHANNEL_DFS == channelEnabledState)
580 {
581 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
582 band->channels[j].flags |= IEEE80211_CHAN_RADAR;
583 }
584 else
585 {
586 band->channels[j].flags &= ~(IEEE80211_CHAN_DISABLED
587 |IEEE80211_CHAN_RADAR);
588 }
589 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700590 }
591 return 0;
592}
593/*
594 * FUNCTION: wlan_hdd_cfg80211_init
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530595 * This function is called by hdd_wlan_startup()
596 * during initialization.
Jeff Johnson295189b2012-06-20 16:38:30 -0700597 * This function is used to initialize and register wiphy structure.
598 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530599int wlan_hdd_cfg80211_register(struct device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -0700600 struct wiphy *wiphy,
601 hdd_config_t *pCfg
602 )
603{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +0530604
605 int i, j;
606
Jeff Johnsone7245742012-09-05 17:12:55 -0700607 ENTER();
608
Jeff Johnson295189b2012-06-20 16:38:30 -0700609 /* Now bind the underlying wlan device with wiphy */
610 set_wiphy_dev(wiphy, dev);
611
612 wiphy->mgmt_stypes = wlan_hdd_txrx_stypes;
613
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -0700614 wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY;
Jeff Johnson295189b2012-06-20 16:38:30 -0700615
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700616#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -0700617 wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME
618 | WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD
619 | WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL
Jeff Johnsone7245742012-09-05 17:12:55 -0700620 | WIPHY_FLAG_OFFCHAN_TX;
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700621#endif
Srinivas Girigowda640728a2013-03-28 12:21:54 -0700622#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_CCX) || defined(FEATURE_WLAN_LFR)
623 if (pCfg->isFastTransitionEnabled
James Zmuda77fb5ae2013-01-29 08:00:17 -0800624#ifdef FEATURE_WLAN_LFR
Srinivas Girigowda640728a2013-03-28 12:21:54 -0700625 || pCfg->isFastRoamIniFeatureEnabled
626#endif
627#ifdef FEATURE_WLAN_CCX
628 || pCfg->isCcxIniFeatureEnabled
629#endif
630 )
631 {
632 wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM;
633 }
James Zmuda77fb5ae2013-01-29 08:00:17 -0800634#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -0800635#ifdef FEATURE_WLAN_TDLS
636 wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS
637 | WIPHY_FLAG_TDLS_EXTERNAL_SETUP;
638#endif
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +0530639#ifdef FEATURE_WLAN_SCAN_PNO
640 wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN;
641 wiphy->max_sched_scan_ssids = MAX_SCAN_SSID;
642 wiphy->max_match_sets = SIR_PNO_MAX_SUPP_NETWORKS;
643#endif/*FEATURE_WLAN_SCAN_PNO*/
Mohit Khanna698ba2a2012-12-04 15:08:18 -0800644
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -0700645 /* even with WIPHY_FLAG_CUSTOM_REGULATORY,
646 driver can still register regulatory callback and
647 it will get CRDA setting in wiphy->band[], but
648 driver need to determine what to do with both
649 regulatory settings */
650 wiphy->reg_notifier = wlan_hdd_crda_reg_notifier;
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700651
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530652 wiphy->max_scan_ssids = MAX_SCAN_SSID;
653
Jeff Johnson295189b2012-06-20 16:38:30 -0700654 wiphy->max_scan_ie_len = 200 ; //TODO: define a macro
655
656 /* Supports STATION & AD-HOC modes right now */
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530657 wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -0700658 | BIT(NL80211_IFTYPE_ADHOC)
Jeff Johnson295189b2012-06-20 16:38:30 -0700659 | BIT(NL80211_IFTYPE_P2P_CLIENT)
660 | BIT(NL80211_IFTYPE_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -0700661 | BIT(NL80211_IFTYPE_AP);
662
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800663#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800664 if( pCfg->enableMCC )
665 {
666 /* Currently, supports up to two channels */
667 wlan_hdd_iface_combination.num_different_channels = 2;
668
669 if( !pCfg->allowMCCGODiffBI )
670 wlan_hdd_iface_combination.beacon_int_infra_match = true;
671
672 }
673 wiphy->iface_combinations = &wlan_hdd_iface_combination;
674 wiphy->n_iface_combinations = 1;
675#endif
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800676
Jeff Johnson295189b2012-06-20 16:38:30 -0700677 /* Before registering we need to update the ht capabilitied based
678 * on ini values*/
679 if( !pCfg->ShortGI20MhzEnable )
680 {
681 wlan_hdd_band_2_4_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
682 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
683 wlan_hdd_band_p2p_2_4_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
684 }
685
686 if( !pCfg->ShortGI40MhzEnable )
687 {
688 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_40;
689 }
690
691 if( !pCfg->nChannelBondingMode5GHz )
692 {
693 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
694 }
695
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +0530696 wiphy->bands[IEEE80211_BAND_2GHZ] = &wlan_hdd_band_2_4_GHZ;
697 wiphy->bands[IEEE80211_BAND_5GHZ] = &wlan_hdd_band_5_GHZ;
698
699 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
700 {
701
702 if (NULL == wiphy->bands[i])
703 {
704 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[i] is NULL, i = %d",
705 __func__, i);
706 continue;
707 }
708
709 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
710 {
711 struct ieee80211_supported_band *band = wiphy->bands[i];
712
713 if (IEEE80211_BAND_2GHZ == i && eCSR_BAND_5G == pCfg->nBandCapability) // 5G only
714 {
715 // Enable social channels for P2P
716 if (WLAN_HDD_IS_SOCIAL_CHANNEL(band->channels[j].center_freq))
717 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
718 else
719 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
720 continue;
721 }
722 else if (IEEE80211_BAND_5GHZ == i && eCSR_BAND_24 == pCfg->nBandCapability) // 2G only
723 {
724 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
725 continue;
726 }
727 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700728 }
729 /*Initialise the supported cipher suite details*/
730 wiphy->cipher_suites = hdd_cipher_suites;
731 wiphy->n_cipher_suites = ARRAY_SIZE(hdd_cipher_suites);
732
733 /*signal strength in mBm (100*dBm) */
734 wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
735
736#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Jeff Johnson295189b2012-06-20 16:38:30 -0700737 wiphy->max_remain_on_channel_duration = 1000;
738#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700739
740 /* Register our wiphy dev with cfg80211 */
741 if (0 > wiphy_register(wiphy))
742 {
743 /* print eror */
744 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
745 return -EIO;
746 }
747
748 EXIT();
749 return 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530750}
Jeff Johnson295189b2012-06-20 16:38:30 -0700751
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -0700752/* In this function we will try to get default country code from crda.
753 If the gCrdaDefaultCountryCode is configured in ini file,
754 we will try to call user space crda to get the regulatory settings for
755 that country. We will timeout if we can't get it from crda.
756 It's called by hdd_wlan_startup() after wlan_hdd_cfg80211_register.
757*/
758int wlan_hdd_get_crda_regd_entry(struct wiphy *wiphy, hdd_config_t *pCfg)
759{
760 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
761 if (memcmp(pCfg->crdaDefaultCountryCode,
762 CFG_CRDA_DEFAULT_COUNTRY_CODE_DEFAULT , 2) != 0)
763 {
764 init_completion(&pHddCtx->driver_crda_req);
765 regulatory_hint(wiphy, pCfg->crdaDefaultCountryCode);
766 wait_for_completion_interruptible_timeout(&pHddCtx->driver_crda_req,
767 CRDA_WAIT_TIME);
Yunsen Wange3ba1fb2013-04-05 15:04:43 -0700768 /* if the country is not found from current regulatory.bin,
769 fall back to world domain */
770 if (is_crda_regulatory_entry_valid() == VOS_FALSE)
771 crda_regulatory_entry_default(pCfg->crdaDefaultCountryCode, NUM_REG_DOMAINS-1);
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -0700772 }
773 return 0;
774}
775
Jeff Johnson295189b2012-06-20 16:38:30 -0700776/* In this function we will do all post VOS start initialization.
777 In this function we will register for all frame in which supplicant
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530778 is interested.
Jeff Johnson295189b2012-06-20 16:38:30 -0700779*/
780void wlan_hdd_cfg80211_post_voss_start(hdd_adapter_t* pAdapter)
781{
Jeff Johnson295189b2012-06-20 16:38:30 -0700782 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
783 /* Register for all P2P action, public action etc frames */
784 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
785
Jeff Johnsone7245742012-09-05 17:12:55 -0700786 ENTER();
787
Jeff Johnson295189b2012-06-20 16:38:30 -0700788 /* Right now we are registering these frame when driver is getting
789 initialized. Once we will move to 2.6.37 kernel, in which we have
790 frame register ops, we will move this code as a part of that */
791 /* GAS Initial Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530792 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Jeff Johnson295189b2012-06-20 16:38:30 -0700793 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
794
795 /* GAS Initial Response */
796 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
797 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530798
Jeff Johnson295189b2012-06-20 16:38:30 -0700799 /* GAS Comeback Request */
800 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
801 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
802
803 /* GAS Comeback Response */
804 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
805 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
806
807 /* P2P Public Action */
808 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530809 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -0700810 P2P_PUBLIC_ACTION_FRAME_SIZE );
811
812 /* P2P Action */
813 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
814 (v_U8_t*)P2P_ACTION_FRAME,
815 P2P_ACTION_FRAME_SIZE );
Chet Lanctot186b5732013-03-18 10:26:30 -0700816
Gopichand Nakkalae3d56e72013-04-21 23:33:32 +0530817 /* WNM BSS Transition Request frame */
818 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
819 (v_U8_t*)WNM_BSS_ACTION_FRAME,
820 WNM_BSS_ACTION_FRAME_SIZE );
821
Chet Lanctot186b5732013-03-18 10:26:30 -0700822#ifdef WLAN_FEATURE_11W
823 /* SA Query Response Action Frame */
824 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
825 (v_U8_t*)SA_QUERY_FRAME_RSP,
826 SA_QUERY_FRAME_RSP_SIZE );
827#endif /* WLAN_FEATURE_11W */
Jeff Johnson295189b2012-06-20 16:38:30 -0700828}
829
830void wlan_hdd_cfg80211_pre_voss_stop(hdd_adapter_t* pAdapter)
831{
Jeff Johnson295189b2012-06-20 16:38:30 -0700832 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
833 /* Register for all P2P action, public action etc frames */
834 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
835
Jeff Johnsone7245742012-09-05 17:12:55 -0700836 ENTER();
837
Jeff Johnson295189b2012-06-20 16:38:30 -0700838 /* Right now we are registering these frame when driver is getting
839 initialized. Once we will move to 2.6.37 kernel, in which we have
840 frame register ops, we will move this code as a part of that */
841 /* GAS Initial Request */
842
843 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
844 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
845
846 /* GAS Initial Response */
847 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
848 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530849
Jeff Johnson295189b2012-06-20 16:38:30 -0700850 /* GAS Comeback Request */
851 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
852 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
853
854 /* GAS Comeback Response */
855 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
856 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
857
858 /* P2P Public Action */
859 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530860 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -0700861 P2P_PUBLIC_ACTION_FRAME_SIZE );
862
863 /* P2P Action */
864 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
865 (v_U8_t*)P2P_ACTION_FRAME,
866 P2P_ACTION_FRAME_SIZE );
Chet Lanctot186b5732013-03-18 10:26:30 -0700867
868#ifdef WLAN_FEATURE_11W
869 /* SA Query Response Action Frame */
870 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
871 (v_U8_t*)SA_QUERY_FRAME_RSP,
872 SA_QUERY_FRAME_RSP_SIZE );
873#endif /* WLAN_FEATURE_11W */
Jeff Johnson295189b2012-06-20 16:38:30 -0700874}
875
876#ifdef FEATURE_WLAN_WAPI
877void wlan_hdd_cfg80211_set_key_wapi(hdd_adapter_t* pAdapter, u8 key_index,
878 const u8 *mac_addr, u8 *key , int key_Len)
879{
880 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
881 tCsrRoamSetKey setKey;
882 v_BOOL_t isConnected = TRUE;
883 int status = 0;
884 v_U32_t roamId= 0xFF;
885 tANI_U8 *pKeyPtr = NULL;
886 int n = 0;
887
888 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",
889 __func__,pAdapter->device_mode);
890
Gopichand Nakkalae7480202013-02-11 15:24:22 +0530891 vos_mem_zero(&setKey, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -0700892 setKey.keyId = key_index; // Store Key ID
893 setKey.encType = eCSR_ENCRYPT_TYPE_WPI; // SET WAPI Encryption
894 setKey.keyDirection = eSIR_TX_RX; // Key Directionn both TX and RX
895 setKey.paeRole = 0 ; // the PAE role
896 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
897 {
898 vos_set_macaddr_broadcast( (v_MACADDR_t *)setKey.peerMac );
899 }
900 else
901 {
902 isConnected = hdd_connIsConnected(pHddStaCtx);
903 vos_mem_copy(setKey.peerMac,&pHddStaCtx->conn_info.bssId,WNI_CFG_BSSID_LEN);
904 }
905 setKey.keyLength = key_Len;
906 pKeyPtr = setKey.Key;
907 memcpy( pKeyPtr, key, key_Len);
908
909 hddLog(VOS_TRACE_LEVEL_INFO,"\n%s: WAPI KEY LENGTH:0x%04x",
910 __func__, key_Len);
911 for (n = 0 ; n < key_Len; n++)
912 hddLog(VOS_TRACE_LEVEL_INFO, "%s WAPI KEY Data[%d]:%02x ",
913 __func__,n,setKey.Key[n]);
914
915 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
916 if ( isConnected )
917 {
918 status= sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
919 pAdapter->sessionId, &setKey, &roamId );
920 }
921 if ( status != 0 )
922 {
923 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
924 "[%4d] sme_RoamSetKey returned ERROR status= %d",
925 __LINE__, status );
926 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
927 }
928}
929#endif /* FEATURE_WLAN_WAPI*/
930
931#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530932int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -0700933 beacon_data_t **ppBeacon,
934 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700935#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530936int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700937 beacon_data_t **ppBeacon,
938 struct cfg80211_beacon_data *params,
939 int dtim_period)
940#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530941{
Jeff Johnson295189b2012-06-20 16:38:30 -0700942 int size;
943 beacon_data_t *beacon = NULL;
944 beacon_data_t *old = NULL;
945 int head_len,tail_len;
946
Jeff Johnsone7245742012-09-05 17:12:55 -0700947 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -0700948 if (params->head && !params->head_len)
949 return -EINVAL;
950
951 old = pAdapter->sessionCtx.ap.beacon;
952
953 if (!params->head && !old)
954 return -EINVAL;
955
956 if (params->tail && !params->tail_len)
957 return -EINVAL;
958
959#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,38))
960 /* Kernel 3.0 is not updating dtim_period for set beacon */
961 if (!params->dtim_period)
962 return -EINVAL;
963#endif
964
965 if(params->head)
966 head_len = params->head_len;
967 else
968 head_len = old->head_len;
969
970 if(params->tail || !old)
971 tail_len = params->tail_len;
972 else
973 tail_len = old->tail_len;
974
975 size = sizeof(beacon_data_t) + head_len + tail_len;
976
977 beacon = kzalloc(size, GFP_KERNEL);
978
979 if( beacon == NULL )
980 return -ENOMEM;
981
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700982#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -0700983 if(params->dtim_period || !old )
984 beacon->dtim_period = params->dtim_period;
985 else
986 beacon->dtim_period = old->dtim_period;
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700987#else
988 if(dtim_period || !old )
989 beacon->dtim_period = dtim_period;
990 else
991 beacon->dtim_period = old->dtim_period;
992#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530993
Jeff Johnson295189b2012-06-20 16:38:30 -0700994 beacon->head = ((u8 *) beacon) + sizeof(beacon_data_t);
995 beacon->tail = beacon->head + head_len;
996 beacon->head_len = head_len;
997 beacon->tail_len = tail_len;
998
999 if(params->head) {
1000 memcpy (beacon->head,params->head,beacon->head_len);
1001 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301002 else {
Jeff Johnson295189b2012-06-20 16:38:30 -07001003 if(old)
1004 memcpy (beacon->head,old->head,beacon->head_len);
1005 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301006
Jeff Johnson295189b2012-06-20 16:38:30 -07001007 if(params->tail) {
1008 memcpy (beacon->tail,params->tail,beacon->tail_len);
1009 }
1010 else {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301011 if(old)
Jeff Johnson295189b2012-06-20 16:38:30 -07001012 memcpy (beacon->tail,old->tail,beacon->tail_len);
1013 }
1014
1015 *ppBeacon = beacon;
1016
1017 kfree(old);
1018
1019 return 0;
1020
1021}
Jeff Johnson295189b2012-06-20 16:38:30 -07001022
1023v_U8_t* wlan_hdd_cfg80211_get_ie_ptr(v_U8_t *pIes, int length, v_U8_t eid)
1024{
1025 int left = length;
1026 v_U8_t *ptr = pIes;
1027 v_U8_t elem_id,elem_len;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301028
Jeff Johnson295189b2012-06-20 16:38:30 -07001029 while(left >= 2)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301030 {
Jeff Johnson295189b2012-06-20 16:38:30 -07001031 elem_id = ptr[0];
1032 elem_len = ptr[1];
1033 left -= 2;
1034 if(elem_len > left)
1035 {
1036 hddLog(VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07001037 FL("****Invalid IEs eid = %d elem_len=%d left=%d*****"),
Jeff Johnson295189b2012-06-20 16:38:30 -07001038 eid,elem_len,left);
1039 return NULL;
1040 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301041 if (elem_id == eid)
Jeff Johnson295189b2012-06-20 16:38:30 -07001042 {
1043 return ptr;
1044 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301045
Jeff Johnson295189b2012-06-20 16:38:30 -07001046 left -= elem_len;
1047 ptr += (elem_len + 2);
1048 }
1049 return NULL;
1050}
1051
Jeff Johnson295189b2012-06-20 16:38:30 -07001052/* Check if rate is 11g rate or not */
1053static int wlan_hdd_rate_is_11g(u8 rate)
1054{
1055 u8 gRateArray[8] = {12, 18, 24, 36, 48, 72, 96, 104}; /* actual rate * 2 */
1056 u8 i;
1057 for (i = 0; i < 8; i++)
1058 {
1059 if(rate == gRateArray[i])
1060 return TRUE;
1061 }
1062 return FALSE;
1063}
1064
1065/* Check for 11g rate and set proper 11g only mode */
1066static void wlan_hdd_check_11gmode(u8 *pIe, u8* require_ht,
1067 u8* pCheckRatesfor11g, eSapPhyMode* pSapHw_mode)
1068{
1069 u8 i, num_rates = pIe[0];
1070
1071 pIe += 1;
1072 for ( i = 0; i < num_rates; i++)
1073 {
1074 if( *pCheckRatesfor11g && (TRUE == wlan_hdd_rate_is_11g(pIe[i] & RATE_MASK)))
1075 {
1076 /* If rate set have 11g rate than change the mode to 11G */
1077 *pSapHw_mode = eSAP_DOT11_MODE_11g;
1078 if (pIe[i] & BASIC_RATE_MASK)
1079 {
1080 /* If we have 11g rate as basic rate, it means mode
1081 is 11g only mode.
1082 */
1083 *pSapHw_mode = eSAP_DOT11_MODE_11g_ONLY;
1084 *pCheckRatesfor11g = FALSE;
1085 }
1086 }
1087 else if((BASIC_RATE_MASK | WLAN_BSS_MEMBERSHIP_SELECTOR_HT_PHY) == pIe[i])
1088 {
1089 *require_ht = TRUE;
1090 }
1091 }
1092 return;
1093}
1094
1095static void wlan_hdd_set_sapHwmode(hdd_adapter_t *pHostapdAdapter)
1096{
1097 tsap_Config_t *pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
1098 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
1099 struct ieee80211_mgmt *pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
1100 u8 checkRatesfor11g = TRUE;
1101 u8 require_ht = FALSE;
1102 u8 *pIe=NULL;
1103
1104 pConfig->SapHw_mode= eSAP_DOT11_MODE_11b;
1105
1106 pIe = wlan_hdd_cfg80211_get_ie_ptr(&pMgmt_frame->u.beacon.variable[0],
1107 pBeacon->head_len, WLAN_EID_SUPP_RATES);
1108 if (pIe != NULL)
1109 {
1110 pIe += 1;
1111 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
1112 &pConfig->SapHw_mode);
1113 }
1114
1115 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
1116 WLAN_EID_EXT_SUPP_RATES);
1117 if (pIe != NULL)
1118 {
1119
1120 pIe += 1;
1121 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
1122 &pConfig->SapHw_mode);
1123 }
1124
1125 if( pConfig->channel > 14 )
1126 {
1127 pConfig->SapHw_mode= eSAP_DOT11_MODE_11a;
1128 }
1129
1130 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
1131 WLAN_EID_HT_CAPABILITY);
1132
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301133 if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07001134 {
1135 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n;
1136 if(require_ht)
1137 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n_ONLY;
1138 }
1139}
1140
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05301141static int wlan_hdd_add_ie(hdd_adapter_t* pHostapdAdapter, v_U8_t *genie,
1142 v_U8_t *total_ielen, v_U8_t *oui, v_U8_t oui_size)
1143{
1144 v_U8_t ielen = 0;
1145 v_U8_t *pIe = NULL;
1146 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
1147
1148 pIe = wlan_hdd_get_vendor_oui_ie_ptr(oui, oui_size,
1149 pBeacon->tail, pBeacon->tail_len);
1150
1151 if (pIe)
1152 {
1153 ielen = pIe[1] + 2;
1154 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
1155 {
1156 vos_mem_copy(&genie[*total_ielen], pIe, ielen);
1157 }
1158 else
1159 {
1160 hddLog( VOS_TRACE_LEVEL_ERROR, "**Ie Length is too big***");
1161 return -EINVAL;
1162 }
1163 *total_ielen += ielen;
1164 }
1165 return 0;
1166}
1167
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001168#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07001169static int wlan_hdd_cfg80211_update_apies(hdd_adapter_t* pHostapdAdapter,
1170 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001171#else
1172static int wlan_hdd_cfg80211_update_apies(hdd_adapter_t* pHostapdAdapter,
1173 struct cfg80211_beacon_data *params)
1174#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07001175{
1176 v_U8_t *genie;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05301177 v_U8_t total_ielen = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07001178 v_U8_t addIE[1] = {0};
Jeff Johnsone7245742012-09-05 17:12:55 -07001179 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07001180
1181 genie = vos_mem_malloc(MAX_GENIE_LEN);
1182
1183 if(genie == NULL) {
1184
1185 return -ENOMEM;
1186 }
1187
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05301188 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
1189 &total_ielen, WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07001190 {
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05301191 ret = -EINVAL;
1192 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001193 }
1194
1195#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05301196 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
1197 &total_ielen, WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE))
1198 {
1199 ret = -EINVAL;
1200 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001201 }
1202#endif
1203
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05301204 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
1205 &total_ielen, P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07001206 {
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05301207 ret = -EINVAL;
1208 goto done;
1209 }
1210
1211 if (WLAN_HDD_SOFTAP == pHostapdAdapter->device_mode)
1212 {
1213 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
1214 &total_ielen, SS_OUI_TYPE, SS_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07001215 {
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05301216 ret = -EINVAL;
1217 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001218 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001219 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001220
1221 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1222 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, genie, total_ielen, NULL,
1223 eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
1224 {
1225 hddLog(LOGE,
1226 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001227 ret = -EINVAL;
1228 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001229 }
1230
1231 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1232 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
1233 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
1234 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
1235 ==eHAL_STATUS_FAILURE)
1236 {
1237 hddLog(LOGE,
1238 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001239 ret = -EINVAL;
1240 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001241 }
1242
1243 // Added for ProResp IE
1244 if ( (params->proberesp_ies != NULL) && (params->proberesp_ies_len != 0) )
1245 {
1246 u16 rem_probe_resp_ie_len = params->proberesp_ies_len;
1247 u8 probe_rsp_ie_len[3] = {0};
1248 u8 counter = 0;
1249 /* Check Probe Resp Length if it is greater then 255 then Store
1250 Probe Resp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1 &
1251 WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are not able
1252 Store More then 255 bytes into One Variable.
1253 */
1254 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
1255 {
1256 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
1257 {
1258 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
1259 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
1260 }
1261 else
1262 {
1263 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
1264 rem_probe_resp_ie_len = 0;
1265 }
1266 }
1267
1268 rem_probe_resp_ie_len = 0;
1269
1270 if (probe_rsp_ie_len[0] > 0)
1271 {
1272 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1273 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
1274 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
1275 probe_rsp_ie_len[0], NULL,
1276 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
1277 {
1278 hddLog(LOGE,
1279 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001280 ret = -EINVAL;
1281 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001282 }
1283 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
1284 }
1285
1286 if (probe_rsp_ie_len[1] > 0)
1287 {
1288 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1289 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
1290 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
1291 probe_rsp_ie_len[1], NULL,
1292 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
1293 {
1294 hddLog(LOGE,
1295 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001296 ret = -EINVAL;
1297 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001298 }
1299 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
1300 }
1301
1302 if (probe_rsp_ie_len[2] > 0)
1303 {
1304 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1305 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
1306 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
1307 probe_rsp_ie_len[2], NULL,
1308 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
1309 {
1310 hddLog(LOGE,
1311 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001312 ret = -EINVAL;
1313 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001314 }
1315 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
1316 }
1317
1318 if (probe_rsp_ie_len[1] == 0 )
1319 {
1320 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1321 WNI_CFG_PROBE_RSP_ADDNIE_DATA2, (tANI_U8*)addIE, 0, NULL,
1322 eANI_BOOLEAN_FALSE) )
1323 {
1324 hddLog(LOGE,
1325 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM\n");
1326 }
1327 }
1328
1329 if (probe_rsp_ie_len[2] == 0 )
1330 {
1331 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1332 WNI_CFG_PROBE_RSP_ADDNIE_DATA3, (tANI_U8*)addIE, 0, NULL,
1333 eANI_BOOLEAN_FALSE) )
1334 {
1335 hddLog(LOGE,
1336 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM\n");
1337 }
1338 }
1339
1340 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1341 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
1342 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
1343 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
1344 == eHAL_STATUS_FAILURE)
1345 {
1346 hddLog(LOGE,
1347 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001348 ret = -EINVAL;
1349 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001350 }
1351 }
1352 else
1353 {
1354 // Reset WNI_CFG_PROBE_RSP Flags
1355 wlan_hdd_reset_prob_rspies(pHostapdAdapter);
1356
1357 hddLog(VOS_TRACE_LEVEL_INFO,
1358 "%s: No Probe Response IE received in set beacon",
1359 __func__);
1360 }
1361
1362 // Added for AssocResp IE
1363 if ( (params->assocresp_ies != NULL) && (params->assocresp_ies_len != 0) )
1364 {
1365 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1366 WNI_CFG_ASSOC_RSP_ADDNIE_DATA, (tANI_U8*)params->assocresp_ies,
1367 params->assocresp_ies_len, NULL,
1368 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
1369 {
1370 hddLog(LOGE,
1371 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001372 ret = -EINVAL;
1373 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001374 }
1375
1376 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1377 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 1, NULL,
1378 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
1379 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
1380 == eHAL_STATUS_FAILURE)
1381 {
1382 hddLog(LOGE,
1383 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001384 ret = -EINVAL;
1385 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001386 }
1387 }
1388 else
1389 {
1390 hddLog(VOS_TRACE_LEVEL_INFO,
1391 "%s: No Assoc Response IE received in set beacon",
1392 __func__);
1393
1394 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1395 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
1396 eANI_BOOLEAN_FALSE) )
1397 {
1398 hddLog(LOGE,
1399 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM\n");
1400 }
1401 }
1402
Jeff Johnsone7245742012-09-05 17:12:55 -07001403done:
Jeff Johnson295189b2012-06-20 16:38:30 -07001404 vos_mem_free(genie);
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05301405 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07001406}
Jeff Johnson295189b2012-06-20 16:38:30 -07001407
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301408/*
Jeff Johnson295189b2012-06-20 16:38:30 -07001409 * FUNCTION: wlan_hdd_validate_operation_channel
1410 * called by wlan_hdd_cfg80211_start_bss() and
1411 * wlan_hdd_cfg80211_set_channel()
1412 * This function validates whether given channel is part of valid
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301413 * channel list.
1414 */
Jeff Johnson295189b2012-06-20 16:38:30 -07001415static VOS_STATUS wlan_hdd_validate_operation_channel(hdd_adapter_t *pAdapter,int channel)
1416{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301417
Jeff Johnson295189b2012-06-20 16:38:30 -07001418 v_U32_t num_ch = 0;
1419 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN];
1420 u32 indx = 0;
1421 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05301422 v_U8_t fValidChannel = FALSE, count = 0;
1423 hdd_config_t *hdd_pConfig_ini= (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301424
Jeff Johnson295189b2012-06-20 16:38:30 -07001425 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
1426
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05301427 if ( hdd_pConfig_ini->sapAllowAllChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -07001428 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05301429 /* Validate the channel */
1430 for (count = RF_CHAN_1 ; count <= RF_CHAN_165 ; count++)
Jeff Johnson295189b2012-06-20 16:38:30 -07001431 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05301432 if ( channel == rfChannels[count].channelNum )
1433 {
1434 fValidChannel = TRUE;
1435 break;
1436 }
1437 }
1438 if (fValidChannel != TRUE)
1439 {
1440 hddLog(VOS_TRACE_LEVEL_ERROR,
1441 "%s: Invalid Channel [%d]", __func__, channel);
1442 return VOS_STATUS_E_FAILURE;
Jeff Johnson295189b2012-06-20 16:38:30 -07001443 }
1444 }
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05301445 else
Jeff Johnson295189b2012-06-20 16:38:30 -07001446 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05301447 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
1448 valid_ch, &num_ch))
1449 {
1450 hddLog(VOS_TRACE_LEVEL_ERROR,
1451 "%s: failed to get valid channel list", __func__);
1452 return VOS_STATUS_E_FAILURE;
1453 }
1454 for (indx = 0; indx < num_ch; indx++)
1455 {
1456 if (channel == valid_ch[indx])
1457 {
1458 break;
1459 }
1460 }
1461
1462 if (indx >= num_ch)
1463 {
1464 hddLog(VOS_TRACE_LEVEL_ERROR,
1465 "%s: Invalid Channel [%d]", __func__, channel);
1466 return VOS_STATUS_E_FAILURE;
1467 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001468 }
1469 return VOS_STATUS_SUCCESS;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301470
Jeff Johnson295189b2012-06-20 16:38:30 -07001471}
1472
Viral Modi3a32cc52013-02-08 11:14:52 -08001473/**
1474 * FUNCTION: wlan_hdd_cfg80211_set_channel
1475 * This function is used to set the channel number
1476 */
1477static int wlan_hdd_cfg80211_set_channel( struct wiphy *wiphy, struct net_device *dev,
1478 struct ieee80211_channel *chan,
1479 enum nl80211_channel_type channel_type
1480 )
1481{
1482 v_U32_t num_ch = 0;
Jeff Johnson4416a782013-03-25 14:17:50 -07001483 int channel = 0;
Viral Modi3a32cc52013-02-08 11:14:52 -08001484 hdd_adapter_t *pAdapter = NULL;
1485 int freq = chan->center_freq; /* freq is in MHZ */
1486
1487 ENTER();
1488
1489 if( NULL == dev )
1490 {
1491 hddLog(VOS_TRACE_LEVEL_ERROR,
1492 "%s: Called with dev = NULL.\n", __func__);
1493 return -ENODEV;
1494 }
1495 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
1496
1497 hddLog(VOS_TRACE_LEVEL_INFO,
1498 "%s: device_mode = %d freq = %d \n",__func__,
1499 pAdapter->device_mode, chan->center_freq);
1500 if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress)
1501 {
1502 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:LOGP in Progress. Ignore!!!",__func__);
1503 return -EAGAIN;
1504 }
1505
1506 /*
1507 * Do freq to chan conversion
1508 * TODO: for 11a
1509 */
1510
1511 channel = ieee80211_frequency_to_channel(freq);
1512
1513 /* Check freq range */
1514 if ((WNI_CFG_CURRENT_CHANNEL_STAMIN > channel) ||
1515 (WNI_CFG_CURRENT_CHANNEL_STAMAX < channel))
1516 {
1517 hddLog(VOS_TRACE_LEVEL_ERROR,
1518 "%s: Channel [%d] is outside valid range from %d to %d\n",
1519 __func__, channel, WNI_CFG_CURRENT_CHANNEL_STAMIN,
1520 WNI_CFG_CURRENT_CHANNEL_STAMAX);
1521 return -EINVAL;
1522 }
1523
1524 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
1525
Gopichand Nakkala6ab19562013-03-07 13:59:42 +05301526 if ((WLAN_HDD_SOFTAP != pAdapter->device_mode) &&
1527 (WLAN_HDD_P2P_GO != pAdapter->device_mode))
Viral Modi3a32cc52013-02-08 11:14:52 -08001528 {
1529 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pAdapter,channel))
1530 {
1531 hddLog(VOS_TRACE_LEVEL_ERROR,
1532 "%s: Invalid Channel [%d] \n", __func__, channel);
1533 return -EINVAL;
1534 }
1535 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
1536 "%s: set channel to [%d] for device mode =%d",
1537 __func__, channel,pAdapter->device_mode);
1538 }
1539 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Viral Modi3a32cc52013-02-08 11:14:52 -08001540 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Viral Modi3a32cc52013-02-08 11:14:52 -08001541 )
1542 {
1543 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
1544 tCsrRoamProfile * pRoamProfile = &pWextState->roamProfile;
1545 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
1546
1547 if (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState)
1548 {
1549 /* Link is up then return cant set channel*/
1550 hddLog( VOS_TRACE_LEVEL_ERROR,
1551 "%s: IBSS Associated, can't set the channel\n", __func__);
1552 return -EINVAL;
1553 }
1554
1555 num_ch = pRoamProfile->ChannelInfo.numOfChannels = 1;
1556 pHddStaCtx->conn_info.operationChannel = channel;
1557 pRoamProfile->ChannelInfo.ChannelList =
1558 &pHddStaCtx->conn_info.operationChannel;
1559 }
1560 else if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Viral Modi3a32cc52013-02-08 11:14:52 -08001561 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Viral Modi3a32cc52013-02-08 11:14:52 -08001562 )
1563 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05301564 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
1565 {
1566 if(VOS_STATUS_SUCCESS !=
1567 wlan_hdd_validate_operation_channel(pAdapter,channel))
1568 {
1569 hddLog(VOS_TRACE_LEVEL_ERROR,
1570 "%s: Invalid Channel [%d] \n", __func__, channel);
1571 return -EINVAL;
1572 }
1573 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
1574 }
1575 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
Viral Modi3a32cc52013-02-08 11:14:52 -08001576 {
1577 hdd_config_t *cfg_param = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
1578
1579 /* If auto channel selection is configured as enable/ 1 then ignore
1580 channel set by supplicant
1581 */
1582 if ( cfg_param->apAutoChannelSelection )
1583 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05301584 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel =
1585 AUTO_CHANNEL_SELECT;
Viral Modi3a32cc52013-02-08 11:14:52 -08001586 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
1587 "%s: set channel to auto channel (0) for device mode =%d",
1588 __func__, pAdapter->device_mode);
1589 }
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05301590 else
1591 {
1592 if(VOS_STATUS_SUCCESS !=
1593 wlan_hdd_validate_operation_channel(pAdapter,channel))
1594 {
1595 hddLog(VOS_TRACE_LEVEL_ERROR,
1596 "%s: Invalid Channel [%d] \n", __func__, channel);
1597 return -EINVAL;
1598 }
1599 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
1600 }
Viral Modi3a32cc52013-02-08 11:14:52 -08001601 }
1602 }
1603 else
1604 {
1605 hddLog(VOS_TRACE_LEVEL_FATAL,
1606 "%s: Invalid device mode failed to set valid channel", __func__);
1607 return -EINVAL;
1608 }
1609 EXIT();
1610 return 0;
1611}
1612
Jeff Johnson295189b2012-06-20 16:38:30 -07001613#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
1614static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
1615 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001616#else
1617static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
1618 struct cfg80211_beacon_data *params,
1619 const u8 *ssid, size_t ssid_len,
1620 enum nl80211_hidden_ssid hidden_ssid)
1621#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07001622{
1623 tsap_Config_t *pConfig;
1624 beacon_data_t *pBeacon = NULL;
1625 struct ieee80211_mgmt *pMgmt_frame;
1626 v_U8_t *pIe=NULL;
1627 v_U16_t capab_info;
1628 eCsrAuthType RSNAuthType;
1629 eCsrEncryptionType RSNEncryptType;
1630 eCsrEncryptionType mcRSNEncryptType;
1631 int status = VOS_STATUS_SUCCESS;
1632 tpWLAN_SAPEventCB pSapEventCallback;
1633 hdd_hostapd_state_t *pHostapdState;
1634 v_U8_t wpaRsnIEdata[(SIR_MAC_MAX_IE_LENGTH * 2)+4]; //Max ie length 255 * 2(WPA+RSN) + 2 bytes (vendor specific ID) * 2
1635 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05301636 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07001637 struct qc_mac_acl_entry *acl_entry = NULL;
1638 v_SINT_t i;
Madan Mohan Koyyalamudi543172b2012-12-05 16:40:18 -08001639 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07001640
1641 ENTER();
1642
1643 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter);
1644
1645 pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
1646
1647 pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
1648
1649 pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
1650
1651 pConfig->beacon_int = pMgmt_frame->u.beacon.beacon_int;
1652
1653 //channel is already set in the set_channel Call back
1654 //pConfig->channel = pCommitConfig->channel;
1655
1656 /*Protection parameter to enable or disable*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301657 pConfig->protEnabled =
Jeff Johnson295189b2012-06-20 16:38:30 -07001658 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtEnabled;
1659
1660 pConfig->dtim_period = pBeacon->dtim_period;
1661
1662 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"****pConfig->dtim_period=%d***\n",
1663 pConfig->dtim_period);
1664
1665
Madan Mohan Koyyalamudie0ca11f2012-11-27 15:57:52 -08001666 if (pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson32d95a32012-09-10 13:15:23 -07001667 {
1668 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -07001669 WLAN_EID_COUNTRY);
Jeff Johnson32d95a32012-09-10 13:15:23 -07001670 if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07001671 {
Jeff Johnson32d95a32012-09-10 13:15:23 -07001672 tANI_BOOLEAN restartNeeded;
Jeff Johnson32d95a32012-09-10 13:15:23 -07001673 pConfig->ieee80211d = 1;
1674 vos_mem_copy(pConfig->countryCode, &pIe[2], 3);
1675 sme_setRegInfo(hHal, pConfig->countryCode);
1676 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
Jeff Johnson295189b2012-06-20 16:38:30 -07001677 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07001678 else
1679 {
1680 pConfig->ieee80211d = 0;
1681 }
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05301682 /*
1683 * If auto channel is configured i.e. channel is 0,
1684 * so skip channel validation.
1685 */
1686 if( AUTO_CHANNEL_SELECT != pConfig->channel )
1687 {
1688 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pHostapdAdapter,pConfig->channel))
1689 {
1690 hddLog(VOS_TRACE_LEVEL_ERROR,
1691 "%s: Invalid Channel [%d] \n", __func__, pConfig->channel);
1692 return -EINVAL;
1693 }
1694 }
1695 else
1696 {
1697 if(1 != pHddCtx->is_dynamic_channel_range_set)
1698 {
1699 hdd_config_t *hdd_pConfig= (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini;
1700 WLANSAP_SetChannelRange(hHal, hdd_pConfig->apStartChannelNum,
1701 hdd_pConfig->apEndChannelNum,hdd_pConfig->apOperatingBand);
1702 }
1703 pHddCtx->is_dynamic_channel_range_set = 0;
1704 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001705 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07001706 else
Jeff Johnson295189b2012-06-20 16:38:30 -07001707 {
1708 pConfig->ieee80211d = 0;
1709 }
1710 pConfig->authType = eSAP_AUTO_SWITCH;
1711
1712 capab_info = pMgmt_frame->u.beacon.capab_info;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301713
1714 pConfig->privacy = (pMgmt_frame->u.beacon.capab_info &
Jeff Johnson295189b2012-06-20 16:38:30 -07001715 WLAN_CAPABILITY_PRIVACY) ? VOS_TRUE : VOS_FALSE;
1716
1717 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uPrivacy = pConfig->privacy;
1718
1719 /*Set wps station to configured*/
1720 pIe = wlan_hdd_get_wps_ie_ptr(pBeacon->tail, pBeacon->tail_len);
1721
1722 if(pIe)
1723 {
1724 if(pIe[1] < (2 + WPS_OUI_TYPE_SIZE))
1725 {
1726 hddLog( VOS_TRACE_LEVEL_ERROR, "**Wps Ie Length is too small***\n");
1727 return -EINVAL;
1728 }
1729 else if(memcmp(&pIe[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) == 0)
1730 {
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07001731 hddLog( VOS_TRACE_LEVEL_INFO, "** WPS IE(len %d) ***", (pIe[1]+2));
Jeff Johnson295189b2012-06-20 16:38:30 -07001732 /* Check 15 bit of WPS IE as it contain information for wps state
1733 * WPS state
1734 */
1735 if(SAP_WPS_ENABLED_UNCONFIGURED == pIe[15])
1736 {
1737 pConfig->wps_state = SAP_WPS_ENABLED_UNCONFIGURED;
1738 } else if(SAP_WPS_ENABLED_CONFIGURED == pIe[15])
1739 {
1740 pConfig->wps_state = SAP_WPS_ENABLED_CONFIGURED;
1741 }
1742 }
1743 }
1744 else
1745 {
1746 pConfig->wps_state = SAP_WPS_DISABLED;
1747 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301748 pConfig->fwdWPSPBCProbeReq = 1; // Forward WPS PBC probe request frame up
Jeff Johnson295189b2012-06-20 16:38:30 -07001749
1750 pConfig->RSNWPAReqIELength = 0;
1751 pConfig->pRSNWPAReqIE = NULL;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301752 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -07001753 WLAN_EID_RSN);
1754 if(pIe && pIe[1])
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301755 {
Jeff Johnson295189b2012-06-20 16:38:30 -07001756 pConfig->RSNWPAReqIELength = pIe[1] + 2;
1757 memcpy(&wpaRsnIEdata[0], pIe, pConfig->RSNWPAReqIELength);
1758 pConfig->pRSNWPAReqIE = &wpaRsnIEdata[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301759 /* The actual processing may eventually be more extensive than
1760 * this. Right now, just consume any PMKIDs that are sent in
Jeff Johnson295189b2012-06-20 16:38:30 -07001761 * by the app.
1762 * */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301763 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -07001764 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
1765 &RSNEncryptType,
1766 &mcRSNEncryptType,
1767 &RSNAuthType,
1768 pConfig->pRSNWPAReqIE[1]+2,
1769 pConfig->pRSNWPAReqIE );
1770
1771 if( VOS_STATUS_SUCCESS == status )
1772 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301773 /* Now copy over all the security attributes you have
1774 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -07001775 * */
1776 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
1777 pConfig->mcRSNEncryptType = mcRSNEncryptType;
1778 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
1779 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05301780 hddLog( LOG1, FL("CSR AuthType = %d, "
Jeff Johnson295189b2012-06-20 16:38:30 -07001781 "EncryptionType = %d mcEncryptionType = %d\n"),
1782 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
1783 }
1784 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301785
Jeff Johnson295189b2012-06-20 16:38:30 -07001786 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE,
1787 pBeacon->tail, pBeacon->tail_len);
1788
1789 if(pIe && pIe[1] && (pIe[0] == DOT11F_EID_WPA))
1790 {
1791 if (pConfig->pRSNWPAReqIE)
1792 {
1793 /*Mixed mode WPA/WPA2*/
1794 memcpy((&wpaRsnIEdata[0] + pConfig->RSNWPAReqIELength), pIe, pIe[1] + 2);
1795 pConfig->RSNWPAReqIELength += pIe[1] + 2;
1796 }
1797 else
1798 {
1799 pConfig->RSNWPAReqIELength = pIe[1] + 2;
1800 memcpy(&wpaRsnIEdata[0], pIe, pConfig->RSNWPAReqIELength);
1801 pConfig->pRSNWPAReqIE = &wpaRsnIEdata[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301802 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -07001803 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
1804 &RSNEncryptType,
1805 &mcRSNEncryptType,
1806 &RSNAuthType,
1807 pConfig->pRSNWPAReqIE[1]+2,
1808 pConfig->pRSNWPAReqIE );
1809
1810 if( VOS_STATUS_SUCCESS == status )
1811 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301812 /* Now copy over all the security attributes you have
1813 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -07001814 * */
1815 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
1816 pConfig->mcRSNEncryptType = mcRSNEncryptType;
1817 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
1818 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05301819 hddLog( LOG1, FL("CSR AuthType = %d, "
Jeff Johnson295189b2012-06-20 16:38:30 -07001820 "EncryptionType = %d mcEncryptionType = %d\n"),
1821 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
1822 }
1823 }
1824 }
1825
Jeff Johnson4416a782013-03-25 14:17:50 -07001826 if (pConfig->RSNWPAReqIELength > sizeof wpaRsnIEdata) {
1827 hddLog( VOS_TRACE_LEVEL_ERROR, "**RSNWPAReqIELength is too large***");
1828 return -EINVAL;
1829 }
1830
Jeff Johnson295189b2012-06-20 16:38:30 -07001831 pConfig->SSIDinfo.ssidHidden = VOS_FALSE;
1832
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001833#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07001834 if (params->ssid != NULL)
1835 {
1836 memcpy(pConfig->SSIDinfo.ssid.ssId, params->ssid, params->ssid_len);
1837 pConfig->SSIDinfo.ssid.length = params->ssid_len;
1838 if (params->hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
1839 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
1840 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001841#else
1842 if (ssid != NULL)
1843 {
1844 memcpy(pConfig->SSIDinfo.ssid.ssId, ssid, ssid_len);
1845 pConfig->SSIDinfo.ssid.length = ssid_len;
1846 if (hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
1847 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
1848 }
1849#endif
1850
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301851 vos_mem_copy(pConfig->self_macaddr.bytes,
Jeff Johnson295189b2012-06-20 16:38:30 -07001852 pHostapdAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301853
Jeff Johnson295189b2012-06-20 16:38:30 -07001854 /* default value */
1855 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
1856 pConfig->num_accept_mac = 0;
1857 pConfig->num_deny_mac = 0;
1858
1859 pIe = wlan_hdd_get_vendor_oui_ie_ptr(BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
1860 pBeacon->tail, pBeacon->tail_len);
1861
1862 /* pIe for black list is following form:
1863 type : 1 byte
1864 length : 1 byte
1865 OUI : 4 bytes
1866 acl type : 1 byte
1867 no of mac addr in black list: 1 byte
1868 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301869 */
1870 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07001871 {
1872 pConfig->SapMacaddr_acl = pIe[6];
1873 pConfig->num_deny_mac = pIe[7];
1874 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no deny mac = %d\n",
1875 pIe[6], pIe[7]);
1876 if (pConfig->num_deny_mac > MAX_MAC_ADDRESS_DENIED)
1877 pConfig->num_deny_mac = MAX_MAC_ADDRESS_DENIED;
1878 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
1879 for (i = 0; i < pConfig->num_deny_mac; i++)
1880 {
1881 vos_mem_copy(&pConfig->deny_mac[i], acl_entry->addr, sizeof(qcmacaddr));
1882 acl_entry++;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301883 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001884 }
1885 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
1886 pBeacon->tail, pBeacon->tail_len);
1887
1888 /* pIe for white list is following form:
1889 type : 1 byte
1890 length : 1 byte
1891 OUI : 4 bytes
1892 acl type : 1 byte
1893 no of mac addr in white list: 1 byte
1894 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301895 */
1896 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07001897 {
1898 pConfig->SapMacaddr_acl = pIe[6];
1899 pConfig->num_accept_mac = pIe[7];
1900 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no accept mac = %d\n",
1901 pIe[6], pIe[7]);
1902 if (pConfig->num_accept_mac > MAX_MAC_ADDRESS_ACCEPTED)
1903 pConfig->num_accept_mac = MAX_MAC_ADDRESS_ACCEPTED;
1904 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
1905 for (i = 0; i < pConfig->num_accept_mac; i++)
1906 {
1907 vos_mem_copy(&pConfig->accept_mac[i], acl_entry->addr, sizeof(qcmacaddr));
1908 acl_entry++;
1909 }
1910 }
1911 wlan_hdd_set_sapHwmode(pHostapdAdapter);
1912
Jeff Johnsone7245742012-09-05 17:12:55 -07001913#ifdef WLAN_FEATURE_11AC
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -08001914 /* Overwrite the hostapd setting for HW mode only for 11ac.
1915 * This is valid only if mode is set to 11n in hostapd and either AUTO or 11ac in .ini .
1916 * Otherwise, leave whatever is set in hostapd (a OR b OR g OR n mode) */
1917 if( ((pConfig->SapHw_mode == eSAP_DOT11_MODE_11n) ||
1918 (pConfig->SapHw_mode == eSAP_DOT11_MODE_11n_ONLY)) &&
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301919 (((WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->dot11Mode == eHDD_DOT11_MODE_AUTO) ||
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -08001920 ((WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->dot11Mode == eHDD_DOT11_MODE_11ac) ||
1921 ((WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->dot11Mode == eHDD_DOT11_MODE_11ac_ONLY)) )
Jeff Johnsone7245742012-09-05 17:12:55 -07001922 {
1923 pConfig->SapHw_mode = eSAP_DOT11_MODE_11ac;
1924 }
1925#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301926
Ravi Joshiaeb7d9e2013-05-02 12:28:14 -07001927 if ( AUTO_CHANNEL_SELECT != pConfig->channel )
1928 {
1929 sme_SelectCBMode(hHal,
1930 sapConvertSapPhyModeToCsrPhyMode(pConfig->SapHw_mode),
1931 pConfig->channel);
1932 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001933 // ht_capab is not what the name conveys,this is used for protection bitmap
1934 pConfig->ht_capab =
1935 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtection;
1936
1937 if ( 0 != wlan_hdd_cfg80211_update_apies(pHostapdAdapter, params) )
1938 {
1939 hddLog(LOGE, FL("SAP Not able to set AP IEs"));
1940 return -EINVAL;
1941 }
1942
1943 //Uapsd Enabled Bit
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301944 pConfig->UapsdEnable =
Jeff Johnson295189b2012-06-20 16:38:30 -07001945 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apUapsdEnabled;
1946 //Enable OBSS protection
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301947 pConfig->obssProtEnabled =
1948 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apOBSSProtEnabled;
Jeff Johnson295189b2012-06-20 16:38:30 -07001949
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301950 hddLog(LOGW, FL("SOftAP macaddress : "MAC_ADDRESS_STR"\n"),
Jeff Johnson295189b2012-06-20 16:38:30 -07001951 MAC_ADDR_ARRAY(pHostapdAdapter->macAddressCurrent.bytes));
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301952 hddLog(LOGW,FL("ssid =%s\n"), pConfig->SSIDinfo.ssid.ssId);
Jeff Johnson295189b2012-06-20 16:38:30 -07001953 hddLog(LOGW,FL("beaconint=%d, channel=%d\n"), (int)pConfig->beacon_int,
1954 (int)pConfig->channel);
1955 hddLog(LOGW,FL("hw_mode=%x\n"), pConfig->SapHw_mode);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301956 hddLog(LOGW,FL("privacy=%d, authType=%d\n"), pConfig->privacy,
1957 pConfig->authType);
Jeff Johnson295189b2012-06-20 16:38:30 -07001958 hddLog(LOGW,FL("RSN/WPALen=%d, \n"),(int)pConfig->RSNWPAReqIELength);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301959 hddLog(LOGW,FL("Uapsd = %d\n"),pConfig->UapsdEnable);
Jeff Johnson295189b2012-06-20 16:38:30 -07001960 hddLog(LOGW,FL("ProtEnabled = %d, OBSSProtEnabled = %d\n"),
1961 pConfig->protEnabled, pConfig->obssProtEnabled);
1962
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301963 if(test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -07001964 {
1965 //Bss already started. just return.
1966 //TODO Probably it should update some beacon params.
1967 hddLog( LOGE, "Bss Already started...Ignore the request");
1968 EXIT();
1969 return 0;
1970 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301971
Jeff Johnson295189b2012-06-20 16:38:30 -07001972 pConfig->persona = pHostapdAdapter->device_mode;
1973
1974 pSapEventCallback = hdd_hostapd_SAPEventCB;
1975 if(WLANSAP_StartBss(pVosContext, pSapEventCallback, pConfig,
1976 (v_PVOID_t)pHostapdAdapter->dev) != VOS_STATUS_SUCCESS)
1977 {
1978 hddLog(LOGE,FL("SAP Start Bss fail\n"));
1979 return -EINVAL;
1980 }
1981
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301982 hddLog(LOG1,
Jeff Johnson295189b2012-06-20 16:38:30 -07001983 FL("Waiting for Scan to complete(auto mode) and BSS to start"));
1984
1985 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301986
Jeff Johnson295189b2012-06-20 16:38:30 -07001987 if (!VOS_IS_STATUS_SUCCESS(status))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301988 {
1989 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07001990 ("ERROR: HDD vos wait for single_event failed!!\n"));
1991 VOS_ASSERT(0);
1992 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301993
Jeff Johnson295189b2012-06-20 16:38:30 -07001994 //Succesfully started Bss update the state bit.
1995 set_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags);
1996
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07001997#ifdef WLAN_FEATURE_P2P_DEBUG
1998 if (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO)
1999 {
2000 if(globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED)
2001 {
2002 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
2003 hddLog(LOGE,"[P2P State] From Go nego completed to "
Jeff Johnson1250df42012-12-10 14:31:52 -08002004 "Non-autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07002005 }
2006 else if(globalP2PConnectionStatus == P2P_NOT_ACTIVE)
2007 {
2008 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
2009 hddLog(LOGE,"[P2P State] From Inactive to "
Jeff Johnson1250df42012-12-10 14:31:52 -08002010 "Autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07002011 }
2012 }
2013#endif
2014
Jeff Johnson295189b2012-06-20 16:38:30 -07002015 pHostapdState->bCommit = TRUE;
2016 EXIT();
2017
2018 return 0;
2019}
2020
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002021#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302022static int wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy,
2023 struct net_device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -07002024 struct beacon_parameters *params)
2025{
2026 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302027 int status=VOS_STATUS_SUCCESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07002028
2029 ENTER();
2030
2031 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "device mode=%d\n",pAdapter->device_mode);
2032
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002033 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
2034 {
2035 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2036 "%s:LOGP in Progress. Ignore!!!", __func__);
2037 return -EAGAIN;
2038 }
2039
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302040 if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07002041 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07002042 )
2043 {
2044 beacon_data_t *old,*new;
2045
2046 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302047
Jeff Johnson295189b2012-06-20 16:38:30 -07002048 if (old)
2049 return -EALREADY;
2050
2051 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
2052
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302053 if(status != VOS_STATUS_SUCCESS)
Jeff Johnson295189b2012-06-20 16:38:30 -07002054 {
2055 hddLog(VOS_TRACE_LEVEL_FATAL,
2056 "%s:Error!!! Allocating the new beacon\n",__func__);
2057 return -EINVAL;
2058 }
2059
2060 pAdapter->sessionCtx.ap.beacon = new;
2061
2062 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
2063 }
2064
2065 EXIT();
2066 return status;
2067}
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302068
2069static int wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07002070 struct net_device *dev,
2071 struct beacon_parameters *params)
2072{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302073 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnson295189b2012-06-20 16:38:30 -07002074 int status=VOS_STATUS_SUCCESS;
2075
2076 ENTER();
2077
2078 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",
2079 __func__,pAdapter->device_mode);
2080
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002081 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
2082 {
2083 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2084 "%s:LOGP in Progress. Ignore!!!", __func__);
2085 return -EAGAIN;
2086 }
2087
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302088 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07002089 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302090 )
Jeff Johnson295189b2012-06-20 16:38:30 -07002091 {
2092 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302093
Jeff Johnson295189b2012-06-20 16:38:30 -07002094 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302095
Jeff Johnson295189b2012-06-20 16:38:30 -07002096 if (!old)
2097 return -ENOENT;
2098
2099 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
2100
2101 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302102 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson295189b2012-06-20 16:38:30 -07002103 "%s: Error!!! Allocating the new beacon\n",__func__);
2104 return -EINVAL;
2105 }
2106
2107 pAdapter->sessionCtx.ap.beacon = new;
2108
2109 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
2110 }
2111
2112 EXIT();
2113 return status;
2114}
2115
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002116#endif //(LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
2117
2118#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07002119static int wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy,
2120 struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002121#else
2122static int wlan_hdd_cfg80211_stop_ap (struct wiphy *wiphy,
2123 struct net_device *dev)
2124#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07002125{
2126 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnsone7245742012-09-05 17:12:55 -07002127 hdd_context_t *pHddCtx = NULL;
2128 hdd_scaninfo_t *pScanInfo = NULL;
2129 hdd_adapter_t *staAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07002130 VOS_STATUS status = 0;
2131
2132 ENTER();
2133
2134 if (NULL == pAdapter)
2135 {
2136 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002137 "%s: HDD adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002138 return -ENODEV;
2139 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07002140
Jeff Johnson4416a782013-03-25 14:17:50 -07002141 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07002142 if (NULL == pHddCtx)
2143 {
2144 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002145 "%s: HDD context is Null", __func__);
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07002146 return -ENODEV;
2147 }
Jeff Johnson4416a782013-03-25 14:17:50 -07002148 if (pHddCtx->isLogpInProgress)
2149 {
2150 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2151 "%s:LOGP in Progress. Ignore!!!", __func__);
2152 return -EAGAIN;
2153 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07002154
2155 staAdapter = hdd_get_adapter(pAdapter->pHddCtx, WLAN_HDD_INFRA_STATION);
2156 if (NULL == staAdapter)
2157 {
2158 staAdapter = hdd_get_adapter(pAdapter->pHddCtx, WLAN_HDD_P2P_CLIENT);
2159 if (NULL == staAdapter)
2160 {
2161 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002162 "%s: HDD adapter context is Null", __func__);
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07002163 return -ENODEV;
2164 }
2165 }
2166
2167 pScanInfo = &pHddCtx->scan_info;
2168
Jeff Johnson4416a782013-03-25 14:17:50 -07002169 if (pHddCtx->isLogpInProgress)
Jeff Johnson295189b2012-06-20 16:38:30 -07002170 {
2171 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:LOGP in Progress. Ignore!!!",__func__);
2172 return -EAGAIN;
2173 }
2174
2175 pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
2176
2177 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",
2178 __func__,pAdapter->device_mode);
2179
Jeff Johnsone7245742012-09-05 17:12:55 -07002180 if ((pScanInfo != NULL) && pScanInfo->mScanPending)
2181 {
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -08002182 INIT_COMPLETION(pScanInfo->abortscan_event_var);
Jeff Johnsone7245742012-09-05 17:12:55 -07002183 hdd_abort_mac_scan(staAdapter->pHddCtx);
2184 status = wait_for_completion_interruptible_timeout(
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -08002185 &pScanInfo->abortscan_event_var,
Jeff Johnsone7245742012-09-05 17:12:55 -07002186 msecs_to_jiffies(WLAN_WAIT_TIME_ABORTSCAN));
2187 if (!status)
2188 {
2189 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Jeff Johnson902c9832012-12-10 14:28:09 -08002190 "%s: Timeout occurred while waiting for abortscan" ,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002191 __func__);
Jeff Johnsone7245742012-09-05 17:12:55 -07002192 VOS_ASSERT(pScanInfo->mScanPending);
2193 return 0;
2194 }
2195 }
2196
Jeff Johnson295189b2012-06-20 16:38:30 -07002197 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07002198 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07002199 )
2200 {
2201 beacon_data_t *old;
2202
2203 old = pAdapter->sessionCtx.ap.beacon;
2204
2205 if (!old)
2206 return -ENOENT;
2207
Jeff Johnson295189b2012-06-20 16:38:30 -07002208 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07002209
2210 mutex_lock(&pHddCtx->sap_lock);
2211 if(test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
2212 {
Jeff Johnson4416a782013-03-25 14:17:50 -07002213 if ( VOS_STATUS_SUCCESS == (status = WLANSAP_StopBss(pHddCtx->pvosContext) ) )
Jeff Johnson295189b2012-06-20 16:38:30 -07002214 {
2215 hdd_hostapd_state_t *pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
2216
2217 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
2218
2219 if (!VOS_IS_STATUS_SUCCESS(status))
2220 {
2221 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2222 ("ERROR: HDD vos wait for single_event failed!!\n"));
2223 VOS_ASSERT(0);
2224 }
2225 }
2226 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
2227 }
2228 mutex_unlock(&pHddCtx->sap_lock);
2229
2230 if(status != VOS_STATUS_SUCCESS)
2231 {
2232 hddLog(VOS_TRACE_LEVEL_FATAL,
2233 "%s:Error!!! Stopping the BSS\n",__func__);
2234 return -EINVAL;
2235 }
2236
Jeff Johnson4416a782013-03-25 14:17:50 -07002237 if (ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -07002238 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 0,NULL, eANI_BOOLEAN_FALSE)
2239 ==eHAL_STATUS_FAILURE)
2240 {
2241 hddLog(LOGE,
2242 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM\n");
2243 }
2244
Jeff Johnson4416a782013-03-25 14:17:50 -07002245 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -07002246 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
2247 eANI_BOOLEAN_FALSE) )
2248 {
2249 hddLog(LOGE,
2250 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM\n");
2251 }
2252
2253 // Reset WNI_CFG_PROBE_RSP Flags
2254 wlan_hdd_reset_prob_rspies(pAdapter);
2255
2256 pAdapter->sessionCtx.ap.beacon = NULL;
2257 kfree(old);
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07002258#ifdef WLAN_FEATURE_P2P_DEBUG
2259 if((pAdapter->device_mode == WLAN_HDD_P2P_GO) &&
2260 (globalP2PConnectionStatus == P2P_GO_COMPLETED_STATE))
2261 {
2262 hddLog(LOGE,"[P2P State] From GO completed to Inactive state "
2263 "GO got removed");
2264 globalP2PConnectionStatus = P2P_NOT_ACTIVE;
2265 }
2266#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07002267 }
2268 EXIT();
2269 return status;
2270}
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002271
2272#if (LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
2273
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302274static int wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
2275 struct net_device *dev,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002276 struct cfg80211_ap_settings *params)
2277{
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302278 hdd_adapter_t *pAdapter;
2279 hdd_context_t *pHddCtx;
2280 int status = 0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002281
2282 ENTER();
2283
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302284 if (NULL == dev)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07002285 {
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302286 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
2287 "%s: Device is Null", __func__);
2288 return -ENODEV;
2289 }
2290
2291 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2292 if (NULL == pAdapter)
2293 {
2294 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
2295 "%s: HDD adapter is Null", __func__);
2296 return -ENODEV;
2297 }
2298
2299 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
2300 {
2301 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
2302 "%s: HDD adapter magic is invalid", __func__);
2303 return -ENODEV;
2304 }
2305
2306 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2307 if (NULL == pHddCtx)
2308 {
2309 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
2310 "%s: HDD context is Null", __func__);
2311 return -ENODEV;
2312 }
2313
2314 if (pHddCtx->isLogpInProgress)
2315 {
2316 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
2317 "%s: LOGP in Progress. Ignore!!!", __func__);
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07002318 return -EAGAIN;
2319 }
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302320
2321 if (pHddCtx->isLoadUnloadInProgress)
2322 {
2323 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
2324 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
2325 return -EAGAIN;
2326 }
2327
2328 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device mode = %d",
2329 __func__, pAdapter->device_mode);
2330
2331 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002332 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002333 )
2334 {
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302335 beacon_data_t *old, *new;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002336
2337 old = pAdapter->sessionCtx.ap.beacon;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302338
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002339 if (old)
2340 return -EALREADY;
2341
2342 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter, &new, &params->beacon, params->dtim_period);
2343
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302344 if (status != 0)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002345 {
2346 hddLog(VOS_TRACE_LEVEL_FATAL,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302347 "%s:Error!!! Allocating the new beacon", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002348 return -EINVAL;
2349 }
2350 pAdapter->sessionCtx.ap.beacon = new;
Viral Modi3a32cc52013-02-08 11:14:52 -08002351#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
2352 wlan_hdd_cfg80211_set_channel(wiphy, dev, params->channel, params->channel_type);
2353#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002354 status = wlan_hdd_cfg80211_start_bss(pAdapter, &params->beacon, params->ssid,
2355 params->ssid_len, params->hidden_ssid);
2356 }
2357
2358 EXIT();
2359 return status;
2360}
2361
2362
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302363static int wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002364 struct net_device *dev,
2365 struct cfg80211_beacon_data *params)
2366{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302367 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002368 int status=VOS_STATUS_SUCCESS;
2369
2370 ENTER();
2371
2372 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",
2373 __func__, pAdapter->device_mode);
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07002374 if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress)
2375 {
2376 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:LOGP in Progress. Ignore!!!",__func__);
2377 return -EAGAIN;
2378 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002379
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302380 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002381 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302382 )
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002383 {
2384 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302385
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002386 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302387
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002388 if (!old)
2389 return -ENOENT;
2390
2391 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter, &new, params, 0);
2392
2393 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302394 hddLog(VOS_TRACE_LEVEL_FATAL,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002395 "%s: Error!!! Allocating the new beacon\n",__func__);
2396 return -EINVAL;
2397 }
2398
2399 pAdapter->sessionCtx.ap.beacon = new;
2400
2401 status = wlan_hdd_cfg80211_start_bss(pAdapter, params, NULL, 0, 0);
2402 }
2403
2404 EXIT();
2405 return status;
2406}
2407
2408#endif //(LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
2409
Jeff Johnson295189b2012-06-20 16:38:30 -07002410
2411static int wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
2412 struct net_device *dev,
2413 struct bss_parameters *params)
2414{
2415 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2416
2417 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302418
Jeff Johnson295189b2012-06-20 16:38:30 -07002419 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",
2420 __func__,pAdapter->device_mode);
2421
2422 if((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07002423 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302424 )
Jeff Johnson295189b2012-06-20 16:38:30 -07002425 {
2426 /* ap_isolate == -1 means that in change bss, upper layer doesn't
2427 * want to update this parameter */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302428 if (-1 != params->ap_isolate)
Jeff Johnson295189b2012-06-20 16:38:30 -07002429 {
2430 pAdapter->sessionCtx.ap.apDisableIntraBssFwd = !!params->ap_isolate;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302431 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002432 }
2433
2434 EXIT();
2435 return 0;
2436}
2437
2438/*
2439 * FUNCTION: wlan_hdd_cfg80211_change_iface
2440 * This function is used to set the interface type (INFRASTRUCTURE/ADHOC)
2441 */
2442int wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
2443 struct net_device *ndev,
2444 enum nl80211_iftype type,
2445 u32 *flags,
2446 struct vif_params *params
2447 )
2448{
2449 struct wireless_dev *wdev;
2450 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
2451 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
Mohit Khanna0f232092012-09-11 14:46:08 -07002452 hdd_adapter_t *pP2pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07002453 tCsrRoamProfile *pRoamProfile = NULL;
2454 eCsrRoamBssType LastBSSType;
2455 hdd_config_t *pConfig = pHddCtx->cfg_ini;
2456 eMib_dot11DesiredBssType connectedBssType;
2457 VOS_STATUS status;
2458
2459 ENTER();
2460
2461 if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress)
2462 {
2463 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:LOGP in Progress. Ignore!!!",__func__);
2464 return -EAGAIN;
2465 }
2466
2467 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
2468 __func__, pAdapter->device_mode);
2469
2470 wdev = ndev->ieee80211_ptr;
2471
2472#ifdef WLAN_BTAMP_FEATURE
2473 if((NL80211_IFTYPE_P2P_CLIENT == type)||
2474 (NL80211_IFTYPE_ADHOC == type)||
2475 (NL80211_IFTYPE_AP == type)||
2476 (NL80211_IFTYPE_P2P_GO == type))
2477 {
2478 pHddCtx->isAmpAllowed = VOS_FALSE;
2479 // stop AMP traffic
2480 status = WLANBAP_StopAmp();
2481 if(VOS_STATUS_SUCCESS != status )
2482 {
2483 pHddCtx->isAmpAllowed = VOS_TRUE;
2484 hddLog(VOS_TRACE_LEVEL_FATAL,
2485 "%s: Failed to stop AMP", __func__);
2486 return -EINVAL;
2487 }
2488 }
2489#endif //WLAN_BTAMP_FEATURE
2490 /* Reset the current device mode bit mask*/
2491 wlan_hdd_clear_concurrency_mode(pHddCtx, pAdapter->device_mode);
2492
2493 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -07002494 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnsone7245742012-09-05 17:12:55 -07002495 || (pAdapter->device_mode == WLAN_HDD_P2P_DEVICE)
Jeff Johnson295189b2012-06-20 16:38:30 -07002496 )
2497 {
2498 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
2499 pRoamProfile = &pWextState->roamProfile;
2500 LastBSSType = pRoamProfile->BSSType;
2501
2502 switch (type)
2503 {
2504 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -07002505 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -07002506 hddLog(VOS_TRACE_LEVEL_INFO,
2507 "%s: setting interface Type to INFRASTRUCTURE", __func__);
2508 pRoamProfile->BSSType = eCSR_BSS_TYPE_INFRASTRUCTURE;
Jeff Johnsone7245742012-09-05 17:12:55 -07002509#ifdef WLAN_FEATURE_11AC
2510 if(pConfig->dot11Mode == eHDD_DOT11_MODE_AUTO)
2511 {
2512 pConfig->dot11Mode = eHDD_DOT11_MODE_11ac;
2513 }
2514#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302515 pRoamProfile->phyMode =
Jeff Johnsone7245742012-09-05 17:12:55 -07002516 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07002517 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08002518 //Check for sub-string p2p to confirm its a p2p interface
2519 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302520 {
Gopichand Nakkala864d3552012-12-31 16:08:51 -08002521 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
2522 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
2523 }
2524 else
2525 {
2526 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -07002527 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -08002528 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002529 break;
2530 case NL80211_IFTYPE_ADHOC:
2531 hddLog(VOS_TRACE_LEVEL_INFO,
2532 "%s: setting interface Type to ADHOC", __func__);
2533 pRoamProfile->BSSType = eCSR_BSS_TYPE_START_IBSS;
2534 pRoamProfile->phyMode =
2535 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Shailender Karmuchia734f332013-04-19 14:02:48 -07002536 pAdapter->device_mode = WLAN_HDD_IBSS;
Jeff Johnson295189b2012-06-20 16:38:30 -07002537 wdev->iftype = type;
2538 break;
2539
2540 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -07002541 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07002542 {
2543 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
2544 "%s: setting interface Type to %s", __func__,
2545 (type == NL80211_IFTYPE_AP) ? "SoftAP" : "P2pGo");
2546
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08002547 //Cancel any remain on channel for GO mode
2548 if (NL80211_IFTYPE_P2P_GO == type)
2549 {
2550 wlan_hdd_cancel_existing_remain_on_channel(pAdapter);
2551 }
Mohit Khanna0f232092012-09-11 14:46:08 -07002552 if (NL80211_IFTYPE_AP == type)
2553 {
2554 /* As Loading WLAN Driver one interface being created for p2p device
2555 * address. This will take one HW STA and the max number of clients
2556 * that can connect to softAP will be reduced by one. so while changing
2557 * the interface type to NL80211_IFTYPE_AP (SoftAP) remove p2p0
2558 * interface as it is not required in SoftAP mode.
2559 */
2560
2561 // Get P2P Adapter
2562 pP2pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_DEVICE);
2563
2564 if (pP2pAdapter)
2565 {
2566 hdd_stop_adapter(pHddCtx, pP2pAdapter);
2567 hdd_deinit_adapter(pHddCtx, pP2pAdapter);
2568 hdd_close_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
2569 }
2570 }
2571
Jeff Johnson295189b2012-06-20 16:38:30 -07002572 //De-init the adapter.
2573 hdd_stop_adapter( pHddCtx, pAdapter );
2574 hdd_deinit_adapter( pHddCtx, pAdapter );
2575 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
Jeff Johnson295189b2012-06-20 16:38:30 -07002576 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
2577 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Jeff Johnson32d95a32012-09-10 13:15:23 -07002578
2579 //Disable BMPS and IMPS if enabled
2580 //before starting Go
2581 if(WLAN_HDD_P2P_GO == pAdapter->device_mode)
2582 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302583 if(VOS_STATUS_E_FAILURE ==
Jeff Johnson32d95a32012-09-10 13:15:23 -07002584 hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_P2P_GO))
2585 {
2586 //Fail to Exit BMPS
2587 VOS_ASSERT(0);
2588 }
2589 }
2590
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -07002591 if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) &&
2592 (pConfig->apRandomBssidEnabled))
2593 {
2594 /* To meet Android requirements create a randomized
2595 MAC address of the form 02:1A:11:Fx:xx:xx */
2596 get_random_bytes(&ndev->dev_addr[3], 3);
2597 ndev->dev_addr[0] = 0x02;
2598 ndev->dev_addr[1] = 0x1A;
2599 ndev->dev_addr[2] = 0x11;
2600 ndev->dev_addr[3] |= 0xF0;
2601 memcpy(pAdapter->macAddressCurrent.bytes, ndev->dev_addr,
2602 VOS_MAC_ADDR_SIZE);
2603 pr_info("wlan: Generated HotSpot BSSID "
2604 "%02x:%02x:%02x:%02x:%02x:%02x\n",
2605 ndev->dev_addr[0],
2606 ndev->dev_addr[1],
2607 ndev->dev_addr[2],
2608 ndev->dev_addr[3],
2609 ndev->dev_addr[4],
2610 ndev->dev_addr[5]);
2611 }
2612
Jeff Johnson295189b2012-06-20 16:38:30 -07002613 hdd_set_ap_ops( pAdapter->dev );
2614
2615 status = hdd_init_ap_mode(pAdapter);
2616 if(status != VOS_STATUS_SUCCESS)
2617 {
2618 hddLog(VOS_TRACE_LEVEL_FATAL,
2619 "%s: Error initializing the ap mode", __func__);
2620 return -EINVAL;
2621 }
2622 hdd_set_conparam(1);
2623
Jeff Johnson295189b2012-06-20 16:38:30 -07002624 /*interface type changed update in wiphy structure*/
2625 if(wdev)
2626 {
2627 wdev->iftype = type;
2628 pHddCtx->change_iface = type;
2629 }
2630 else
2631 {
2632 hddLog(VOS_TRACE_LEVEL_ERROR,
2633 "%s: ERROR !!!! Wireless dev is NULL", __func__);
2634 return -EINVAL;
2635 }
2636 goto done;
2637 }
2638
2639 default:
2640 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
2641 __func__);
2642 return -EOPNOTSUPP;
2643 }
2644 }
2645 else if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07002646 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07002647 )
2648 {
2649 switch(type)
2650 {
2651 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -07002652 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -07002653 case NL80211_IFTYPE_ADHOC:
Jeff Johnson32d95a32012-09-10 13:15:23 -07002654 hdd_stop_adapter( pHddCtx, pAdapter );
2655 hdd_deinit_adapter( pHddCtx, pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07002656 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08002657 //Check for sub-string p2p to confirm its a p2p interface
2658 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala864d3552012-12-31 16:08:51 -08002659 {
2660 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
2661 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
2662 }
2663 else
2664 {
2665 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -07002666 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -08002667 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002668 hdd_set_conparam(0);
2669 pHddCtx->change_iface = type;
Jeff Johnson295189b2012-06-20 16:38:30 -07002670 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
2671 hdd_set_station_ops( pAdapter->dev );
2672 status = hdd_init_station_mode( pAdapter );
2673 if( VOS_STATUS_SUCCESS != status )
2674 return -EOPNOTSUPP;
Jeff Johnsone7245742012-09-05 17:12:55 -07002675 /* In case of JB, for P2P-GO, only change interface will be called,
2676 * This is the right place to enable back bmps_imps()
2677 */
2678 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07002679 goto done;
2680 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -07002681 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07002682 wdev->iftype = type;
Jeff Johnson295189b2012-06-20 16:38:30 -07002683 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
2684 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Jeff Johnson295189b2012-06-20 16:38:30 -07002685 goto done;
2686 default:
2687 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
2688 __func__);
2689 return -EOPNOTSUPP;
2690
2691 }
2692
2693 }
2694 else
2695 {
2696 return -EOPNOTSUPP;
2697 }
2698
2699
2700 if(pRoamProfile)
2701 {
2702 if ( LastBSSType != pRoamProfile->BSSType )
2703 {
2704 /*interface type changed update in wiphy structure*/
2705 wdev->iftype = type;
2706
2707 /*the BSS mode changed, We need to issue disconnect
2708 if connected or in IBSS disconnect state*/
2709 if ( hdd_connGetConnectedBssType(
2710 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), &connectedBssType ) ||
2711 ( eCSR_BSS_TYPE_START_IBSS == LastBSSType ) )
2712 {
2713 /*need to issue a disconnect to CSR.*/
2714 INIT_COMPLETION(pAdapter->disconnect_comp_var);
2715 if( eHAL_STATUS_SUCCESS ==
2716 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
2717 pAdapter->sessionId,
2718 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
2719 {
2720 wait_for_completion_interruptible_timeout(
2721 &pAdapter->disconnect_comp_var,
2722 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
2723 }
2724 }
2725 }
2726 }
2727
2728done:
2729 /*set bitmask based on updated value*/
2730 wlan_hdd_set_concurrency_mode(pHddCtx, pAdapter->device_mode);
2731#ifdef WLAN_BTAMP_FEATURE
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302732 if((NL80211_IFTYPE_STATION == type) && (pHddCtx->concurrency_mode <= 1) &&
Jeff Johnson295189b2012-06-20 16:38:30 -07002733 (pHddCtx->no_of_sessions[WLAN_HDD_INFRA_STATION] <=1))
2734 {
2735 //we are ok to do AMP
2736 pHddCtx->isAmpAllowed = VOS_TRUE;
2737 }
2738#endif //WLAN_BTAMP_FEATURE
2739 EXIT();
2740 return 0;
2741}
2742
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002743#ifdef FEATURE_WLAN_TDLS
2744static int wlan_hdd_tdls_add_station(struct wiphy *wiphy,
2745 struct net_device *dev, u8 *mac, bool update, tCsrStaParams *StaParams)
2746{
2747 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2748 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
2749 VOS_STATUS status;
Hoonki Lee5305c3a2013-04-29 23:28:59 -07002750 hddTdlsPeer_t *pTdlsPeer;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002751
2752 ENTER();
2753
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05302754 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002755 {
2756 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2757 "Invalid arguments");
2758 return -EINVAL;
2759 }
Hoonki Lee27511902013-03-14 18:19:06 -07002760
2761 if ((eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode) ||
2762 (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode))
2763 {
2764 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2765 "%s: TDLS mode is disabled OR not enabled in FW."
2766 MAC_ADDRESS_STR " Request declined.",
2767 __func__, MAC_ADDR_ARRAY(mac));
2768 return -ENOTSUPP;
2769 }
2770
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002771 if (pHddCtx->isLogpInProgress)
2772 {
2773 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2774 "%s:LOGP in Progress. Ignore!!!", __func__);
Gopichand Nakkala05922802013-03-14 12:23:19 -07002775 wlan_hdd_tdls_set_link_status(pAdapter, mac, eTDLS_LINK_IDLE);
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002776 return -EBUSY;
2777 }
2778
Hoonki Lee5305c3a2013-04-29 23:28:59 -07002779 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, mac);
2780
2781 if ( NULL == pTdlsPeer ) {
2782 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2783 "%s: " MAC_ADDRESS_STR " (update %d) not exist. return invalid",
2784 __func__, MAC_ADDR_ARRAY(mac), update);
2785 return -EINVAL;
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07002786 }
Hoonki Lee5305c3a2013-04-29 23:28:59 -07002787
2788 /* in add station, we accept existing valid staId if there is */
2789 if ((0 == update) &&
2790 ((pTdlsPeer->link_status >= eTDLS_LINK_CONNECTING) ||
2791 (TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07002792 {
Hoonki Lee5305c3a2013-04-29 23:28:59 -07002793 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07002794 "%s: " MAC_ADDRESS_STR
Hoonki Lee5305c3a2013-04-29 23:28:59 -07002795 " link_status %d. staId %d. add station ignored.",
2796 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, pTdlsPeer->staId);
2797 return 0;
2798 }
2799 /* in change station, we accept only when staId is valid */
2800 if ((1 == update) &&
2801 ((pTdlsPeer->link_status > eTDLS_LINK_CONNECTING) ||
2802 (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
2803 {
2804 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2805 "%s: " MAC_ADDRESS_STR
2806 " link status %d. staId %d. change station %s.",
2807 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, pTdlsPeer->staId,
2808 (TDLS_STA_INDEX_VALID(pTdlsPeer->staId)) ? "ignored" : "declined");
2809 return (TDLS_STA_INDEX_VALID(pTdlsPeer->staId)) ? 0 : -EPERM;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07002810 }
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07002811
2812 /* when others are on-going, we want to change link_status to idle */
Hoonki Leefb8df672013-04-10 18:20:34 -07002813 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, mac, TRUE, TRUE))
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002814 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07002815 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2816 "%s: " MAC_ADDRESS_STR
2817 " TDLS setup is ongoing. Request declined.",
2818 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala05922802013-03-14 12:23:19 -07002819 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002820 }
2821
2822 /* first to check if we reached to maximum supported TDLS peer.
2823 TODO: for now, return -EPERM looks working fine,
2824 but need to check if any other errno fit into this category.*/
2825 if (HDD_MAX_NUM_TDLS_STA <= wlan_hdd_tdlsConnectedPeers(pAdapter))
2826 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07002827 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2828 "%s: " MAC_ADDRESS_STR
2829 " TDLS Max peer already connected. Request declined.",
2830 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala05922802013-03-14 12:23:19 -07002831 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002832 }
2833 else
2834 {
2835 hddTdlsPeer_t *pTdlsPeer;
2836 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, mac);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07002837 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002838 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07002839 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2840 "%s: " MAC_ADDRESS_STR " already connected. Request declined.",
2841 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002842 return -EPERM;
2843 }
2844 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07002845 if (0 == update)
2846 wlan_hdd_tdls_set_link_status(pAdapter, mac, eTDLS_LINK_CONNECTING);
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002847
Jeff Johnsond75fe012013-04-06 10:53:06 -07002848 /* debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05302849 if (NULL != StaParams)
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07002850 {
2851 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2852 "%s: TDLS Peer Parameters.", __func__);
Hoonki Lee66b75f32013-04-16 18:30:07 -07002853 if(StaParams->htcap_present)
2854 {
2855 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2856 "ht_capa->cap_info: %0x", StaParams->HTCap.capInfo);
2857 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2858 "ht_capa->extended_capabilities: %0x",
2859 StaParams->HTCap.extendedHtCapInfo);
2860 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07002861 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2862 "params->capability: %0x",StaParams->capability);
2863 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2864 "params->ext_capab_len: %0x",StaParams->extn_capability);
Hoonki Lee66b75f32013-04-16 18:30:07 -07002865 if(StaParams->vhtcap_present)
2866 {
2867 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2868 "rxMcsMap %x rxHighest %x txMcsMap %x txHighest %x",
2869 StaParams->VHTCap.suppMcs.rxMcsMap, StaParams->VHTCap.suppMcs.rxHighest,
2870 StaParams->VHTCap.suppMcs.txMcsMap, StaParams->VHTCap.suppMcs.txHighest);
2871 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07002872 {
2873 int i = 0;
Hoonki Lee5305c3a2013-04-29 23:28:59 -07002874 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "Supported rates:");
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07002875 for (i = 0; i < sizeof(StaParams->supported_rates); i++)
2876 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2877 "[%d]: %x ", i, StaParams->supported_rates[i]);
2878 }
Jeff Johnsond75fe012013-04-06 10:53:06 -07002879 } /* end debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05302880 else if ((1 == update) && (NULL == StaParams))
2881 {
2882 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2883 "%s : update is true, but staParams is NULL. Error!", __func__);
2884 return -EPERM;
2885 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002886
2887 INIT_COMPLETION(pAdapter->tdls_add_station_comp);
2888
2889 if (!update)
2890 {
2891 status = sme_AddTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
2892 pAdapter->sessionId, mac);
2893 }
2894 else
2895 {
2896 status = sme_ChangeTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
2897 pAdapter->sessionId, mac, StaParams);
2898 }
2899
2900 status = wait_for_completion_interruptible_timeout(&pAdapter->tdls_add_station_comp,
2901 msecs_to_jiffies(WAIT_TIME_TDLS_ADD_STA));
2902
2903 if (!status)
2904 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07002905 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002906 "%s: timeout waiting for tdls add station indication",
2907 __func__);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07002908 return -EPERM;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002909 }
2910 if ( eHAL_STATUS_SUCCESS != pAdapter->tdlsAddStaStatus)
2911 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07002912 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002913 "%s: Add Station is unsucessful", __func__);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07002914 return -EPERM;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002915 }
2916
2917 return 0;
Gopichand Nakkala05922802013-03-14 12:23:19 -07002918
2919error:
2920 wlan_hdd_tdls_set_link_status(pAdapter, mac, eTDLS_LINK_IDLE);
2921 return -EPERM;
2922
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002923}
2924#endif
2925
Jeff Johnson295189b2012-06-20 16:38:30 -07002926static int wlan_hdd_change_station(struct wiphy *wiphy,
2927 struct net_device *dev,
2928 u8 *mac,
2929 struct station_parameters *params)
2930{
2931 VOS_STATUS status = VOS_STATUS_SUCCESS;
2932 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Gopichand Nakkala29149562013-05-10 21:43:41 +05302933 hdd_context_t *pHddCtx;
2934 hdd_station_ctx_t *pHddStaCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07002935 v_MACADDR_t STAMacAddress;
Gopichand Nakkalab0856222013-03-12 22:39:05 -07002936#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002937 tCsrStaParams StaParams = {0};
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002938 tANI_U8 isBufSta = 0;
Gopichand Nakkalab0856222013-03-12 22:39:05 -07002939#endif
Jeff Johnsone7245742012-09-05 17:12:55 -07002940 ENTER();
2941
Gopichand Nakkala29149562013-05-10 21:43:41 +05302942 if ((NULL == pAdapter))
2943 {
2944 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
2945 "invalid adapter ");
2946 return -EINVAL;
2947 }
2948
2949 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2950 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
2951
2952 if ((NULL == pHddCtx) || (NULL == pHddStaCtx))
2953 {
2954 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
2955 "invalid HDD state or HDD station context");
2956 return -EINVAL;
2957 }
2958
2959 if (pHddCtx->isLogpInProgress)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002960 {
2961 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2962 "%s:LOGP in Progress. Ignore!!!", __func__);
2963 return -EAGAIN;
2964 }
2965
Jeff Johnson295189b2012-06-20 16:38:30 -07002966 vos_mem_copy(STAMacAddress.bytes, mac, sizeof(v_MACADDR_t));
2967
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002968 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
2969 || (pAdapter->device_mode == WLAN_HDD_P2P_GO))
Jeff Johnson295189b2012-06-20 16:38:30 -07002970 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -08002971 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED))
Jeff Johnson295189b2012-06-20 16:38:30 -07002972 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302973 status = hdd_softap_change_STA_state( pAdapter, &STAMacAddress,
Jeff Johnson295189b2012-06-20 16:38:30 -07002974 WLANTL_STA_AUTHENTICATED);
2975
Gopichand Nakkala29149562013-05-10 21:43:41 +05302976 if (status != VOS_STATUS_SUCCESS)
2977 {
2978 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2979 "%s: Not able to change TL state to AUTHENTICATED", __func__);
2980 return -EINVAL;
2981 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002982 }
2983 }
Hoonki Leea6d49be2013-04-05 09:43:25 -07002984 else if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
2985 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)) {
Gopichand Nakkala29149562013-05-10 21:43:41 +05302986#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07002987 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
2988 StaParams.capability = params->capability;
2989 StaParams.uapsd_queues = params->uapsd_queues;
2990 StaParams.max_sp = params->max_sp;
2991
2992 if (0 != params->ext_capab_len)
2993 vos_mem_copy(StaParams.extn_capability, params->ext_capab,
2994 sizeof(StaParams.extn_capability));
2995
2996 if (NULL != params->ht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -07002997 {
2998 StaParams.htcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07002999 vos_mem_copy(&StaParams.HTCap, params->ht_capa, sizeof(tSirHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -07003000 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003001
3002 StaParams.supported_rates_len = params->supported_rates_len;
3003
3004 /* Note : The Maximum sizeof supported_rates sent by the Supplicant is 32.
3005 * The supported_rates array , for all the structures propogating till Add Sta
3006 * to the firmware has to be modified , if the supplicant (ieee80211) is
3007 * modified to send more rates.
3008 */
3009
3010 /* To avoid Data Currption , set to max length to SIR_MAC_MAX_SUPP_RATES
3011 */
3012 if (StaParams.supported_rates_len > SIR_MAC_MAX_SUPP_RATES)
3013 StaParams.supported_rates_len = SIR_MAC_MAX_SUPP_RATES;
3014
3015 if (0 != StaParams.supported_rates_len) {
3016 int i = 0;
3017 vos_mem_copy(StaParams.supported_rates, params->supported_rates,
3018 StaParams.supported_rates_len);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07003019 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003020 "Supported Rates with Length %d", StaParams.supported_rates_len);
3021 for (i=0; i < StaParams.supported_rates_len; i++)
Hoonki Lee5305c3a2013-04-29 23:28:59 -07003022 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003023 "[%d]: %0x", i, StaParams.supported_rates[i]);
3024 }
3025
3026 if (NULL != params->vht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -07003027 {
3028 StaParams.vhtcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003029 vos_mem_copy(&StaParams.VHTCap, params->vht_capa, sizeof(tSirVHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -07003030 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003031
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003032 if (0 != params->ext_capab_len ) {
3033 /*Define A Macro : TODO Sunil*/
3034 if ((1<<4) & StaParams.extn_capability[3]) {
3035 isBufSta = 1;
3036 }
3037 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003038 //status = wlan_hdd_tdls_set_peer_caps( mac, params->uapsd_queues,
3039 // params->max_sp, isBufSta);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003040 //if (VOS_STATUS_SUCCESS != status) {
3041 // VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3042 // "%s: wlan_hdd_tdls_set_peer_caps failed!", __func__);
3043 // return -EINVAL;
3044 //}
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003045 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 1, &StaParams);
3046
3047 if (VOS_STATUS_SUCCESS != status) {
3048 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3049 "%s: sme_ChangeTdlsPeerSta failed!", __func__);
3050 return -EINVAL;
3051 }
3052 }
Gopichand Nakkalab0856222013-03-12 22:39:05 -07003053#endif
Gopichand Nakkala29149562013-05-10 21:43:41 +05303054 if(params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED))
3055 {
3056 status = WLANTL_ChangeSTAState(pHddCtx->pvosContext, pHddStaCtx->conn_info.staId[ 0 ],
3057 WLANTL_STA_AUTHENTICATED);
3058 if (status != VOS_STATUS_SUCCESS)
3059 {
3060 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
3061 "%s: Not able to change TL state to AUTHENTICATED", __func__);
3062 return -EINVAL;
3063 }
3064 pHddStaCtx->conn_info.uIsAuthenticated = VOS_TRUE;
3065 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3066 "%s: TL Moving to Authenticated state", __func__);
3067 }
3068 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303069
Jeff Johnsone7245742012-09-05 17:12:55 -07003070 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07003071 return status;
3072}
3073
3074/*
Jeff Johnson295189b2012-06-20 16:38:30 -07003075 * FUNCTION: wlan_hdd_cfg80211_add_key
3076 * This function is used to initialize the key information
3077 */
3078#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003079static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07003080 struct net_device *ndev,
3081 u8 key_index, bool pairwise,
3082 const u8 *mac_addr,
3083 struct key_params *params
3084 )
3085#else
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003086static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07003087 struct net_device *ndev,
3088 u8 key_index, const u8 *mac_addr,
3089 struct key_params *params
3090 )
3091#endif
3092{
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003093 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -07003094 tCsrRoamSetKey setKey;
3095 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
3096 int status = 0;
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003097 v_U32_t roamId= 0xFF;
3098 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07003099 hdd_hostapd_state_t *pHostapdState;
3100 VOS_STATUS vos_status;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07003101 eHalStatus halStatus;
Jeff Johnson295189b2012-06-20 16:38:30 -07003102
3103 ENTER();
3104
Jeff Johnson04dd8a82012-06-29 20:41:40 -07003105 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
3106 {
3107 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3108 "%s:LOGP in Progress. Ignore!!!", __func__);
3109 return -EAGAIN;
3110 }
3111
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003112 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
3113 __func__, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07003114
3115 if (CSR_MAX_NUM_KEY <= key_index)
3116 {
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003117 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07003118 key_index);
3119
3120 return -EINVAL;
3121 }
3122
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003123 if (CSR_MAX_KEY_LEN < params->key_len)
3124 {
3125 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key length %d", __func__,
3126 params->key_len);
3127
3128 return -EINVAL;
3129 }
3130
3131 hddLog(VOS_TRACE_LEVEL_INFO,
3132 "%s: called with key index = %d & key length %d",
3133 __func__, key_index, params->key_len);
Jeff Johnson295189b2012-06-20 16:38:30 -07003134
3135 /*extract key idx, key len and key*/
3136 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
3137 setKey.keyId = key_index;
3138 setKey.keyLength = params->key_len;
3139 vos_mem_copy(&setKey.Key[0],params->key, params->key_len);
3140
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003141 switch (params->cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -07003142 {
3143 case WLAN_CIPHER_SUITE_WEP40:
3144 setKey.encType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
3145 break;
3146
3147 case WLAN_CIPHER_SUITE_WEP104:
3148 setKey.encType = eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
3149 break;
3150
3151 case WLAN_CIPHER_SUITE_TKIP:
3152 {
3153 u8 *pKey = &setKey.Key[0];
3154 setKey.encType = eCSR_ENCRYPT_TYPE_TKIP;
3155
3156 vos_mem_zero(pKey, CSR_MAX_KEY_LEN);
3157
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003158 /*Supplicant sends the 32bytes key in this order
Jeff Johnson295189b2012-06-20 16:38:30 -07003159
3160 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003161 | Tk1 |TX-MIC | RX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -07003162 |--------------|----------|----------|
3163 <---16bytes---><--8bytes--><--8bytes-->
3164
3165 */
3166 /*Sme expects the 32 bytes key to be in the below order
3167
3168 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003169 | Tk1 |RX-MIC | TX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -07003170 |--------------|----------|----------|
3171 <---16bytes---><--8bytes--><--8bytes-->
3172 */
3173 /* Copy the Temporal Key 1 (TK1) */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003174 vos_mem_copy(pKey, params->key, 16);
Jeff Johnson295189b2012-06-20 16:38:30 -07003175
3176 /*Copy the rx mic first*/
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003177 vos_mem_copy(&pKey[16], &params->key[24], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -07003178
3179 /*Copy the tx mic */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003180 vos_mem_copy(&pKey[24], &params->key[16], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -07003181
3182
3183 break;
3184 }
3185
3186 case WLAN_CIPHER_SUITE_CCMP:
3187 setKey.encType = eCSR_ENCRYPT_TYPE_AES;
3188 break;
3189
3190#ifdef FEATURE_WLAN_WAPI
3191 case WLAN_CIPHER_SUITE_SMS4:
3192 {
3193 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
3194 wlan_hdd_cfg80211_set_key_wapi(pAdapter, key_index, mac_addr,
3195 params->key, params->key_len);
3196 return 0;
3197 }
3198#endif
Chet Lanctot186b5732013-03-18 10:26:30 -07003199
Jeff Johnson295189b2012-06-20 16:38:30 -07003200#ifdef FEATURE_WLAN_CCX
3201 case WLAN_CIPHER_SUITE_KRK:
3202 setKey.encType = eCSR_ENCRYPT_TYPE_KRK;
3203 break;
3204#endif
Chet Lanctot186b5732013-03-18 10:26:30 -07003205
3206#ifdef WLAN_FEATURE_11W
3207 case WLAN_CIPHER_SUITE_AES_CMAC:
3208 setKey.encType = eCSR_ENCRYPT_TYPE_AES_CMAC;
Chet Lanctot3b5158a2013-03-31 16:45:21 -07003209 break;
Chet Lanctot186b5732013-03-18 10:26:30 -07003210#endif
3211
Jeff Johnson295189b2012-06-20 16:38:30 -07003212 default:
3213 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unsupported cipher type %lu",
3214 __func__, params->cipher);
3215 return -EOPNOTSUPP;
3216 }
3217
3218 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: encryption type %d",
3219 __func__, setKey.encType);
3220
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003221 if (
Jeff Johnson295189b2012-06-20 16:38:30 -07003222#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
3223 (!pairwise)
3224#else
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003225 (!mac_addr || is_broadcast_ether_addr(mac_addr))
Jeff Johnson295189b2012-06-20 16:38:30 -07003226#endif
3227 )
3228 {
3229 /* set group key*/
3230 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnson1250df42012-12-10 14:31:52 -08003231 "%s- %d: setting Broadcast key",
Jeff Johnson295189b2012-06-20 16:38:30 -07003232 __func__, __LINE__);
3233 setKey.keyDirection = eSIR_RX_ONLY;
3234 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
3235 }
3236 else
3237 {
3238 /* set pairwise key*/
3239 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3240 "%s- %d: setting pairwise key",
3241 __func__, __LINE__);
3242 setKey.keyDirection = eSIR_TX_RX;
3243 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
3244 }
3245
Gopichand Nakkala29149562013-05-10 21:43:41 +05303246 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP) ||
3247 (pAdapter->device_mode == WLAN_HDD_P2P_GO))
3248 {
Jeff Johnson295189b2012-06-20 16:38:30 -07003249 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003250 if( pHostapdState->bssState == BSS_START )
3251 {
Jeff Johnson295189b2012-06-20 16:38:30 -07003252 status = WLANSAP_SetKeySta( pVosContext, &setKey);
3253
3254 if ( status != eHAL_STATUS_SUCCESS )
3255 {
3256 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3257 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
3258 __LINE__, status );
3259 }
3260 }
3261
3262 /* Saving WEP keys */
3263 else if( eCSR_ENCRYPT_TYPE_WEP40_STATICKEY == setKey.encType ||
3264 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY == setKey.encType )
3265 {
3266 //Save the wep key in ap context. Issue setkey after the BSS is started.
3267 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
3268 vos_mem_copy(&pAPCtx->wepKey[key_index], &setKey, sizeof(tCsrRoamSetKey));
3269 }
3270 else
3271 {
3272 //Save the key in ap context. Issue setkey after the BSS is started.
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003273 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07003274 vos_mem_copy(&pAPCtx->groupKey, &setKey, sizeof(tCsrRoamSetKey));
3275 }
3276 }
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003277 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION) ||
3278 (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT) )
Jeff Johnson295189b2012-06-20 16:38:30 -07003279 {
3280 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
3281 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3282
Gopichand Nakkala3d295922013-05-07 16:19:14 +05303283#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
3284 if (!pairwise)
3285#else
3286 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
3287#endif
3288 {
3289 /* set group key*/
3290 if (pHddStaCtx->roam_info.deferKeyComplete)
3291 {
3292 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3293 "%s- %d: Perform Set key Complete",
3294 __func__, __LINE__);
3295 hdd_PerformRoamSetKeyComplete(pAdapter);
3296 }
3297 }
3298
Jeff Johnson295189b2012-06-20 16:38:30 -07003299 pWextState->roamProfile.Keys.KeyLength[key_index] = (u8)params->key_len;
3300
Venkata Prathyusha Kuntupalliee2ce712013-01-17 14:09:24 -08003301 pWextState->roamProfile.Keys.defaultIndex = key_index;
3302
3303
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003304 vos_mem_copy(&pWextState->roamProfile.Keys.KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -07003305 params->key, params->key_len);
3306
Gopichand Nakkala3d295922013-05-07 16:19:14 +05303307
Jeff Johnson295189b2012-06-20 16:38:30 -07003308 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
3309
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303310 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -07003311 "%s: set key for peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303312 __func__, setKey.peerMac[0], setKey.peerMac[1],
3313 setKey.peerMac[2], setKey.peerMac[3],
3314 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -07003315 setKey.keyDirection);
3316
3317 vos_status = wlan_hdd_check_ula_done(pAdapter);
3318
3319 if ( vos_status != VOS_STATUS_SUCCESS )
3320 {
3321 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3322 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
3323 __LINE__, vos_status );
3324
3325 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
3326
3327 return -EINVAL;
3328
3329 }
3330
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07003331#ifdef WLAN_FEATURE_VOWIFI_11R
Gopichand Nakkala3d295922013-05-07 16:19:14 +05303332 /* The supplicant may attempt to set the PTK once pre-authentication
3333 is done. Save the key in the UMAC and include it in the ADD BSS
3334 request */
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07003335 halStatus = sme_FTUpdateKey( WLAN_HDD_GET_HAL_CTX(pAdapter), &setKey);
Gopichand Nakkala3d295922013-05-07 16:19:14 +05303336 if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_SUCCESS )
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07003337 {
Gopichand Nakkala3d295922013-05-07 16:19:14 +05303338 hddLog(VOS_TRACE_LEVEL_INFO_MED,
3339 "%s: Update PreAuth Key success", __func__);
3340 return 0;
3341 }
3342 else if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_FAILED )
3343 {
3344 hddLog(VOS_TRACE_LEVEL_ERROR,
3345 "%s: Update PreAuth Key failed", __func__);
Gopichand Nakkalad7d13652013-02-15 01:48:00 +05303346 return -EINVAL;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07003347 }
3348#endif /* WLAN_FEATURE_VOWIFI_11R */
Jeff Johnson295189b2012-06-20 16:38:30 -07003349
3350 /* issue set key request to SME*/
3351 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
3352 pAdapter->sessionId, &setKey, &roamId );
3353
3354 if ( 0 != status )
3355 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303356 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07003357 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
3358 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
3359 return -EINVAL;
3360 }
3361
3362
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303363 /* in case of IBSS as there was no information available about WEP keys during
3364 * IBSS join, group key intialized with NULL key, so re-initialize group key
Jeff Johnson295189b2012-06-20 16:38:30 -07003365 * with correct value*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303366 if ( (eCSR_BSS_TYPE_START_IBSS == pWextState->roamProfile.BSSType) &&
3367 !( ( IW_AUTH_KEY_MGMT_802_1X
3368 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X))
Jeff Johnson295189b2012-06-20 16:38:30 -07003369 && (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType)
3370 )
3371 &&
3372 ( (WLAN_CIPHER_SUITE_WEP40 == params->cipher)
3373 || (WLAN_CIPHER_SUITE_WEP104 == params->cipher)
3374 )
3375 )
3376 {
3377 setKey.keyDirection = eSIR_RX_ONLY;
3378 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
3379
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303380 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -07003381 "%s: set key peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303382 __func__, setKey.peerMac[0], setKey.peerMac[1],
3383 setKey.peerMac[2], setKey.peerMac[3],
3384 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -07003385 setKey.keyDirection);
3386
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303387 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07003388 pAdapter->sessionId, &setKey, &roamId );
3389
3390 if ( 0 != status )
3391 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303392 hddLog(VOS_TRACE_LEVEL_ERROR,
3393 "%s: sme_RoamSetKey failed for group key (IBSS), returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07003394 __func__, status);
3395 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
3396 return -EINVAL;
3397 }
3398 }
3399 }
3400
3401 return 0;
3402}
3403
3404/*
3405 * FUNCTION: wlan_hdd_cfg80211_get_key
3406 * This function is used to get the key information
3407 */
3408#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303409static int wlan_hdd_cfg80211_get_key(
3410 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07003411 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303412 u8 key_index, bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -07003413 const u8 *mac_addr, void *cookie,
3414 void (*callback)(void *cookie, struct key_params*)
3415 )
3416#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303417static int wlan_hdd_cfg80211_get_key(
3418 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07003419 struct net_device *ndev,
3420 u8 key_index, const u8 *mac_addr, void *cookie,
3421 void (*callback)(void *cookie, struct key_params*)
3422 )
3423#endif
3424{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303425 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -07003426 hdd_wext_state_t *pWextState= WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
3427 tCsrRoamProfile *pRoamProfile = &(pWextState->roamProfile);
3428 struct key_params params;
3429
3430 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303431
Jeff Johnson295189b2012-06-20 16:38:30 -07003432 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",
3433 __func__,pAdapter->device_mode);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303434
Jeff Johnson295189b2012-06-20 16:38:30 -07003435 memset(&params, 0, sizeof(params));
3436
3437 if (CSR_MAX_NUM_KEY <= key_index)
3438 {
3439 return -EINVAL;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303440 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003441
3442 switch(pRoamProfile->EncryptionType.encryptionType[0])
3443 {
3444 case eCSR_ENCRYPT_TYPE_NONE:
3445 params.cipher = IW_AUTH_CIPHER_NONE;
3446 break;
3447
3448 case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY:
3449 case eCSR_ENCRYPT_TYPE_WEP40:
3450 params.cipher = WLAN_CIPHER_SUITE_WEP40;
3451 break;
3452
3453 case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY:
3454 case eCSR_ENCRYPT_TYPE_WEP104:
3455 params.cipher = WLAN_CIPHER_SUITE_WEP104;
3456 break;
3457
3458 case eCSR_ENCRYPT_TYPE_TKIP:
3459 params.cipher = WLAN_CIPHER_SUITE_TKIP;
3460 break;
3461
3462 case eCSR_ENCRYPT_TYPE_AES:
3463 params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
3464 break;
3465
3466 default:
3467 params.cipher = IW_AUTH_CIPHER_NONE;
3468 break;
3469 }
3470
3471 params.key_len = pRoamProfile->Keys.KeyLength[key_index];
3472 params.seq_len = 0;
3473 params.seq = NULL;
3474 params.key = &pRoamProfile->Keys.KeyMaterial[key_index][0];
3475 callback(cookie, &params);
3476 return 0;
3477}
3478
3479/*
3480 * FUNCTION: wlan_hdd_cfg80211_del_key
3481 * This function is used to delete the key information
3482 */
3483#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303484static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07003485 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303486 u8 key_index,
3487 bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -07003488 const u8 *mac_addr
3489 )
3490#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303491static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07003492 struct net_device *ndev,
3493 u8 key_index,
3494 const u8 *mac_addr
3495 )
3496#endif
3497{
3498 int status = 0;
3499
3500 //This code needs to be revisited. There is sme_removeKey API, we should
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303501 //plan to use that. After the change to use correct index in setkey,
Jeff Johnson295189b2012-06-20 16:38:30 -07003502 //it is observed that this is invalidating peer
3503 //key index whenever re-key is done. This is affecting data link.
3504 //It should be ok to ignore del_key.
3505#if 0
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303506 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
3507 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07003508 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
3509 tCsrRoamSetKey setKey;
3510 v_U32_t roamId= 0xFF;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303511
Jeff Johnson295189b2012-06-20 16:38:30 -07003512 ENTER();
3513
3514 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device_mode = %d\n",
3515 __func__,pAdapter->device_mode);
3516
3517 if (CSR_MAX_NUM_KEY <= key_index)
3518 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303519 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07003520 key_index);
3521
3522 return -EINVAL;
3523 }
3524
3525 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
3526 setKey.keyId = key_index;
3527
3528 if (mac_addr)
3529 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
3530 else
3531 vos_mem_copy(setKey.peerMac, groupmacaddr, WNI_CFG_BSSID_LEN);
3532
3533 setKey.encType = eCSR_ENCRYPT_TYPE_NONE;
3534
3535 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07003536 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303537 )
3538 {
3539
3540 hdd_hostapd_state_t *pHostapdState =
Jeff Johnson295189b2012-06-20 16:38:30 -07003541 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
3542 if( pHostapdState->bssState == BSS_START)
3543 {
3544 status = WLANSAP_SetKeySta( pVosContext, &setKey);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303545
Jeff Johnson295189b2012-06-20 16:38:30 -07003546 if ( status != eHAL_STATUS_SUCCESS )
3547 {
3548 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3549 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
3550 __LINE__, status );
3551 }
3552 }
3553 }
3554 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303555 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnson295189b2012-06-20 16:38:30 -07003556 )
3557 {
3558 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3559
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303560 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
3561
3562 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -07003563 "%s: delete key for peerMac %2x:%2x:%2x:%2x:%2x:%2x",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303564 __func__, setKey.peerMac[0], setKey.peerMac[1],
3565 setKey.peerMac[2], setKey.peerMac[3],
Jeff Johnson295189b2012-06-20 16:38:30 -07003566 setKey.peerMac[4], setKey.peerMac[5]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303567 if(pAdapter->sessionCtx.station.conn_info.connState ==
3568 eConnectionState_Associated)
Jeff Johnson295189b2012-06-20 16:38:30 -07003569 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303570 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07003571 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303572
Jeff Johnson295189b2012-06-20 16:38:30 -07003573 if ( 0 != status )
3574 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303575 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07003576 "%s: sme_RoamSetKey failure, returned %d",
3577 __func__, status);
3578 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
3579 return -EINVAL;
3580 }
3581 }
3582 }
3583#endif
Jeff Johnsone7245742012-09-05 17:12:55 -07003584 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07003585 return status;
3586}
3587
3588/*
3589 * FUNCTION: wlan_hdd_cfg80211_set_default_key
3590 * This function is used to set the default tx key index
3591 */
3592#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
3593static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
3594 struct net_device *ndev,
3595 u8 key_index,
3596 bool unicast, bool multicast)
3597#else
3598static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
3599 struct net_device *ndev,
3600 u8 key_index)
3601#endif
3602{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303603 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -07003604 int status = 0;
Gopichand Nakkala29149562013-05-10 21:43:41 +05303605 hdd_wext_state_t *pWextState;
3606 hdd_station_ctx_t *pHddStaCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07003607
3608 ENTER();
3609
Gopichand Nakkala29149562013-05-10 21:43:41 +05303610 if ((NULL == pAdapter))
3611 {
3612 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
3613 "invalid adapter");
3614 return -EINVAL;
3615 }
3616
3617 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
3618 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3619
3620 if ((NULL == pWextState) || (NULL == pHddStaCtx))
3621 {
3622 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
3623 "invalid Wext state or HDD context");
3624 return -EINVAL;
3625 }
3626
Jeff Johnson295189b2012-06-20 16:38:30 -07003627 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d key_index = %d \n",
3628 __func__,pAdapter->device_mode, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303629
Jeff Johnson295189b2012-06-20 16:38:30 -07003630 if (CSR_MAX_NUM_KEY <= key_index)
3631 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303632 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07003633 key_index);
3634
3635 return -EINVAL;
3636 }
3637
Jeff Johnson04dd8a82012-06-29 20:41:40 -07003638 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
3639 {
3640 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3641 "%s:LOGP in Progress. Ignore!!!", __func__);
3642 return -EAGAIN;
3643 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303644
Jeff Johnson295189b2012-06-20 16:38:30 -07003645 if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -07003646 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303647 )
Jeff Johnson295189b2012-06-20 16:38:30 -07003648 {
Gopichand Nakkala29149562013-05-10 21:43:41 +05303649 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
Jeff Johnson295189b2012-06-20 16:38:30 -07003650 pWextState->roamProfile.EncryptionType.encryptionType[0]) &&
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303651 (eCSR_ENCRYPT_TYPE_AES !=
Jeff Johnson295189b2012-06-20 16:38:30 -07003652 pWextState->roamProfile.EncryptionType.encryptionType[0])
3653 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303654 {
3655 /* if default key index is not same as previous one,
Jeff Johnson295189b2012-06-20 16:38:30 -07003656 * then update the default key index */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303657
Jeff Johnson295189b2012-06-20 16:38:30 -07003658 tCsrRoamSetKey setKey;
3659 v_U32_t roamId= 0xFF;
3660 tCsrKeys *Keys = &pWextState->roamProfile.Keys;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303661
3662 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: default tx key index %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07003663 __func__, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303664
Jeff Johnson295189b2012-06-20 16:38:30 -07003665 Keys->defaultIndex = (u8)key_index;
3666 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
3667 setKey.keyId = key_index;
3668 setKey.keyLength = Keys->KeyLength[key_index];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303669
3670 vos_mem_copy(&setKey.Key[0],
3671 &Keys->KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -07003672 Keys->KeyLength[key_index]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303673
Gopichand Nakkala29149562013-05-10 21:43:41 +05303674 setKey.keyDirection = eSIR_TX_RX;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303675
3676 vos_mem_copy(setKey.peerMac,
Jeff Johnson295189b2012-06-20 16:38:30 -07003677 &pHddStaCtx->conn_info.bssId[0],
3678 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303679
Gopichand Nakkala29149562013-05-10 21:43:41 +05303680 if (Keys->KeyLength[key_index] == CSR_WEP40_KEY_LEN &&
3681 pWextState->roamProfile.EncryptionType.encryptionType[0] ==
3682 eCSR_ENCRYPT_TYPE_WEP104)
3683 {
3684 /*In the case of dynamic wep supplicant hardcodes DWEP type to eCSR_ENCRYPT_TYPE_WEP104
3685 even though ap is configured for WEP-40 encryption. In this canse the key length
3686 is 5 but the encryption type is 104 hence checking the key langht(5) and encryption
3687 type(104) and switching encryption type to 40*/
3688 pWextState->roamProfile.EncryptionType.encryptionType[0] =
3689 eCSR_ENCRYPT_TYPE_WEP40;
3690 pWextState->roamProfile.mcEncryptionType.encryptionType[0] =
3691 eCSR_ENCRYPT_TYPE_WEP40;
3692 }
3693
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303694 setKey.encType =
Jeff Johnson295189b2012-06-20 16:38:30 -07003695 pWextState->roamProfile.EncryptionType.encryptionType[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303696
Jeff Johnson295189b2012-06-20 16:38:30 -07003697 /* issue set key request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303698 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07003699 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303700
Jeff Johnson295189b2012-06-20 16:38:30 -07003701 if ( 0 != status )
3702 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303703 hddLog(VOS_TRACE_LEVEL_ERROR,
3704 "%s: sme_RoamSetKey failed, returned %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07003705 status);
3706 return -EINVAL;
3707 }
3708 }
3709 }
3710
3711 /* In SoftAp mode setting key direction for default mode */
3712 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
3713 {
3714 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
3715 pWextState->roamProfile.EncryptionType.encryptionType[0]) &&
3716 (eCSR_ENCRYPT_TYPE_AES !=
3717 pWextState->roamProfile.EncryptionType.encryptionType[0])
3718 )
3719 {
3720 /* Saving key direction for default key index to TX default */
3721 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
3722 pAPCtx->wepKey[key_index].keyDirection = eSIR_TX_DEFAULT;
3723 }
3724 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303725
Jeff Johnson295189b2012-06-20 16:38:30 -07003726 return status;
3727}
3728
Jeff Johnson295189b2012-06-20 16:38:30 -07003729/*
3730 * FUNCTION: wlan_hdd_cfg80211_inform_bss
3731 * This function is used to inform the BSS details to nl80211 interface.
3732 */
3733static struct cfg80211_bss* wlan_hdd_cfg80211_inform_bss(
3734 hdd_adapter_t *pAdapter, tCsrRoamConnectedProfile *roamProfile)
3735{
3736 struct net_device *dev = pAdapter->dev;
3737 struct wireless_dev *wdev = dev->ieee80211_ptr;
3738 struct wiphy *wiphy = wdev->wiphy;
3739 tSirBssDescription *pBssDesc = roamProfile->pBssDesc;
3740 int chan_no;
3741 int ie_length;
3742 const char *ie;
3743 unsigned int freq;
3744 struct ieee80211_channel *chan;
3745 int rssi = 0;
3746 struct cfg80211_bss *bss = NULL;
3747
3748 ENTER();
3749
3750 if( NULL == pBssDesc )
3751 {
3752 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pBssDesc is NULL\n", __func__);
3753 return bss;
3754 }
3755
3756 chan_no = pBssDesc->channelId;
3757 ie_length = GET_IE_LEN_IN_BSS_DESC( pBssDesc->length );
3758 ie = ((ie_length != 0) ? (const char *)&pBssDesc->ieFields: NULL);
3759
3760 if( NULL == ie )
3761 {
3762 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: IE of BSS descriptor is NULL\n", __func__);
3763 return bss;
3764 }
3765
3766#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
3767 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
3768 {
3769 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
3770 }
3771 else
3772 {
3773 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
3774 }
3775#else
3776 freq = ieee80211_channel_to_frequency(chan_no);
3777#endif
3778
3779 chan = __ieee80211_get_channel(wiphy, freq);
3780
3781 bss = cfg80211_get_bss(wiphy, chan, pBssDesc->bssId,
3782 &roamProfile->SSID.ssId[0], roamProfile->SSID.length,
3783 WLAN_CAPABILITY_ESS, WLAN_CAPABILITY_ESS);
3784 if (bss == NULL)
3785 {
3786 rssi = (VOS_MIN ((pBssDesc->rssi + pBssDesc->sinr), 0))*100;
3787
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303788 return (cfg80211_inform_bss(wiphy, chan, pBssDesc->bssId,
3789 le64_to_cpu(*(__le64 *)pBssDesc->timeStamp),
Jeff Johnson295189b2012-06-20 16:38:30 -07003790 pBssDesc->capabilityInfo,
3791 pBssDesc->beaconInterval, ie, ie_length,
3792 rssi, GFP_KERNEL ));
3793}
3794 else
3795 {
3796 return bss;
3797 }
3798}
3799
3800
3801
3802/*
3803 * FUNCTION: wlan_hdd_cfg80211_inform_bss_frame
3804 * This function is used to inform the BSS details to nl80211 interface.
3805 */
3806struct cfg80211_bss*
3807wlan_hdd_cfg80211_inform_bss_frame( hdd_adapter_t *pAdapter,
3808 tSirBssDescription *bss_desc
3809 )
3810{
3811 /*
3812 cfg80211_inform_bss() is not updating ie field of bss entry, if entry
3813 already exists in bss data base of cfg80211 for that particular BSS ID.
3814 Using cfg80211_inform_bss_frame to update the bss entry instead of
3815 cfg80211_inform_bss, But this call expects mgmt packet as input. As of
3816 now there is no possibility to get the mgmt(probe response) frame from PE,
3817 converting bss_desc to ieee80211_mgmt(probe response) and passing to
3818 cfg80211_inform_bss_frame.
3819 */
3820 struct net_device *dev = pAdapter->dev;
3821 struct wireless_dev *wdev = dev->ieee80211_ptr;
3822 struct wiphy *wiphy = wdev->wiphy;
3823 int chan_no = bss_desc->channelId;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08003824#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
3825 qcom_ie_age *qie_age = NULL;
3826 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length ) + sizeof(qcom_ie_age);
3827#else
Jeff Johnson295189b2012-06-20 16:38:30 -07003828 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length );
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08003829#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07003830 const char *ie =
3831 ((ie_length != 0) ? (const char *)&bss_desc->ieFields: NULL);
3832 unsigned int freq;
3833 struct ieee80211_channel *chan;
3834 struct ieee80211_mgmt *mgmt =
3835 kzalloc((sizeof (struct ieee80211_mgmt) + ie_length), GFP_KERNEL);
3836 struct cfg80211_bss *bss_status = NULL;
3837 size_t frame_len = sizeof (struct ieee80211_mgmt) + ie_length;
3838 int rssi = 0;
Jeff Johnsone7245742012-09-05 17:12:55 -07003839#ifdef WLAN_OPEN_SOURCE
3840 struct timespec ts;
3841#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07003842
3843 ENTER();
3844
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -07003845 if (!mgmt)
3846 return NULL;
3847
Jeff Johnson295189b2012-06-20 16:38:30 -07003848 memcpy(mgmt->bssid, bss_desc->bssId, ETH_ALEN);
Jeff Johnsone7245742012-09-05 17:12:55 -07003849
3850#ifdef WLAN_OPEN_SOURCE
3851 /* Android does not want the timestamp from the frame.
3852 Instead it wants a monotonic increasing value */
3853 get_monotonic_boottime(&ts);
3854 mgmt->u.probe_resp.timestamp =
3855 ((u64)ts.tv_sec * 1000000) + (ts.tv_nsec / 1000);
3856#else
3857 /* keep old behavior for non-open source (for now) */
Jeff Johnson295189b2012-06-20 16:38:30 -07003858 memcpy(&mgmt->u.probe_resp.timestamp, bss_desc->timeStamp,
3859 sizeof (bss_desc->timeStamp));
Jeff Johnsone7245742012-09-05 17:12:55 -07003860
3861#endif
3862
Jeff Johnson295189b2012-06-20 16:38:30 -07003863 mgmt->u.probe_resp.beacon_int = bss_desc->beaconInterval;
3864 mgmt->u.probe_resp.capab_info = bss_desc->capabilityInfo;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08003865
3866#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
3867 /* GPS Requirement: need age ie per entry. Using vendor specific. */
3868 /* Assuming this is the last IE, copy at the end */
3869 ie_length -=sizeof(qcom_ie_age);
3870 qie_age = (qcom_ie_age *)(mgmt->u.probe_resp.variable + ie_length);
3871 qie_age->element_id = QCOM_VENDOR_IE_ID;
3872 qie_age->len = QCOM_VENDOR_IE_AGE_LEN;
3873 qie_age->oui_1 = QCOM_OUI1;
3874 qie_age->oui_2 = QCOM_OUI2;
3875 qie_age->oui_3 = QCOM_OUI3;
3876 qie_age->type = QCOM_VENDOR_IE_AGE_TYPE;
3877 qie_age->age = vos_timer_get_system_ticks() - bss_desc->nReceivedTime;
3878#endif
3879
Jeff Johnson295189b2012-06-20 16:38:30 -07003880 memcpy(mgmt->u.probe_resp.variable, ie, ie_length);
Gopichand Nakkalad908ec82013-05-16 19:32:19 +05303881 if (bss_desc->fProbeRsp)
3882 {
3883 mgmt->frame_control |=
3884 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_RESP);
3885 }
3886 else
3887 {
3888 mgmt->frame_control |=
3889 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_BEACON);
3890 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003891
3892#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303893 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ) &&
Jeff Johnson295189b2012-06-20 16:38:30 -07003894 (wiphy->bands[IEEE80211_BAND_2GHZ] != NULL))
3895 {
3896 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
3897 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303898 else if ((chan_no > ARRAY_SIZE(hdd_channels_2_4_GHZ)) &&
Jeff Johnson295189b2012-06-20 16:38:30 -07003899 (wiphy->bands[IEEE80211_BAND_5GHZ] != NULL))
3900
3901 {
3902 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
3903 }
3904 else
3905 {
3906 kfree(mgmt);
3907 return NULL;
3908 }
3909#else
3910 freq = ieee80211_channel_to_frequency(chan_no);
3911#endif
3912 chan = __ieee80211_get_channel(wiphy, freq);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -08003913 /*when the band is changed on the fly using the GUI, three things are done
3914 * 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)
3915 * as part of the scan abort, message willbe queued to PE and we proceed with flushing and changinh the band.
3916 * pe will stop the scanning further and report back the results what ever it had till now by calling the call back function.
3917 * if the time between update band and scandone call back is sufficent enough the band change reflects in SME, SME validates the channels
3918 * and discards the channels correponding to previous band and calls back with zero bss results.
3919 * 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
3920 * all the channels correponding to previous band.this is due to race condition.but those channels are invalid to the new band and so
3921 * this function __ieee80211_get_channel will return NULL.Each time we report scan result with this pointer null warning kernel trace is printed.
3922 * if the scan results contain large number of APs continuosly kernel warning trace is printed and it will lead to apps watch dog bark.
3923 * So drop the bss and continue to next bss.
3924 */
3925 if(chan == NULL)
3926 {
3927 hddLog(VOS_TRACE_LEVEL_INFO, "%s chan pointer is NULL", __func__);
Chilam Ngc4244af2013-04-01 15:37:32 -07003928 kfree(mgmt);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -08003929 return NULL;
3930 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003931 /*To keep the rssi icon of the connected AP in the scan window
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303932 *and the rssi icon of the wireless networks in sync
Jeff Johnson295189b2012-06-20 16:38:30 -07003933 * */
3934 if (( eConnectionState_Associated ==
3935 pAdapter->sessionCtx.station.conn_info.connState ) &&
3936 ( VOS_TRUE == vos_mem_compare(bss_desc->bssId,
3937 pAdapter->sessionCtx.station.conn_info.bssId,
3938 WNI_CFG_BSSID_LEN)))
3939 {
3940 /* supplicant takes the signal strength in terms of mBm(100*dBm) */
3941 rssi = (pAdapter->rssi * 100);
3942 }
3943 else
3944 {
3945 rssi = (VOS_MIN ((bss_desc->rssi + bss_desc->sinr), 0))*100;
3946 }
3947
3948 bss_status = cfg80211_inform_bss_frame(wiphy, chan, mgmt,
3949 frame_len, rssi, GFP_KERNEL);
3950 kfree(mgmt);
3951 return bss_status;
3952}
3953
3954/*
3955 * FUNCTION: wlan_hdd_cfg80211_update_bss_db
3956 * This function is used to update the BSS data base of CFG8011
3957 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303958struct cfg80211_bss* wlan_hdd_cfg80211_update_bss_db( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07003959 tCsrRoamInfo *pRoamInfo
3960 )
3961{
3962 tCsrRoamConnectedProfile roamProfile;
3963 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
3964 struct cfg80211_bss *bss = NULL;
3965
3966 ENTER();
3967
3968 memset(&roamProfile, 0, sizeof(tCsrRoamConnectedProfile));
3969 sme_RoamGetConnectProfile(hHal, pAdapter->sessionId, &roamProfile);
3970
3971 if (NULL != roamProfile.pBssDesc)
3972 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303973 bss = wlan_hdd_cfg80211_inform_bss(pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07003974 &roamProfile);
3975
3976 if (NULL == bss)
3977 {
3978 hddLog(VOS_TRACE_LEVEL_INFO, "%s: cfg80211_inform_bss return NULL",
3979 __func__);
3980 }
3981
3982 sme_RoamFreeConnectProfile(hHal, &roamProfile);
3983 }
3984 else
3985 {
3986 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: roamProfile.pBssDesc is NULL",
3987 __func__);
3988 }
3989 return bss;
3990}
3991
3992/*
3993 * FUNCTION: wlan_hdd_cfg80211_update_bss
3994 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303995static int wlan_hdd_cfg80211_update_bss( struct wiphy *wiphy,
3996 hdd_adapter_t *pAdapter
Jeff Johnson295189b2012-06-20 16:38:30 -07003997 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303998{
Jeff Johnson295189b2012-06-20 16:38:30 -07003999 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
4000 tCsrScanResultInfo *pScanResult;
4001 eHalStatus status = 0;
4002 tScanResultHandle pResult;
4003 struct cfg80211_bss *bss_status = NULL;
4004
4005 ENTER();
4006
4007 if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress)
4008 {
4009 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:LOGP in Progress. Ignore!!!",__func__);
4010 return -EAGAIN;
4011 }
4012
4013 /*
4014 * start getting scan results and populate cgf80211 BSS database
4015 */
4016 status = sme_ScanGetResult(hHal, pAdapter->sessionId, NULL, &pResult);
4017
4018 /* no scan results */
4019 if (NULL == pResult)
4020 {
4021 hddLog(VOS_TRACE_LEVEL_INFO, "%s: No scan result\n", __func__);
4022 return status;
4023 }
4024
4025 pScanResult = sme_ScanResultGetFirst(hHal, pResult);
4026
4027 while (pScanResult)
4028 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304029 /*
4030 * cfg80211_inform_bss() is not updating ie field of bss entry, if
4031 * entry already exists in bss data base of cfg80211 for that
4032 * particular BSS ID. Using cfg80211_inform_bss_frame to update the
4033 * bss entry instead of cfg80211_inform_bss, But this call expects
4034 * mgmt packet as input. As of now there is no possibility to get
4035 * the mgmt(probe response) frame from PE, converting bss_desc to
Jeff Johnson295189b2012-06-20 16:38:30 -07004036 * ieee80211_mgmt(probe response) and passing to c
4037 * fg80211_inform_bss_frame.
4038 * */
4039
4040 bss_status = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
4041 &pScanResult->BssDescriptor);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304042
Jeff Johnson295189b2012-06-20 16:38:30 -07004043
4044 if (NULL == bss_status)
4045 {
4046 hddLog(VOS_TRACE_LEVEL_INFO,
4047 "%s: NULL returned by cfg80211_inform_bss\n", __func__);
4048 }
4049 else
4050 {
4051 cfg80211_put_bss(bss_status);
4052 }
4053
4054 pScanResult = sme_ScanResultGetNext(hHal, pResult);
4055 }
4056
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304057 sme_ScanResultPurge(hHal, pResult);
Jeff Johnson295189b2012-06-20 16:38:30 -07004058
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304059 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07004060}
4061
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004062void
4063hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel)
4064{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304065 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07004066 "%02X:%02X:%02X:%02X:%02X:%02X\n",
4067 macAddr[0], macAddr[1], macAddr[2], macAddr[3], macAddr[4],
4068 macAddr[5]);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004069} /****** end hddPrintMacAddr() ******/
4070
4071void
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07004072hddPrintPmkId(tANI_U8 *pmkId, tANI_U8 logLevel)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004073{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304074 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07004075 "%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X\n",
4076 pmkId[0], pmkId[1], pmkId[2], pmkId[3], pmkId[4],
4077 pmkId[5], pmkId[6], pmkId[7], pmkId[8], pmkId[9], pmkId[10],
4078 pmkId[11], pmkId[12], pmkId[13], pmkId[14], pmkId[15]);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004079} /****** end hddPrintPmkId() ******/
4080
4081//hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel);
4082//hddPrintMacAddr(macAddr, VOS_TRACE_LEVEL_FATAL);
4083
4084//void sirDumpBuf(tpAniSirGlobal pMac, tANI_U8 modId, tANI_U32 level, tANI_U8 *buf, tANI_U32 size);
4085//sirDumpBuf(pMac, VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, pmkid, 16);
4086
4087#define dump_bssid(bssid) \
4088 { \
Jeff Johnsone7245742012-09-05 17:12:55 -07004089 hddLog(VOS_TRACE_LEVEL_INFO, "BSSID (MAC) address:\t"); \
4090 hddPrintMacAddr(bssid, VOS_TRACE_LEVEL_INFO);\
4091 hddLog(VOS_TRACE_LEVEL_INFO, "\n"); \
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004092 }
4093
4094#define dump_pmkid(pMac, pmkid) \
4095 { \
Jeff Johnsone7245742012-09-05 17:12:55 -07004096 hddLog(VOS_TRACE_LEVEL_INFO, "PMKSA-ID:\t"); \
4097 hddPrintPmkId(pmkid, VOS_TRACE_LEVEL_INFO);\
4098 hddLog(VOS_TRACE_LEVEL_INFO, "\n"); \
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004099 }
4100
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -07004101#if defined(FEATURE_WLAN_LFR) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004102/*
4103 * FUNCTION: wlan_hdd_cfg80211_pmksa_candidate_notify
4104 * This function is used to notify the supplicant of a new PMKSA candidate.
4105 */
4106int wlan_hdd_cfg80211_pmksa_candidate_notify(
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304107 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004108 int index, bool preauth )
4109{
Jeff Johnsone7245742012-09-05 17:12:55 -07004110#ifdef FEATURE_WLAN_OKC
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004111 struct net_device *dev = pAdapter->dev;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004112 hdd_context_t *pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004113
4114 ENTER();
Jeff Johnsone7245742012-09-05 17:12:55 -07004115 hddLog(VOS_TRACE_LEVEL_INFO, "%s is going to notify supplicant of:", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004116
4117 if( NULL == pRoamInfo )
4118 {
4119 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pRoamInfo is NULL\n", __func__);
4120 return -EINVAL;
4121 }
4122
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004123 if (eANI_BOOLEAN_TRUE == hdd_is_okc_mode_enabled(pHddCtx))
4124 {
4125 dump_bssid(pRoamInfo->bssid);
4126 cfg80211_pmksa_candidate_notify(dev, index,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004127 pRoamInfo->bssid, preauth, GFP_KERNEL);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004128 }
Jeff Johnsone7245742012-09-05 17:12:55 -07004129#endif /* FEATURE_WLAN_OKC */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304130 return 0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004131}
4132#endif //FEATURE_WLAN_LFR
4133
Jeff Johnson295189b2012-06-20 16:38:30 -07004134/*
4135 * FUNCTION: hdd_cfg80211_scan_done_callback
4136 * scanning callback function, called after finishing scan
4137 *
4138 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304139static eHalStatus hdd_cfg80211_scan_done_callback(tHalHandle halHandle,
Jeff Johnson295189b2012-06-20 16:38:30 -07004140 void *pContext, tANI_U32 scanId, eCsrScanStatus status)
4141{
4142 struct net_device *dev = (struct net_device *) pContext;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304143 //struct wireless_dev *wdev = dev->ieee80211_ptr;
Jeff Johnson295189b2012-06-20 16:38:30 -07004144 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07004145 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
4146 hdd_scaninfo_t *pScanInfo = &pHddCtx->scan_info;
Jeff Johnson295189b2012-06-20 16:38:30 -07004147 struct cfg80211_scan_request *req = NULL;
4148 int ret = 0;
4149
4150 ENTER();
4151
4152 hddLog(VOS_TRACE_LEVEL_INFO,
4153 "%s called with halHandle = %p, pContext = %p,"
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304154 "scanID = %d, returned status = %d\n",
Jeff Johnson295189b2012-06-20 16:38:30 -07004155 __func__, halHandle, pContext, (int) scanId, (int) status);
4156
4157 //Block on scan req completion variable. Can't wait forever though.
4158 ret = wait_for_completion_interruptible_timeout(
4159 &pScanInfo->scan_req_completion_event,
4160 msecs_to_jiffies(WLAN_WAIT_TIME_SCAN_REQ));
4161 if (!ret)
4162 {
4163 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -07004164 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -07004165 }
4166
4167 if(pScanInfo->mScanPending != VOS_TRUE)
4168 {
4169 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -07004170 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -07004171 }
4172
4173 /* Check the scanId */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304174 if (pScanInfo->scanId != scanId)
Jeff Johnson295189b2012-06-20 16:38:30 -07004175 {
4176 hddLog(VOS_TRACE_LEVEL_INFO,
4177 "%s called with mismatched scanId pScanInfo->scanId = %d "
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304178 "scanId = %d \n", __func__, (int) pScanInfo->scanId,
Jeff Johnson295189b2012-06-20 16:38:30 -07004179 (int) scanId);
4180 }
4181
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304182 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07004183 pAdapter);
4184
4185 if (0 > ret)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304186 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004187
4188
4189 /* If any client wait scan result through WEXT
4190 * send scan done event to client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07004191 if (pHddCtx->scan_info.waitScanResult)
Jeff Johnson295189b2012-06-20 16:38:30 -07004192 {
4193 /* The other scan request waiting for current scan finish
4194 * Send event to notify current scan finished */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07004195 if(WEXT_SCAN_PENDING_DELAY == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -07004196 {
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07004197 vos_event_set(&pHddCtx->scan_info.scan_finished_event);
Jeff Johnson295189b2012-06-20 16:38:30 -07004198 }
4199 /* Send notify to WEXT client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07004200 else if(WEXT_SCAN_PENDING_PIGGYBACK == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -07004201 {
4202 struct net_device *dev = pAdapter->dev;
4203 union iwreq_data wrqu;
4204 int we_event;
4205 char *msg;
4206
4207 memset(&wrqu, '\0', sizeof(wrqu));
4208 we_event = SIOCGIWSCAN;
4209 msg = NULL;
4210 wireless_send_event(dev, we_event, &wrqu, msg);
4211 }
4212 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07004213 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07004214
4215 /* Get the Scan Req */
4216 req = pAdapter->request;
4217
4218 if (!req)
4219 {
4220 hddLog(VOS_TRACE_LEVEL_ERROR, "request is became NULL\n");
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07004221 pScanInfo->mScanPending = VOS_FALSE;
Jeff Johnsone7245742012-09-05 17:12:55 -07004222 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -07004223 }
4224
4225 /*
4226 * setting up 0, just in case.
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304227 */
Jeff Johnson295189b2012-06-20 16:38:30 -07004228 req->n_ssids = 0;
4229 req->n_channels = 0;
4230 req->ie = 0;
4231
Jeff Johnson295189b2012-06-20 16:38:30 -07004232 pAdapter->request = NULL;
Jeff Johnsone7245742012-09-05 17:12:55 -07004233 /* Scan is no longer pending */
4234 pScanInfo->mScanPending = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07004235
Madan Mohan Koyyalamudib764bf82012-10-11 16:38:51 -07004236 /*
4237 * cfg80211_scan_done informing NL80211 about completion
4238 * of scanning
4239 */
4240 cfg80211_scan_done(req, false);
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -08004241 complete(&pScanInfo->abortscan_event_var);
Jeff Johnson295189b2012-06-20 16:38:30 -07004242
Jeff Johnsone7245742012-09-05 17:12:55 -07004243allow_suspend:
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07004244 /* release the wake lock at the end of the scan*/
4245 hdd_allow_suspend();
Jeff Johnsone7245742012-09-05 17:12:55 -07004246
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -07004247 /* Acquire wakelock to handle the case where APP's tries to suspend
4248 * immediatly after the driver gets connect request(i.e after scan)
4249 * from supplicant, this result in app's is suspending and not able
4250 * to process the connect request to AP */
Amar Singhal6144c002013-05-03 16:11:42 -07004251 hdd_allow_suspend_timeout(1000);
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -07004252
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07004253#ifdef FEATURE_WLAN_TDLS
4254 wlan_hdd_tdls_scan_done_callback(pAdapter);
4255#endif
4256
Jeff Johnson295189b2012-06-20 16:38:30 -07004257 EXIT();
4258 return 0;
4259}
4260
4261/*
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08004262 * FUNCTION: hdd_isScanAllowed
4263 * Go through each adapter and check if scan allowed
4264 *
4265 */
4266v_BOOL_t hdd_isScanAllowed( hdd_context_t *pHddCtx )
4267{
4268 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
4269 hdd_station_ctx_t *pHddStaCtx = NULL;
4270 hdd_adapter_t *pAdapter = NULL;
4271 VOS_STATUS status = 0;
4272 v_U8_t staId = 0;
4273 v_U8_t *staMac = NULL;
4274
4275 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
4276
4277 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
4278 {
4279 pAdapter = pAdapterNode->pAdapter;
4280
4281 if( pAdapter )
4282 {
4283 hddLog(VOS_TRACE_LEVEL_INFO,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304284 "%s: Adapter with device mode %d exists",
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08004285 __func__, pAdapter->device_mode);
4286 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
4287 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
4288 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
4289 {
4290 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4291 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
4292 (VOS_FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
4293 {
4294 staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]);
4295 hddLog(VOS_TRACE_LEVEL_ERROR,
4296 "%s: client %02x:%02x:%02x:%02x:%02x:%02x is in the "
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304297 "middle of WPS/EAPOL exchange.", __func__,
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08004298 staMac[0], staMac[1], staMac[2],
4299 staMac[3], staMac[4], staMac[5]);
4300 return VOS_FALSE;
4301 }
4302 }
4303 else if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) ||
4304 (WLAN_HDD_P2P_GO == pAdapter->device_mode))
4305 {
4306 for (staId = 0; staId < WLAN_MAX_STA_COUNT; staId++)
4307 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304308 if ((pAdapter->aStaInfo[staId].isUsed) &&
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08004309 (WLANTL_STA_CONNECTED == pAdapter->aStaInfo[staId].tlSTAState))
4310 {
4311 staMac = (v_U8_t *) &(pAdapter->aStaInfo[staId].macAddrSTA.bytes[0]);
4312
4313 hddLog(VOS_TRACE_LEVEL_ERROR,
4314 "%s: client %02x:%02x:%02x:%02x:%02x:%02x of SoftAP/P2P-GO is in the "
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304315 "middle of WPS/EAPOL exchange.", __func__,
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08004316 staMac[0], staMac[1], staMac[2],
4317 staMac[3], staMac[4], staMac[5]);
4318 return VOS_FALSE;
4319 }
4320 }
4321 }
4322 }
4323 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
4324 pAdapterNode = pNext;
4325 }
4326 hddLog(VOS_TRACE_LEVEL_INFO,
4327 "%s: Scan allowed", __func__);
4328 return VOS_TRUE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304329}
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08004330
4331/*
Jeff Johnson295189b2012-06-20 16:38:30 -07004332 * FUNCTION: wlan_hdd_cfg80211_scan
4333 * this scan respond to scan trigger and update cfg80211 scan database
4334 * later, scan dump command can be used to recieve scan results
4335 */
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -08004336int wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
4337#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
4338 struct net_device *dev,
4339#endif
4340 struct cfg80211_scan_request *request)
4341{
4342#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
4343 struct net_device *dev = request->wdev->netdev;
4344#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304345 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Jeff Johnson295189b2012-06-20 16:38:30 -07004346 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
4347 hdd_wext_state_t *pwextBuf = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
4348 hdd_config_t *cfg_param = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
4349 tCsrScanRequest scanRequest;
4350 tANI_U8 *channelList = NULL, i;
4351 v_U32_t scanId = 0;
4352 int status = 0;
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07004353 hdd_scaninfo_t *pScanInfo = &pHddCtx->scan_info;
Jeff Johnson295189b2012-06-20 16:38:30 -07004354 v_U8_t* pP2pIe = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07004355
4356 ENTER();
4357
4358 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",
4359 __func__,pAdapter->device_mode);
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08004360
Gopichand Nakkala681989c2013-03-06 22:27:48 -08004361 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08004362 (eConnectionState_Connecting ==
Gopichand Nakkala681989c2013-03-06 22:27:48 -08004363 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08004364 {
4365 hddLog(VOS_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08004366 "%s: %p(%d) Connection in progress: Scan request denied (EBUSY)", __func__, \
4367 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08004368 return -EBUSY;
4369 }
4370
Jeff Johnson295189b2012-06-20 16:38:30 -07004371#ifdef WLAN_BTAMP_FEATURE
4372 //Scan not supported when AMP traffic is on.
Gopichand Nakkala681989c2013-03-06 22:27:48 -08004373 if (VOS_TRUE == WLANBAP_AmpSessionOn())
Jeff Johnson295189b2012-06-20 16:38:30 -07004374 {
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08004375 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07004376 "%s: No scanning when AMP is on", __func__);
4377 return -EOPNOTSUPP;
4378 }
4379#endif
4380 //Scan on any other interface is not supported.
Gopichand Nakkala681989c2013-03-06 22:27:48 -08004381 if (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07004382 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -08004383 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07004384 "%s: Not scanning on device_mode = %d",
4385 __func__, pAdapter->device_mode);
4386 return -EOPNOTSUPP;
4387 }
4388
4389 if (TRUE == pScanInfo->mScanPending)
4390 {
4391 hddLog(VOS_TRACE_LEVEL_INFO, "%s: mScanPending is TRUE", __func__);
Gopichand Nakkala681989c2013-03-06 22:27:48 -08004392 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -07004393 }
4394
4395 if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress)
4396 {
4397 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
4398 "%s:LOGP in Progress. Ignore!!!", __func__);
4399 return -EAGAIN;
4400 }
4401
Mohit Khanna6c52bbf2012-09-11 15:10:12 -07004402 if ((WLAN_HDD_GET_CTX(pAdapter))->isLoadUnloadInProgress)
4403 {
4404 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
4405 "%s:Unloading/Loading in Progress. Ignore!!!", __func__);
4406 return -EAGAIN;
4407 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304408 //Don't Allow Scan and return busy if Remain On
Jeff Johnson32d95a32012-09-10 13:15:23 -07004409 //Channel and action frame is pending
4410 //Otherwise Cancel Remain On Channel and allow Scan
4411 //If no action frame pending
Gopichand Nakkala681989c2013-03-06 22:27:48 -08004412 if (0 != wlan_hdd_check_remain_on_channel(pAdapter))
Jeff Johnson32d95a32012-09-10 13:15:23 -07004413 {
4414 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Remain On Channel Pending", __func__);
4415 return -EBUSY;
4416 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08004417#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07004418 /* if tdls disagree scan right now, return immediately.
4419 tdls will schedule the scan when scan is allowed. (return SUCCESS)
4420 or will reject the scan if any TDLS is in progress. (return -EBUSY)
4421 */
4422 status = wlan_hdd_tdls_scan_callback (pAdapter,
4423 wiphy,
4424#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
4425 dev,
Gopichand Nakkalac3c42b92013-03-20 19:42:34 -07004426#endif
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07004427 request);
4428 if(status <= 0)
4429 {
4430 hddLog(VOS_TRACE_LEVEL_INFO, "%s: TDLS Pending %d", __func__, status);
4431 return status;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08004432 }
4433#endif
Jeff Johnson32d95a32012-09-10 13:15:23 -07004434
Jeff Johnson295189b2012-06-20 16:38:30 -07004435 if (mutex_lock_interruptible(&pHddCtx->tmInfo.tmOperationLock))
4436 {
4437 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_ERROR,
Jeff Johnson1250df42012-12-10 14:31:52 -08004438 "%s: Acquire lock fail", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004439 return -EAGAIN;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304440 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004441 if (TRUE == pHddCtx->tmInfo.tmAction.enterImps)
4442 {
4443 hddLog(VOS_TRACE_LEVEL_WARN,
4444 "%s: MAX TM Level Scan not allowed", __func__);
4445 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304446 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -07004447 }
4448 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
4449
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08004450 /* Check if scan is allowed at this point of time.
4451 */
4452 if (!hdd_isScanAllowed(pHddCtx))
4453 {
4454 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Scan not allowed", __func__);
4455 return -EBUSY;
4456 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304457
Jeff Johnson295189b2012-06-20 16:38:30 -07004458 vos_mem_zero( &scanRequest, sizeof(scanRequest));
4459
4460 if (NULL != request)
4461 {
4462 hddLog(VOS_TRACE_LEVEL_INFO, "scan request for ssid = %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304463 (int)request->n_ssids);
Jeff Johnson295189b2012-06-20 16:38:30 -07004464
4465 /* Even though supplicant doesn't provide any SSIDs, n_ssids is set to 1.
4466 * Becasue of this, driver is assuming that this is not wildcard scan and so
4467 * is not aging out the scan results.
4468 */
Jeff Johnson32d95a32012-09-10 13:15:23 -07004469 if (request->ssids && '\0' == request->ssids->ssid[0])
Jeff Johnson295189b2012-06-20 16:38:30 -07004470 {
4471 request->n_ssids = 0;
4472 }
4473
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07004474 if ((request->ssids) && (0 < request->n_ssids))
Jeff Johnson295189b2012-06-20 16:38:30 -07004475 {
4476 tCsrSSIDInfo *SsidInfo;
4477 int j;
4478 scanRequest.SSIDs.numOfSSIDs = request->n_ssids;
4479 /* Allocate num_ssid tCsrSSIDInfo structure */
4480 SsidInfo = scanRequest.SSIDs.SSIDList =
4481 ( tCsrSSIDInfo *)vos_mem_malloc(
4482 request->n_ssids*sizeof(tCsrSSIDInfo));
4483
4484 if(NULL == scanRequest.SSIDs.SSIDList)
4485 {
4486 hddLog(VOS_TRACE_LEVEL_ERROR,
4487 "memory alloc failed SSIDInfo buffer");
4488 return -ENOMEM;
4489 }
4490
4491 /* copy all the ssid's and their length */
4492 for(j = 0; j < request->n_ssids; j++, SsidInfo++)
4493 {
4494 /* get the ssid length */
4495 SsidInfo->SSID.length = request->ssids[j].ssid_len;
4496 vos_mem_copy(SsidInfo->SSID.ssId, &request->ssids[j].ssid[0],
4497 SsidInfo->SSID.length);
4498 SsidInfo->SSID.ssId[SsidInfo->SSID.length] = '\0';
4499 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "SSID number %d: %s",
4500 j, SsidInfo->SSID.ssId);
4501 }
4502 /* set the scan type to active */
4503 scanRequest.scanType = eSIR_ACTIVE_SCAN;
4504 }
4505 else if(WLAN_HDD_P2P_GO == pAdapter->device_mode)
4506 {
4507 /* set the scan type to active */
4508 scanRequest.scanType = eSIR_ACTIVE_SCAN;
4509 }
4510 else
4511 {
4512 /*Set the scan type to default type, in this case it is ACTIVE*/
4513 scanRequest.scanType = pScanInfo->scan_mode;
4514 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304515 scanRequest.minChnTime = cfg_param->nActiveMinChnTime;
Jeff Johnson295189b2012-06-20 16:38:30 -07004516 scanRequest.maxChnTime = cfg_param->nActiveMaxChnTime;
4517 }
4518 else
4519 {
4520 /* set the scan type to active */
4521 scanRequest.scanType = eSIR_ACTIVE_SCAN;
4522 vos_mem_set( scanRequest.bssid, sizeof( tCsrBssid ), 0xff );
4523
4524 /* set min and max channel time to zero */
4525 scanRequest.minChnTime = 0;
4526 scanRequest.maxChnTime = 0;
4527 }
4528
4529 /* set BSSType to default type */
4530 scanRequest.BSSType = eCSR_BSS_TYPE_ANY;
4531
4532 /*TODO: scan the requested channels only*/
4533
4534 /*Right now scanning all the channels */
4535 if( request )
4536 {
4537 if( request->n_channels )
4538 {
4539 channelList = vos_mem_malloc( request->n_channels );
4540 if( NULL == channelList )
4541 {
4542 status = -ENOMEM;
4543 goto free_mem;
4544 }
4545
4546 for( i = 0 ; i < request->n_channels ; i++ )
4547 channelList[i] = request->channels[i]->hw_value;
4548 }
4549
4550 scanRequest.ChannelInfo.numOfChannels = request->n_channels;
4551 scanRequest.ChannelInfo.ChannelList = channelList;
4552
4553 /* set requestType to full scan */
4554 scanRequest.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304555
4556 /* Flush the scan results(only p2p beacons) for STA scan and P2P
Madan Mohan Koyyalamudi8d50f312012-11-27 15:48:57 -08004557 * search (Flush on both full scan and social scan but not on single
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304558 * channel scan).P2P search happens on 3 social channels (1, 6, 11)
Madan Mohan Koyyalamudi8d50f312012-11-27 15:48:57 -08004559 */
4560
4561 /* Supplicant does single channel scan after 8-way handshake
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304562 * and in that case driver shoudnt flush scan results. If
4563 * driver flushes the scan results here and unfortunately if
4564 * the AP doesnt respond to our probe req then association
Madan Mohan Koyyalamudi8d50f312012-11-27 15:48:57 -08004565 * fails which is not desired
4566 */
4567
4568 if( request->n_channels != WLAN_HDD_P2P_SINGLE_CHANNEL_SCAN )
4569 {
4570 sme_ScanFlushP2PResult( WLAN_HDD_GET_HAL_CTX(pAdapter),
4571 pAdapter->sessionId );
4572 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004573
4574 if( request->ie_len )
4575 {
4576 /* save this for future association (join requires this) */
4577 memset( &pScanInfo->scanAddIE, 0, sizeof(pScanInfo->scanAddIE) );
4578 memcpy( pScanInfo->scanAddIE.addIEdata, request->ie, request->ie_len);
4579 pScanInfo->scanAddIE.length = request->ie_len;
4580
4581 if((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Jeff Johnsone7245742012-09-05 17:12:55 -07004582 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
4583 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -07004584 )
4585 {
4586 pwextBuf->roamProfile.pAddIEScan = pScanInfo->scanAddIE.addIEdata;
4587 pwextBuf->roamProfile.nAddIEScanLength = pScanInfo->scanAddIE.length;
4588 }
4589
4590 scanRequest.uIEFieldLen = pScanInfo->scanAddIE.length;
4591 scanRequest.pIEField = pScanInfo->scanAddIE.addIEdata;
4592
Jeff Johnson295189b2012-06-20 16:38:30 -07004593 pP2pIe = wlan_hdd_get_p2p_ie_ptr((v_U8_t*)request->ie,
4594 request->ie_len);
4595 if (pP2pIe != NULL)
4596 {
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07004597#ifdef WLAN_FEATURE_P2P_DEBUG
4598 if (((globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED) ||
4599 (globalP2PConnectionStatus == P2P_GO_NEG_PROCESS)) &&
4600 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
4601 {
4602 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_1;
4603 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
4604 "Go nego completed to Connection is started");
4605 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
4606 "for 8way Handshake");
4607 }
4608 else if((globalP2PConnectionStatus == P2P_CLIENT_DISCONNECTED_STATE) &&
4609 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
4610 {
4611 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_2;
4612 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
4613 "Disconnected state to Connection is started");
4614 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
4615 "for 4way Handshake");
4616 }
4617#endif
4618
Jeff Johnsone7245742012-09-05 17:12:55 -07004619 /* no_cck will be set during p2p find to disable 11b rates */
4620 if(TRUE == request->no_cck)
Jeff Johnson295189b2012-06-20 16:38:30 -07004621 {
Jeff Johnson295189b2012-06-20 16:38:30 -07004622 hddLog(VOS_TRACE_LEVEL_INFO,
4623 "%s: This is a P2P Search", __func__);
4624 scanRequest.p2pSearch = 1;
Jeff Johnsone7245742012-09-05 17:12:55 -07004625
Jeff Johnsone7245742012-09-05 17:12:55 -07004626 if( request->n_channels == WLAN_HDD_P2P_SOCIAL_CHANNELS )
4627 {
Madan Mohan Koyyalamudi1b1d9e82012-10-21 11:38:33 -07004628 /* set requestType to P2P Discovery */
4629 scanRequest.requestType = eCSR_SCAN_P2P_DISCOVERY;
Jeff Johnsone7245742012-09-05 17:12:55 -07004630 }
4631
4632 /*
4633 Skip Dfs Channel in case of P2P Search
4634 if it is set in ini file
4635 */
4636 if(cfg_param->skipDfsChnlInP2pSearch)
4637 {
4638 scanRequest.skipDfsChnlInP2pSearch = 1;
4639 }
4640 else
4641 {
4642 scanRequest.skipDfsChnlInP2pSearch = 0;
4643 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004644
Jeff Johnson295189b2012-06-20 16:38:30 -07004645 }
4646 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004647 }
4648 }
4649
4650 INIT_COMPLETION(pScanInfo->scan_req_completion_event);
4651
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07004652 /* acquire the wakelock to avoid the apps suspend during the scan. To
4653 * address the following issues.
4654 * 1) Disconnected scenario: we are not allowing the suspend as WLAN is not in
4655 * BMPS/IMPS this result in android trying to suspend aggressively and backing off
4656 * for long time, this result in apps running at full power for long time.
4657 * 2) Connected scenario: If we allow the suspend during the scan, RIVA will
4658 * be stuck in full power because of resume BMPS
4659 */
4660 hdd_prevent_suspend();
Jeff Johnsone7245742012-09-05 17:12:55 -07004661
4662 status = sme_ScanRequest( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07004663 pAdapter->sessionId, &scanRequest, &scanId,
4664 &hdd_cfg80211_scan_done_callback, dev );
Jeff Johnsone7245742012-09-05 17:12:55 -07004665
Jeff Johnson295189b2012-06-20 16:38:30 -07004666 if (eHAL_STATUS_SUCCESS != status)
4667 {
4668 hddLog(VOS_TRACE_LEVEL_ERROR,
4669 "%s: sme_ScanRequest returned error %d", __func__, status);
4670 complete(&pScanInfo->scan_req_completion_event);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -07004671 if(eHAL_STATUS_RESOURCES == status)
4672 {
Madan Mohan Koyyalamudia3fcf142012-10-18 15:01:20 -07004673 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 -07004674 status = -EBUSY;
4675 } else {
4676 status = -EIO;
4677 }
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07004678 hdd_allow_suspend();
Jeff Johnson295189b2012-06-20 16:38:30 -07004679 goto free_mem;
4680 }
4681
4682 pScanInfo->mScanPending = TRUE;
4683 pAdapter->request = request;
4684 pScanInfo->scanId = scanId;
4685
4686 complete(&pScanInfo->scan_req_completion_event);
4687
4688free_mem:
4689 if( scanRequest.SSIDs.SSIDList )
4690 {
4691 vos_mem_free(scanRequest.SSIDs.SSIDList);
4692 }
4693
4694 if( channelList )
4695 vos_mem_free( channelList );
4696
4697 EXIT();
4698
4699 return status;
4700}
4701
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07004702
4703void hdd_select_cbmode( hdd_adapter_t *pAdapter,v_U8_t operationChannel)
4704{
4705 v_U8_t iniDot11Mode =
4706 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->dot11Mode;
4707 eHddDot11Mode hddDot11Mode = iniDot11Mode;
4708
4709 switch ( iniDot11Mode )
4710 {
4711 case eHDD_DOT11_MODE_AUTO:
4712 case eHDD_DOT11_MODE_11ac:
4713 case eHDD_DOT11_MODE_11ac_ONLY:
4714#ifdef WLAN_FEATURE_11AC
4715 hddDot11Mode = eHDD_DOT11_MODE_11ac;
4716#else
4717 hddDot11Mode = eHDD_DOT11_MODE_11n;
4718#endif
4719 break;
4720 case eHDD_DOT11_MODE_11n:
4721 case eHDD_DOT11_MODE_11n_ONLY:
4722 hddDot11Mode = eHDD_DOT11_MODE_11n;
4723 break;
4724 default:
4725 hddDot11Mode = iniDot11Mode;
4726 break;
4727 }
4728 /* This call decides required channel bonding mode */
4729 sme_SelectCBMode((WLAN_HDD_GET_CTX(pAdapter)->hHal),
4730 hdd_cfg_xlate_to_csr_phy_mode(hddDot11Mode),
4731 operationChannel);
4732}
4733
Jeff Johnson295189b2012-06-20 16:38:30 -07004734/*
4735 * FUNCTION: wlan_hdd_cfg80211_connect_start
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304736 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -07004737 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304738int wlan_hdd_cfg80211_connect_start( hdd_adapter_t *pAdapter,
Jeff Johnson32d95a32012-09-10 13:15:23 -07004739 const u8 *ssid, size_t ssid_len, const u8 *bssid, u8 operatingChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -07004740{
4741 int status = 0;
4742 hdd_wext_state_t *pWextState;
4743 v_U32_t roamId;
4744 tCsrRoamProfile *pRoamProfile;
4745 eMib_dot11DesiredBssType connectedBssType;
4746 eCsrAuthType RSNAuthType;
4747
4748 ENTER();
4749
4750 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304751
Jeff Johnson295189b2012-06-20 16:38:30 -07004752 if (SIR_MAC_MAX_SSID_LENGTH < ssid_len)
4753 {
4754 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wrong SSID len", __func__);
4755 return -EINVAL;
4756 }
4757
4758 pRoamProfile = &pWextState->roamProfile;
4759
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304760 if (pRoamProfile)
Jeff Johnson295189b2012-06-20 16:38:30 -07004761 {
Jeff Johnsone7245742012-09-05 17:12:55 -07004762 int ret = 0;
4763 hdd_station_ctx_t *pHddStaCtx;
4764 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4765 hdd_connGetConnectedBssType(pHddStaCtx,&connectedBssType );
4766
4767 if((eMib_dot11DesiredBssType_independent == connectedBssType) ||
4768 (eConnectionState_Associated == pHddStaCtx->conn_info.connState) ||
4769 (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState))
Jeff Johnson295189b2012-06-20 16:38:30 -07004770 {
4771 /* Issue disconnect to CSR */
4772 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304773 if( eHAL_STATUS_SUCCESS ==
Jeff Johnson295189b2012-06-20 16:38:30 -07004774 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
4775 pAdapter->sessionId,
4776 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
4777 {
Jeff Johnsone7245742012-09-05 17:12:55 -07004778 ret = wait_for_completion_interruptible_timeout(
4779 &pAdapter->disconnect_comp_var,
4780 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
4781 if (0 == ret)
4782 {
4783 VOS_ASSERT(0);
4784 }
4785 }
4786 }
4787 else if(eConnectionState_Disconnecting == pHddStaCtx->conn_info.connState)
4788 {
4789 ret = wait_for_completion_interruptible_timeout(
4790 &pAdapter->disconnect_comp_var,
4791 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
4792 if (0 == ret)
4793 {
4794 VOS_ASSERT(0);
Jeff Johnson295189b2012-06-20 16:38:30 -07004795 }
4796 }
4797
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304798 if (HDD_WMM_USER_MODE_NO_QOS ==
Jeff Johnson295189b2012-06-20 16:38:30 -07004799 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->WmmMode)
4800 {
4801 /*QoS not enabled in cfg file*/
4802 pRoamProfile->uapsd_mask = 0;
4803 }
4804 else
4805 {
4806 /*QoS enabled, update uapsd mask from cfg file*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304807 pRoamProfile->uapsd_mask =
Jeff Johnson295189b2012-06-20 16:38:30 -07004808 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask;
4809 }
4810
4811 pRoamProfile->SSIDs.numOfSSIDs = 1;
4812 pRoamProfile->SSIDs.SSIDList->SSID.length = ssid_len;
4813 vos_mem_zero(pRoamProfile->SSIDs.SSIDList->SSID.ssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304814 sizeof(pRoamProfile->SSIDs.SSIDList->SSID.ssId));
Jeff Johnson295189b2012-06-20 16:38:30 -07004815 vos_mem_copy((void *)(pRoamProfile->SSIDs.SSIDList->SSID.ssId),
4816 ssid, ssid_len);
4817
4818 if (bssid)
4819 {
4820 pRoamProfile->BSSIDs.numOfBSSIDs = 1;
4821 vos_mem_copy((void *)(pRoamProfile->BSSIDs.bssid), bssid,
4822 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304823 /* Save BSSID in seperate variable as well, as RoamProfile
4824 BSSID is getting zeroed out in the association process. And in
Jeff Johnson295189b2012-06-20 16:38:30 -07004825 case of join failure we should send valid BSSID to supplicant
4826 */
4827 vos_mem_copy((void *)(pWextState->req_bssId), bssid,
4828 WNI_CFG_BSSID_LEN);
4829 }
4830
4831 if ((IW_AUTH_WPA_VERSION_WPA == pWextState->wpaVersion) ||
4832 (IW_AUTH_WPA_VERSION_WPA2 == pWextState->wpaVersion))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304833 {
Jeff Johnson295189b2012-06-20 16:38:30 -07004834 /*set gen ie*/
4835 hdd_SetGENIEToCsr(pAdapter, &RSNAuthType);
4836 /*set auth*/
4837 hdd_set_csr_auth_type(pAdapter, RSNAuthType);
4838 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004839#ifdef FEATURE_WLAN_WAPI
4840 if (pAdapter->wapi_info.nWapiMode)
4841 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004842 hddLog(LOG1, "%s: Setting WAPI AUTH Type and Encryption Mode values", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004843 switch (pAdapter->wapi_info.wapiAuthMode)
4844 {
4845 case WAPI_AUTH_MODE_PSK:
4846 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004847 hddLog(LOG1, "%s: WAPI AUTH TYPE: PSK: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07004848 pAdapter->wapi_info.wapiAuthMode);
4849 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_PSK;
4850 break;
4851 }
4852 case WAPI_AUTH_MODE_CERT:
4853 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004854 hddLog(LOG1, "%s: WAPI AUTH TYPE: CERT: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07004855 pAdapter->wapi_info.wapiAuthMode);
4856 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE;
4857 break;
4858 }
4859 } // End of switch
4860 if ( pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_PSK ||
4861 pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_CERT)
4862 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07004863 hddLog(LOG1, "%s: WAPI PAIRWISE/GROUP ENCRYPTION: WPI", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004864 pRoamProfile->AuthType.numEntries = 1;
4865 pRoamProfile->EncryptionType.numEntries = 1;
4866 pRoamProfile->EncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
4867 pRoamProfile->mcEncryptionType.numEntries = 1;
4868 pRoamProfile->mcEncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
4869 }
4870 }
4871#endif /* FEATURE_WLAN_WAPI */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05304872#ifdef WLAN_FEATURE_GTK_OFFLOAD
4873 /* Initializing gtkOffloadRequestParams */
4874 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
4875 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
4876 {
4877 pHddStaCtx->gtkOffloadRequestParams.requested = FALSE;
4878 memset(&pHddStaCtx->gtkOffloadRequestParams.gtkOffloadReqParams,
4879 0, sizeof (tSirGtkOffloadParams));
4880 }
4881#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07004882 pRoamProfile->csrPersona = pAdapter->device_mode;
4883
Jeff Johnson32d95a32012-09-10 13:15:23 -07004884 if( operatingChannel )
4885 {
4886 pRoamProfile->ChannelInfo.ChannelList = &operatingChannel;
4887 pRoamProfile->ChannelInfo.numOfChannels = 1;
4888 }
Chet Lanctot186b5732013-03-18 10:26:30 -07004889 else
4890 {
4891 pRoamProfile->ChannelInfo.ChannelList = NULL;
4892 pRoamProfile->ChannelInfo.numOfChannels = 0;
4893 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07004894 if ( (WLAN_HDD_IBSS == pAdapter->device_mode) && operatingChannel)
4895 {
4896 hdd_select_cbmode(pAdapter,operatingChannel);
4897 }
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08004898 /* change conn_state to connecting before sme_RoamConnect(), because sme_RoamConnect()
4899 * has a direct path to call hdd_smeRoamCallback(), which will change the conn_state
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304900 * If direct path, conn_state will be accordingly changed to NotConnected or Associated
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08004901 * by either hdd_AssociationCompletionHandler() or hdd_DisConnectHandler() in sme_RoamCallback()
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -08004902 * if sme_RomConnect is to be queued, Connecting state will remain until it is completed.
4903 */
4904 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode)
4905 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
4906 eConnectionState_Connecting);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304907
4908 status = sme_RoamConnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07004909 pAdapter->sessionId, pRoamProfile, &roamId);
4910
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08004911 if( (eHAL_STATUS_SUCCESS != status) &&
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +05304912 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) )
4913
4914 {
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08004915 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: sme_RoamConnect (session %d) failed with "
4916 "status %d. -> NotConnected", __func__, pAdapter->sessionId, status);
4917 /* change back to NotAssociated */
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +05304918 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08004919 eConnectionState_NotConnected);
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +05304920 }
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -08004921
4922 pRoamProfile->ChannelInfo.ChannelList = NULL;
4923 pRoamProfile->ChannelInfo.numOfChannels = 0;
4924
Jeff Johnson295189b2012-06-20 16:38:30 -07004925 }
4926 else
4927 {
4928 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid Roam profile", __func__);
4929 return -EINVAL;
4930 }
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08004931 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07004932 return status;
4933}
4934
4935/*
4936 * FUNCTION: wlan_hdd_set_cfg80211_auth_type
4937 * This function is used to set the authentication type (OPEN/SHARED).
4938 *
4939 */
4940static int wlan_hdd_cfg80211_set_auth_type(hdd_adapter_t *pAdapter,
4941 enum nl80211_auth_type auth_type)
4942{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304943 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07004944 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4945
4946 ENTER();
4947
4948 /*set authentication type*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304949 switch (auth_type)
Jeff Johnson295189b2012-06-20 16:38:30 -07004950 {
Jeff Johnson295189b2012-06-20 16:38:30 -07004951 case NL80211_AUTHTYPE_AUTOMATIC:
Gopichand Nakkala29149562013-05-10 21:43:41 +05304952 hddLog(VOS_TRACE_LEVEL_INFO,
4953 "%s: set authentication type to AUTOSWITCH", __func__);
4954 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_AUTOSWITCH;
4955 break;
4956
4957 case NL80211_AUTHTYPE_OPEN_SYSTEM:
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07004958#ifdef WLAN_FEATURE_VOWIFI_11R
4959 case NL80211_AUTHTYPE_FT:
4960#endif /* WLAN_FEATURE_VOWIFI_11R */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304961 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -07004962 "%s: set authentication type to OPEN", __func__);
4963 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
4964 break;
4965
4966 case NL80211_AUTHTYPE_SHARED_KEY:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304967 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -07004968 "%s: set authentication type to SHARED", __func__);
4969 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_SHARED_KEY;
4970 break;
4971#ifdef FEATURE_WLAN_CCX
4972 case NL80211_AUTHTYPE_NETWORK_EAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304973 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -07004974 "%s: set authentication type to CCKM WPA", __func__);
4975 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_CCKM_WPA;//eCSR_AUTH_TYPE_CCKM_RSN needs to be handled as well if required.
4976 break;
4977#endif
4978
4979
4980 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304981 hddLog(VOS_TRACE_LEVEL_ERROR,
4982 "%s: Unsupported authentication type %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07004983 auth_type);
4984 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_UNKNOWN;
4985 return -EINVAL;
4986 }
4987
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304988 pWextState->roamProfile.AuthType.authType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -07004989 pHddStaCtx->conn_info.authType;
4990 return 0;
4991}
4992
4993/*
4994 * FUNCTION: wlan_hdd_set_akm_suite
4995 * This function is used to set the key mgmt type(PSK/8021x).
4996 *
4997 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304998static int wlan_hdd_set_akm_suite( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07004999 u32 key_mgmt
5000 )
5001{
5002 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
5003 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305004
Jeff Johnson295189b2012-06-20 16:38:30 -07005005 /*set key mgmt type*/
5006 switch(key_mgmt)
5007 {
5008 case WLAN_AKM_SUITE_PSK:
Gopichand Nakkala356fb102013-03-06 12:34:04 +05305009#ifdef WLAN_FEATURE_VOWIFI_11R
5010 case WLAN_AKM_SUITE_FT_PSK:
5011#endif
5012 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to PSK",
Jeff Johnson295189b2012-06-20 16:38:30 -07005013 __func__);
5014 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_PSK;
5015 break;
5016
5017 case WLAN_AKM_SUITE_8021X:
Gopichand Nakkala356fb102013-03-06 12:34:04 +05305018#ifdef WLAN_FEATURE_VOWIFI_11R
5019 case WLAN_AKM_SUITE_FT_8021X:
5020#endif
5021 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to 8021x",
Jeff Johnson295189b2012-06-20 16:38:30 -07005022 __func__);
5023 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
5024 break;
5025#ifdef FEATURE_WLAN_CCX
5026#define WLAN_AKM_SUITE_CCKM 0x00409600 /* Should be in ieee802_11_defs.h */
5027#define IW_AUTH_KEY_MGMT_CCKM 8 /* Should be in linux/wireless.h */
5028 case WLAN_AKM_SUITE_CCKM:
5029 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to CCKM",
5030 __func__);
5031 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_CCKM;
5032 break;
5033#endif
5034
5035 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305036 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported key mgmt type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07005037 __func__, key_mgmt);
5038 return -EINVAL;
5039
5040 }
5041 return 0;
5042}
5043
5044/*
5045 * FUNCTION: wlan_hdd_cfg80211_set_cipher
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305046 * This function is used to set the encryption type
Jeff Johnson295189b2012-06-20 16:38:30 -07005047 * (NONE/WEP40/WEP104/TKIP/CCMP).
5048 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305049static int wlan_hdd_cfg80211_set_cipher( hdd_adapter_t *pAdapter,
5050 u32 cipher,
Jeff Johnson295189b2012-06-20 16:38:30 -07005051 bool ucast
5052 )
5053{
5054 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305055 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07005056 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
5057
5058 ENTER();
5059
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305060 if (!cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -07005061 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305062 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: received cipher %d - considering none",
Jeff Johnson295189b2012-06-20 16:38:30 -07005063 __func__, cipher);
5064 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
5065 }
5066 else
5067 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305068
Jeff Johnson295189b2012-06-20 16:38:30 -07005069 /*set encryption method*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305070 switch (cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -07005071 {
5072 case IW_AUTH_CIPHER_NONE:
5073 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
5074 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305075
Jeff Johnson295189b2012-06-20 16:38:30 -07005076 case WLAN_CIPHER_SUITE_WEP40:
Gopichand Nakkala29149562013-05-10 21:43:41 +05305077 encryptionType = eCSR_ENCRYPT_TYPE_WEP40;
Jeff Johnson295189b2012-06-20 16:38:30 -07005078 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305079
Jeff Johnson295189b2012-06-20 16:38:30 -07005080 case WLAN_CIPHER_SUITE_WEP104:
Gopichand Nakkala29149562013-05-10 21:43:41 +05305081 encryptionType = eCSR_ENCRYPT_TYPE_WEP104;
Jeff Johnson295189b2012-06-20 16:38:30 -07005082 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305083
Jeff Johnson295189b2012-06-20 16:38:30 -07005084 case WLAN_CIPHER_SUITE_TKIP:
5085 encryptionType = eCSR_ENCRYPT_TYPE_TKIP;
5086 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305087
Jeff Johnson295189b2012-06-20 16:38:30 -07005088 case WLAN_CIPHER_SUITE_CCMP:
5089 encryptionType = eCSR_ENCRYPT_TYPE_AES;
5090 break;
5091#ifdef FEATURE_WLAN_WAPI
5092 case WLAN_CIPHER_SUITE_SMS4:
5093 encryptionType = eCSR_ENCRYPT_TYPE_WPI;
5094 break;
5095#endif
5096
5097#ifdef FEATURE_WLAN_CCX
5098 case WLAN_CIPHER_SUITE_KRK:
5099 encryptionType = eCSR_ENCRYPT_TYPE_KRK;
5100 break;
5101#endif
5102 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305103 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported cipher type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07005104 __func__, cipher);
5105 return -EOPNOTSUPP;
5106 }
5107 }
5108
5109 if (ucast)
5110 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305111 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting unicast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07005112 __func__, encryptionType);
5113 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
5114 pWextState->roamProfile.EncryptionType.numEntries = 1;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305115 pWextState->roamProfile.EncryptionType.encryptionType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -07005116 encryptionType;
5117 }
5118 else
5119 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305120 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting mcast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07005121 __func__, encryptionType);
5122 pHddStaCtx->conn_info.mcEncryptionType = encryptionType;
5123 pWextState->roamProfile.mcEncryptionType.numEntries = 1;
5124 pWextState->roamProfile.mcEncryptionType.encryptionType[0] = encryptionType;
5125 }
5126
5127 return 0;
5128}
5129
5130
5131/*
5132 * FUNCTION: wlan_hdd_cfg80211_set_ie
5133 * This function is used to parse WPA/RSN IE's.
5134 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305135int wlan_hdd_cfg80211_set_ie( hdd_adapter_t *pAdapter,
5136 u8 *ie,
Jeff Johnson295189b2012-06-20 16:38:30 -07005137 size_t ie_len
5138 )
5139{
5140 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
5141 u8 *genie = ie;
5142 v_U16_t remLen = ie_len;
5143#ifdef FEATURE_WLAN_WAPI
5144 v_U32_t akmsuite[MAX_NUM_AKM_SUITES];
5145 u16 *tmp;
5146 v_U16_t akmsuiteCount;
5147 int *akmlist;
5148#endif
5149 ENTER();
5150
5151 /* clear previous assocAddIE */
5152 pWextState->assocAddIE.length = 0;
5153 pWextState->roamProfile.bWPSAssociation = VOS_FALSE;
5154
5155 while (remLen >= 2)
5156 {
5157 v_U16_t eLen = 0;
5158 v_U8_t elementId;
5159 elementId = *genie++;
5160 eLen = *genie++;
5161 remLen -= 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305162
5163 hddLog(VOS_TRACE_LEVEL_INFO, "%s: IE[0x%X], LEN[%d]\n",
Jeff Johnson295189b2012-06-20 16:38:30 -07005164 __func__, elementId, eLen);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305165
5166 switch ( elementId )
Jeff Johnson295189b2012-06-20 16:38:30 -07005167 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305168 case DOT11F_EID_WPA:
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005169 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 -07005170 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305171 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07005172 "%s: Invalid WPA IE", __func__);
5173 return -EINVAL;
5174 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305175 else if (0 == memcmp(&genie[0], "\x00\x50\xf2\x04", 4))
Jeff Johnson295189b2012-06-20 16:38:30 -07005176 {
5177 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305178 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPS IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -07005179 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305180
Jeff Johnson295189b2012-06-20 16:38:30 -07005181 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
5182 {
Jeff Johnson902c9832012-12-10 14:28:09 -08005183 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE. "
5184 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -07005185 VOS_ASSERT(0);
5186 return -ENOMEM;
5187 }
5188 // WSC IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
5189 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
5190 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305191
Jeff Johnson295189b2012-06-20 16:38:30 -07005192 pWextState->roamProfile.bWPSAssociation = VOS_TRUE;
5193 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
5194 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
5195 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305196 else if (0 == memcmp(&genie[0], "\x00\x50\xf2", 3))
5197 {
Jeff Johnson295189b2012-06-20 16:38:30 -07005198 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPA IE (len %d)",__func__, eLen + 2);
5199 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
5200 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2) /*ie_len*/);
5201 pWextState->roamProfile.pWPAReqIE = pWextState->WPARSNIE;
5202 pWextState->roamProfile.nWPAReqIELength = eLen + 2;//ie_len;
5203 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305204 else if ( (0 == memcmp(&genie[0], P2P_OUI_TYPE,
5205 P2P_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07005206 /*Consider P2P IE, only for P2P Client */
5207 && (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
5208 {
5209 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305210 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set P2P IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -07005211 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305212
Jeff Johnson295189b2012-06-20 16:38:30 -07005213 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
5214 {
Jeff Johnson902c9832012-12-10 14:28:09 -08005215 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
5216 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -07005217 VOS_ASSERT(0);
5218 return -ENOMEM;
5219 }
5220 // P2P IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
5221 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
5222 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305223
Jeff Johnson295189b2012-06-20 16:38:30 -07005224 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
5225 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
5226 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005227#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305228 else if ( (0 == memcmp(&genie[0], WFD_OUI_TYPE,
5229 WFD_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07005230 /*Consider WFD IE, only for P2P Client */
5231 && (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
5232 {
5233 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305234 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WFD IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -07005235 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305236
Jeff Johnson295189b2012-06-20 16:38:30 -07005237 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
5238 {
Jeff Johnson902c9832012-12-10 14:28:09 -08005239 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
5240 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -07005241 VOS_ASSERT(0);
5242 return -ENOMEM;
5243 }
5244 // WFD IE is saved to Additional IE ; it should be accumulated to handle
5245 // WPS IE + P2P IE + WFD IE
5246 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
5247 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305248
Jeff Johnson295189b2012-06-20 16:38:30 -07005249 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
5250 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
5251 }
5252#endif
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005253 /* Appending HS 2.0 Indication Element in Assiciation Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305254 else if ( (0 == memcmp(&genie[0], HS20_OUI_TYPE,
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07005255 HS20_OUI_TYPE_SIZE)) )
5256 {
5257 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305258 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set HS20 IE(len %d)",
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07005259 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005260
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07005261 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
5262 {
Jeff Johnson902c9832012-12-10 14:28:09 -08005263 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
5264 "Need bigger buffer space");
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07005265 VOS_ASSERT(0);
5266 return -ENOMEM;
5267 }
5268 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
5269 pWextState->assocAddIE.length += eLen + 2;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005270
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07005271 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
5272 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
5273 }
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005274
Jeff Johnson295189b2012-06-20 16:38:30 -07005275 break;
5276 case DOT11F_EID_RSN:
5277 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set RSN IE(len %d)",__func__, eLen + 2);
5278 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
5279 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2)/*ie_len*/);
5280 pWextState->roamProfile.pRSNReqIE = pWextState->WPARSNIE;
5281 pWextState->roamProfile.nRSNReqIELength = eLen + 2; //ie_len;
5282 break;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005283 /* Appending Extended Capabilities with Interworking bit set in Assoc Req */
5284 case DOT11F_EID_EXTCAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305285 {
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005286 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305287 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set Extended CAPS IE(len %d)",
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005288 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305289
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005290 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
5291 {
Jeff Johnson902c9832012-12-10 14:28:09 -08005292 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
5293 "Need bigger buffer space");
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005294 VOS_ASSERT(0);
5295 return -ENOMEM;
5296 }
5297 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
5298 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305299
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005300 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
5301 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
5302 break;
5303 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005304#ifdef FEATURE_WLAN_WAPI
5305 case WLAN_EID_WAPI:
5306 pAdapter->wapi_info.nWapiMode = 1; //Setting WAPI Mode to ON=1
5307 hddLog(VOS_TRACE_LEVEL_INFO,"WAPI MODE IS %lu \n",
5308 pAdapter->wapi_info.nWapiMode);
5309 tmp = (u16 *)ie;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305310 tmp = tmp + 2; // Skip element Id and Len, Version
Jeff Johnson295189b2012-06-20 16:38:30 -07005311 akmsuiteCount = WPA_GET_LE16(tmp);
5312 tmp = tmp + 1;
5313 akmlist = (int *)(tmp);
5314 if(akmsuiteCount <= MAX_NUM_AKM_SUITES)
5315 {
5316 memcpy(akmsuite, akmlist, (4*akmsuiteCount));
5317 }
5318 else
5319 {
5320 hddLog(VOS_TRACE_LEVEL_FATAL, "Invalid akmSuite count\n");
5321 VOS_ASSERT(0);
5322 return -EINVAL;
5323 }
5324
5325 if (WAPI_PSK_AKM_SUITE == akmsuite[0])
5326 {
5327 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO PSK",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005328 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005329 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_PSK;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305330 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005331 if (WAPI_CERT_AKM_SUITE == akmsuite[0])
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305332 {
Jeff Johnson295189b2012-06-20 16:38:30 -07005333 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO CERTIFICATE",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005334 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005335 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_CERT;
5336 }
5337 break;
5338#endif
5339 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305340 hddLog (VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07005341 "%s Set UNKNOWN IE %X", __func__, elementId);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005342 /* when Unknown IE is received we should break and continue
5343 * to the next IE in the buffer instead we were returning
5344 * so changing this to break */
5345 break;
Jeff Johnson295189b2012-06-20 16:38:30 -07005346 }
5347 genie += eLen;
5348 remLen -= eLen;
5349 }
5350 EXIT();
5351 return 0;
5352}
5353
5354/*
Gopichand Nakkala18f0c262013-05-07 23:25:08 +05305355 * FUNCTION: hdd_isWPAIEPresent
5356 * Parse the received IE to find the WPA IE
5357 *
5358 */
5359static bool hdd_isWPAIEPresent(u8 *ie, u8 ie_len)
5360{
5361 v_U8_t eLen = 0;
5362 v_U16_t remLen = ie_len;
5363 v_U8_t elementId = 0;
5364
5365 while (remLen >= 2)
5366 {
5367 elementId = *ie++;
5368 eLen = *ie++;
5369 remLen -= 2;
5370 if (eLen > remLen)
5371 {
5372 hddLog(VOS_TRACE_LEVEL_ERROR,
5373 "%s: IE length is wrong %d", __func__, eLen);
5374 return FALSE;
5375 }
5376 if ((elementId == DOT11F_EID_WPA) && (remLen > 5))
5377 {
5378 /* OUI - 0x00 0X50 0XF2
5379 WPA Information Element - 0x01
5380 WPA version - 0x01*/
5381 if (0 == memcmp(&ie[0], "\x00\x50\xf2\x01\x01", 5))
5382 return TRUE;
5383 }
5384 ie += eLen;
5385 remLen -= eLen;
5386 }
5387 return FALSE;
5388}
5389
5390/*
Jeff Johnson295189b2012-06-20 16:38:30 -07005391 * FUNCTION: wlan_hdd_cfg80211_set_privacy
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305392 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -07005393 * parameters during connect operation.
5394 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305395int wlan_hdd_cfg80211_set_privacy( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07005396 struct cfg80211_connect_params *req
5397 )
5398{
5399 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305400 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07005401 ENTER();
5402
5403 /*set wpa version*/
5404 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
5405
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305406 if (req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -07005407 {
5408 if ( (NL80211_WPA_VERSION_1 == req->crypto.wpa_versions)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305409 && ( (req->ie_len)
Gopichand Nakkala18f0c262013-05-07 23:25:08 +05305410 && (hdd_isWPAIEPresent(req->ie, req->ie_len) ) ) )
Jeff Johnson295189b2012-06-20 16:38:30 -07005411 // Make sure that it is including a WPA IE.
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305412 /* Currently NL is putting WPA version 1 even for open,
Jeff Johnson295189b2012-06-20 16:38:30 -07005413 * since p2p ie is also put in same buffer.
5414 * */
5415 {
5416 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
5417 }
5418 else if (NL80211_WPA_VERSION_2 == req->crypto.wpa_versions)
5419 {
5420 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
5421 }
5422 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305423
5424 hddLog(VOS_TRACE_LEVEL_INFO, "%s: set wpa version to %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07005425 pWextState->wpaVersion);
5426
5427 /*set authentication type*/
5428 status = wlan_hdd_cfg80211_set_auth_type(pAdapter, req->auth_type);
5429
5430 if (0 > status)
5431 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305432 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07005433 "%s: failed to set authentication type ", __func__);
5434 return status;
5435 }
5436
5437 /*set key mgmt type*/
5438 if (req->crypto.n_akm_suites)
5439 {
5440 status = wlan_hdd_set_akm_suite(pAdapter, req->crypto.akm_suites[0]);
5441 if (0 > status)
5442 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305443 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set akm suite",
Jeff Johnson295189b2012-06-20 16:38:30 -07005444 __func__);
5445 return status;
5446 }
5447 }
5448
5449 /*set pairwise cipher type*/
5450 if (req->crypto.n_ciphers_pairwise)
5451 {
5452 status = wlan_hdd_cfg80211_set_cipher(pAdapter,
5453 req->crypto.ciphers_pairwise[0], true);
5454 if (0 > status)
5455 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305456 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07005457 "%s: failed to set unicast cipher type", __func__);
5458 return status;
5459 }
5460 }
5461 else
5462 {
5463 /*Reset previous cipher suite to none*/
5464 status = wlan_hdd_cfg80211_set_cipher(pAdapter, 0, true);
5465 if (0 > status)
5466 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305467 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07005468 "%s: failed to set unicast cipher type", __func__);
5469 return status;
5470 }
5471 }
5472
5473 /*set group cipher type*/
5474 status = wlan_hdd_cfg80211_set_cipher(pAdapter, req->crypto.cipher_group,
5475 false);
5476
5477 if (0 > status)
5478 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305479 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set mcast cipher type",
Jeff Johnson295189b2012-06-20 16:38:30 -07005480 __func__);
5481 return status;
5482 }
5483
Chet Lanctot186b5732013-03-18 10:26:30 -07005484#ifdef WLAN_FEATURE_11W
5485 pWextState->roamProfile.MFPEnabled = (req->mfp == NL80211_MFP_REQUIRED);
5486#endif
5487
Jeff Johnson295189b2012-06-20 16:38:30 -07005488 /*parse WPA/RSN IE, and set the correspoing fileds in Roam profile*/
5489 if (req->ie_len)
5490 {
5491 status = wlan_hdd_cfg80211_set_ie(pAdapter, req->ie, req->ie_len);
5492 if ( 0 > status)
5493 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305494 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse the WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -07005495 __func__);
5496 return status;
5497 }
5498 }
5499
5500 /*incase of WEP set default key information*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305501 if (req->key && req->key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -07005502 {
5503 if ( (WLAN_CIPHER_SUITE_WEP40 == req->crypto.ciphers_pairwise[0])
5504 || (WLAN_CIPHER_SUITE_WEP104 == req->crypto.ciphers_pairwise[0])
5505 )
5506 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305507 if ( IW_AUTH_KEY_MGMT_802_1X
Jeff Johnson295189b2012-06-20 16:38:30 -07005508 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X ))
5509 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305510 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Dynamic WEP not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -07005511 __func__);
5512 return -EOPNOTSUPP;
5513 }
5514 else
5515 {
5516 u8 key_len = req->key_len;
5517 u8 key_idx = req->key_idx;
5518
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305519 if ((eCSR_SECURITY_WEP_KEYSIZE_MAX_BYTES >= key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -07005520 && (CSR_MAX_NUM_KEY > key_idx)
5521 )
5522 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305523 hddLog(VOS_TRACE_LEVEL_INFO,
5524 "%s: setting default wep key, key_idx = %hu key_len %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07005525 __func__, key_idx, key_len);
5526 vos_mem_copy(
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305527 &pWextState->roamProfile.Keys.KeyMaterial[key_idx][0],
Jeff Johnson295189b2012-06-20 16:38:30 -07005528 req->key, key_len);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305529 pWextState->roamProfile.Keys.KeyLength[key_idx] =
Jeff Johnson295189b2012-06-20 16:38:30 -07005530 (u8)key_len;
5531 pWextState->roamProfile.Keys.defaultIndex = (u8)key_idx;
5532 }
5533 }
5534 }
5535 }
5536
5537 return status;
5538}
5539
5540/*
5541 * FUNCTION: wlan_hdd_cfg80211_set_privacy
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305542 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -07005543 * parameters during connect operation.
5544 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305545static int wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07005546 struct net_device *ndev,
5547 struct cfg80211_connect_params *req
5548 )
5549{
5550 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305551 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -07005552 VOS_STATUS exitbmpsStatus = VOS_STATUS_E_INVAL;
5553 hdd_context_t *pHddCtx = NULL;
5554
5555 ENTER();
5556
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305557 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -07005558 "%s: device_mode = %d\n",__func__,pAdapter->device_mode);
5559
5560 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
5561 {
5562 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5563 "%s:LOGP in Progress. Ignore!!!", __func__);
5564 return -EAGAIN;
5565 }
5566
5567#ifdef WLAN_BTAMP_FEATURE
5568 //Infra connect not supported when AMP traffic is on.
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305569 if( VOS_TRUE == WLANBAP_AmpSessionOn() )
Jeff Johnson295189b2012-06-20 16:38:30 -07005570 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305571 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07005572 "%s: No connection when AMP is on", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08005573 return -ECONNREFUSED;
Jeff Johnson295189b2012-06-20 16:38:30 -07005574 }
5575#endif
5576 /*initialise security parameters*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305577 status = wlan_hdd_cfg80211_set_privacy(pAdapter, req);
Jeff Johnson295189b2012-06-20 16:38:30 -07005578
5579 if ( 0 > status)
5580 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305581 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security params",
Jeff Johnson295189b2012-06-20 16:38:30 -07005582 __func__);
5583 return status;
5584 }
5585
5586 //If Device Mode is Station Concurrent Sessions Exit BMps
Jeff Johnsona8a1a482012-12-12 16:49:33 -08005587 //P2P Mode will be taken care in Open/close adapter
Jeff Johnson295189b2012-06-20 16:38:30 -07005588 if((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
5589 (vos_concurrent_sessions_running()))
5590 {
5591 v_CONTEXT_t pVosContext = vos_get_global_context( VOS_MODULE_ID_HDD, NULL );
5592
5593 if (NULL != pVosContext)
5594 {
5595 pHddCtx = vos_get_context( VOS_MODULE_ID_HDD, pVosContext);
5596 if(NULL != pHddCtx)
5597 {
5598 exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
5599 }
5600 }
5601 }
5602
Mohit Khanna765234a2012-09-11 15:08:35 -07005603 if ( req->channel )
5604 {
5605 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
5606 req->ssid_len, req->bssid,
5607 req->channel->hw_value);
5608 }
5609 else
5610 {
5611 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
5612 req->ssid_len, req->bssid,
5613 0);
5614 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005615
5616 if (0 > status)
5617 {
5618 //ReEnable BMPS if disabled
5619 if((VOS_STATUS_SUCCESS == exitbmpsStatus) &&
5620 (NULL != pHddCtx))
5621 {
5622 //ReEnable Bmps and Imps back
5623 hdd_enable_bmps_imps(pHddCtx);
5624 }
5625
5626 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: connect failed", __func__);
5627 return status;
5628 }
5629 (WLAN_HDD_GET_CTX(pAdapter))->isAmpAllowed = VOS_FALSE;
5630 EXIT();
5631 return status;
5632}
5633
5634
5635/*
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05305636 * FUNCTION: wlan_hdd_disconnect
5637 * This function is used to issue a disconnect request to SME
5638 */
5639int wlan_hdd_disconnect( hdd_adapter_t *pAdapter, u16 reason )
5640{
5641 int status = 0;
5642 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
5643 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
5644 (WLAN_HDD_GET_CTX(pAdapter))->isAmpAllowed = VOS_TRUE;
5645 INIT_COMPLETION(pAdapter->disconnect_comp_var);
5646 /*issue disconnect*/
5647 status = sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
5648 pAdapter->sessionId, reason);
5649
5650 if ( 0 != status )
5651 {
5652 hddLog(VOS_TRACE_LEVEL_ERROR,
5653 "%s csrRoamDisconnect failure, returned %d \n",
5654 __func__, (int)status );
5655 return -EINVAL;
5656 }
5657 wait_for_completion_interruptible_timeout(
5658 &pAdapter->disconnect_comp_var,
5659 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
5660 /*stop tx queues*/
5661 netif_tx_disable(pAdapter->dev);
5662 netif_carrier_off(pAdapter->dev);
5663 return status;
5664}
5665
5666
5667/*
Jeff Johnson295189b2012-06-20 16:38:30 -07005668 * FUNCTION: wlan_hdd_cfg80211_disconnect
5669 * This function is used to issue a disconnect request to SME
5670 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305671static int wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07005672 struct net_device *dev,
5673 u16 reason
5674 )
5675{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305676 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
5677 tCsrRoamProfile *pRoamProfile =
Jeff Johnson295189b2012-06-20 16:38:30 -07005678 &(WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter))->roamProfile;
5679 int status = 0;
5680 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkala4327a152013-03-04 23:22:42 -08005681 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaaa353782013-05-17 20:36:22 +05305682#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08005683 tANI_U8 staIdx;
5684#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305685
Jeff Johnson295189b2012-06-20 16:38:30 -07005686 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305687
5688 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",
Jeff Johnson295189b2012-06-20 16:38:30 -07005689 __func__,pAdapter->device_mode);
5690
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305691 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Disconnect called with reason code %d",
5692 __func__, reason);
Jeff Johnson295189b2012-06-20 16:38:30 -07005693
5694 if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress)
5695 {
5696 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5697 "%s:LOGP in Progress. Ignore!!!",__func__);
5698 return -EAGAIN;
5699 }
5700 if (NULL != pRoamProfile)
5701 {
5702 /*issue disconnect request to SME, if station is in connected state*/
5703 if (pHddStaCtx->conn_info.connState == eConnectionState_Associated)
5704 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305705 eCsrRoamDisconnectReason reasonCode =
Jeff Johnson295189b2012-06-20 16:38:30 -07005706 eCSR_DISCONNECT_REASON_UNSPECIFIED;
Gopichand Nakkalaaa353782013-05-17 20:36:22 +05305707 hdd_scaninfo_t *pScanInfo;
Jeff Johnson295189b2012-06-20 16:38:30 -07005708 switch(reason)
5709 {
5710 case WLAN_REASON_MIC_FAILURE:
5711 reasonCode = eCSR_DISCONNECT_REASON_MIC_ERROR;
5712 break;
5713
5714 case WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY:
5715 case WLAN_REASON_DISASSOC_AP_BUSY:
5716 case WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA:
5717 reasonCode = eCSR_DISCONNECT_REASON_DISASSOC;
5718 break;
5719
5720 case WLAN_REASON_PREV_AUTH_NOT_VALID:
5721 case WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA:
5722 reasonCode = eCSR_DISCONNECT_REASON_DEAUTH;
5723 break;
5724
5725 case WLAN_REASON_DEAUTH_LEAVING:
5726 default:
5727 reasonCode = eCSR_DISCONNECT_REASON_UNSPECIFIED;
5728 break;
5729 }
Gopichand Nakkalaaa353782013-05-17 20:36:22 +05305730 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
5731 pScanInfo = &pHddCtx->scan_info;
5732 if (pScanInfo->mScanPending)
5733 {
5734 hddLog(VOS_TRACE_LEVEL_INFO, "Disconnect is in progress, "
5735 "Aborting Scan");
5736 hdd_abort_mac_scan(pHddCtx);
5737 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005738
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08005739#ifdef FEATURE_WLAN_TDLS
5740 /* First clean up the tdls peers if any */
Gopichand Nakkala4327a152013-03-04 23:22:42 -08005741 for (staIdx = 0 ; staIdx < HDD_MAX_NUM_TDLS_STA; staIdx++)
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08005742 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -08005743 if ((pHddCtx->tdlsConnInfo[staIdx].sessionId == pAdapter->sessionId) &&
5744 (pHddCtx->tdlsConnInfo[staIdx].staId))
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08005745 {
Hoonki Lee11f7dda2013-02-14 16:55:44 -08005746 uint8 *mac;
Gopichand Nakkala4327a152013-03-04 23:22:42 -08005747 mac = pHddCtx->tdlsConnInfo[staIdx].peerMac.bytes;
Hoonki Lee11f7dda2013-02-14 16:55:44 -08005748 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07005749 "%s: call sme_DeleteTdlsPeerSta staId %d sessionId %d " MAC_ADDRESS_STR,
Gopichand Nakkala4327a152013-03-04 23:22:42 -08005750 __func__, pHddCtx->tdlsConnInfo[staIdx].staId, pAdapter->sessionId,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07005751 MAC_ADDR_ARRAY(mac));
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08005752 sme_DeleteTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala4327a152013-03-04 23:22:42 -08005753 pAdapter->sessionId,
5754 mac);
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08005755 }
5756 }
5757#endif
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05305758 status = wlan_hdd_disconnect(pAdapter, reasonCode);
5759 if ( 0 != status )
Jeff Johnson295189b2012-06-20 16:38:30 -07005760 {
5761 hddLog(VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05305762 "%s wlan_hdd_disconnect failure, returned %d \n",
Jeff Johnson295189b2012-06-20 16:38:30 -07005763 __func__, (int)status );
5764 return -EINVAL;
5765 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005766 }
5767 }
5768 else
5769 {
5770 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid roam profile", __func__);
5771 }
5772
5773 return status;
5774}
5775
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05305776
Jeff Johnson295189b2012-06-20 16:38:30 -07005777/*
5778 * FUNCTION: wlan_hdd_cfg80211_set_privacy_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305779 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -07005780 * settings in IBSS mode.
5781 */
5782static int wlan_hdd_cfg80211_set_privacy_ibss(
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305783 hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07005784 struct cfg80211_ibss_params *params
5785 )
5786{
5787 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305788 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07005789 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
5790 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305791
Jeff Johnson295189b2012-06-20 16:38:30 -07005792 ENTER();
5793
5794 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
5795
5796 if (params->ie_len && ( NULL != params->ie) )
5797 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305798 if (WLAN_EID_RSN == params->ie[0])
Jeff Johnson295189b2012-06-20 16:38:30 -07005799 {
5800 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
5801 encryptionType = eCSR_ENCRYPT_TYPE_AES;
5802 }
5803 else
5804 {
5805 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
5806 encryptionType = eCSR_ENCRYPT_TYPE_TKIP;
5807 }
5808 status = wlan_hdd_cfg80211_set_ie(pAdapter, params->ie, params->ie_len);
5809
5810 if (0 > status)
5811 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305812 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -07005813 __func__);
5814 return status;
5815 }
5816 }
5817
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305818 pWextState->roamProfile.AuthType.authType[0] =
5819 pHddStaCtx->conn_info.authType =
Jeff Johnson295189b2012-06-20 16:38:30 -07005820 eCSR_AUTH_TYPE_OPEN_SYSTEM;
5821
5822 if (params->privacy)
5823 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305824 /* Security enabled IBSS, At this time there is no information available
5825 * about the security paramters, so initialise the encryption type to
Jeff Johnson295189b2012-06-20 16:38:30 -07005826 * eCSR_ENCRYPT_TYPE_WEP40_STATICKEY.
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305827 * The correct security parameters will be updated later in
Jeff Johnson295189b2012-06-20 16:38:30 -07005828 * wlan_hdd_cfg80211_add_key */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305829 /* Hal expects encryption type to be set inorder
Jeff Johnson295189b2012-06-20 16:38:30 -07005830 *enable privacy bit in beacons */
5831
5832 encryptionType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
5833 }
5834
5835 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
5836 pWextState->roamProfile.EncryptionType.numEntries = 1;
5837 pWextState->roamProfile.EncryptionType.encryptionType[0] = encryptionType;
5838
5839 return status;
5840}
5841
5842/*
5843 * FUNCTION: wlan_hdd_cfg80211_join_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305844 * This function is used to create/join an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -07005845 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305846static int wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07005847 struct net_device *dev,
5848 struct cfg80211_ibss_params *params
5849 )
5850{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305851 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Jeff Johnson295189b2012-06-20 16:38:30 -07005852 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
5853 tCsrRoamProfile *pRoamProfile;
5854 int status;
5855 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
5856
5857 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305858
5859 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -07005860 "%s: device_mode = %d\n",__func__,pAdapter->device_mode);
5861
5862 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
5863 {
5864 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5865 "%s:LOGP in Progress. Ignore!!!", __func__);
5866 return -EAGAIN;
5867 }
5868
5869 if (NULL == pWextState)
5870 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305871 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption\n",
Jeff Johnson295189b2012-06-20 16:38:30 -07005872 __func__);
5873 return -EIO;
5874 }
5875
5876 pRoamProfile = &pWextState->roamProfile;
5877
5878 if ( eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType )
5879 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305880 hddLog (VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07005881 "%s Interface type is not set to IBSS \n", __func__);
5882 return -EINVAL;
5883 }
5884
5885 /* Set Channel */
5886 if (NULL != params->channel)
5887 {
5888 u8 channelNum;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07005889 v_U32_t numChans = WNI_CFG_VALID_CHANNEL_LIST_LEN;
5890 v_U8_t validChan[WNI_CFG_VALID_CHANNEL_LIST_LEN];
5891 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
5892 int indx;
Jeff Johnson295189b2012-06-20 16:38:30 -07005893
5894 /* Get channel number */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305895 channelNum =
Jeff Johnson295189b2012-06-20 16:38:30 -07005896 ieee80211_frequency_to_channel(params->channel->center_freq);
5897
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07005898
5899 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
5900 validChan, &numChans))
Jeff Johnson295189b2012-06-20 16:38:30 -07005901 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07005902 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid channel list",
5903 __func__);
5904 return -EOPNOTSUPP;
Jeff Johnson295189b2012-06-20 16:38:30 -07005905 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07005906
5907 for (indx = 0; indx < numChans; indx++)
Jeff Johnson295189b2012-06-20 16:38:30 -07005908 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07005909 if (channelNum == validChan[indx])
5910 {
5911 break;
5912 }
5913 }
5914 if (indx >= numChans)
5915 {
5916 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Not valid Channel %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07005917 __func__, channelNum);
5918 return -EINVAL;
5919 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07005920 /* Set the Operational Channel */
5921 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: set channel %d", __func__,
5922 channelNum);
5923 pRoamProfile->ChannelInfo.numOfChannels = 1;
5924 pHddStaCtx->conn_info.operationChannel = channelNum;
5925 pRoamProfile->ChannelInfo.ChannelList =
5926 &pHddStaCtx->conn_info.operationChannel;
Jeff Johnson295189b2012-06-20 16:38:30 -07005927 }
5928
5929 /* Initialize security parameters */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305930 status = wlan_hdd_cfg80211_set_privacy_ibss(pAdapter, params);
Jeff Johnson295189b2012-06-20 16:38:30 -07005931 if (status < 0)
5932 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305933 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security parameters",
Jeff Johnson295189b2012-06-20 16:38:30 -07005934 __func__);
5935 return status;
5936 }
5937
5938 /* Issue connect start */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305939 status = wlan_hdd_cfg80211_connect_start(pAdapter, params->ssid,
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07005940 params->ssid_len, params->bssid,
5941 pHddStaCtx->conn_info.operationChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -07005942
5943 if (0 > status)
5944 {
5945 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: connect failed", __func__);
5946 return status;
5947 }
5948
5949 return 0;
5950}
5951
5952/*
5953 * FUNCTION: wlan_hdd_cfg80211_leave_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305954 * This function is used to leave an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -07005955 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305956static int wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07005957 struct net_device *dev
5958 )
5959{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305960 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Jeff Johnson295189b2012-06-20 16:38:30 -07005961 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
5962 tCsrRoamProfile *pRoamProfile;
5963
5964 ENTER();
5965
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005966 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
5967 {
5968 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5969 "%s:LOGP in Progress. Ignore!!!", __func__);
5970 return -EAGAIN;
5971 }
5972
Jeff Johnson295189b2012-06-20 16:38:30 -07005973 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d\n",__func__,pAdapter->device_mode);
5974 if (NULL == pWextState)
5975 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305976 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption\n",
Jeff Johnson295189b2012-06-20 16:38:30 -07005977 __func__);
5978 return -EIO;
5979 }
5980
5981 pRoamProfile = &pWextState->roamProfile;
5982
5983 /* Issue disconnect only if interface type is set to IBSS */
5984 if (eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType)
5985 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305986 hddLog (VOS_TRACE_LEVEL_ERROR, "%s: BSS Type is not set to IBSS",
Jeff Johnson295189b2012-06-20 16:38:30 -07005987 __func__);
5988 return -EINVAL;
5989 }
5990
5991 /* Issue Disconnect request */
5992 INIT_COMPLETION(pAdapter->disconnect_comp_var);
5993 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
5994 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
5995
5996 return 0;
5997}
5998
5999/*
6000 * FUNCTION: wlan_hdd_cfg80211_set_wiphy_params
6001 * This function is used to set the phy parameters
6002 * (RTS Threshold/FRAG Threshold/Retry Count etc ...)
6003 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306004static int wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07006005 u32 changed)
6006{
6007 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
6008 tHalHandle hHal = pHddCtx->hHal;
6009
6010 ENTER();
6011
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006012 if ( pHddCtx->isLogpInProgress )
6013 {
6014 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6015 "%s:LOGP in Progress. Ignore!!!", __func__);
6016 return -EAGAIN;
6017 }
6018
Jeff Johnson295189b2012-06-20 16:38:30 -07006019 if (changed & WIPHY_PARAM_RTS_THRESHOLD)
6020 {
6021 u16 rts_threshold = (wiphy->rts_threshold == -1) ?
6022 WNI_CFG_RTS_THRESHOLD_STAMAX :
6023 wiphy->rts_threshold;
6024
6025 if ((WNI_CFG_RTS_THRESHOLD_STAMIN > rts_threshold) ||
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306026 (WNI_CFG_RTS_THRESHOLD_STAMAX < rts_threshold))
Jeff Johnson295189b2012-06-20 16:38:30 -07006027 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306028 hddLog(VOS_TRACE_LEVEL_ERROR,
6029 "%s: Invalid RTS Threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07006030 __func__, rts_threshold);
6031 return -EINVAL;
6032 }
6033
6034 if (0 != ccmCfgSetInt(hHal, WNI_CFG_RTS_THRESHOLD,
6035 rts_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306036 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -07006037 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306038 hddLog(VOS_TRACE_LEVEL_ERROR,
6039 "%s: ccmCfgSetInt failed for rts_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07006040 __func__, rts_threshold);
6041 return -EIO;
6042 }
6043
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306044 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set rts threshold %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07006045 rts_threshold);
6046 }
6047
6048 if (changed & WIPHY_PARAM_FRAG_THRESHOLD)
6049 {
6050 u16 frag_threshold = (wiphy->frag_threshold == -1) ?
6051 WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX :
6052 wiphy->frag_threshold;
6053
6054 if ((WNI_CFG_FRAGMENTATION_THRESHOLD_STAMIN > frag_threshold)||
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306055 (WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX < frag_threshold) )
Jeff Johnson295189b2012-06-20 16:38:30 -07006056 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306057 hddLog(VOS_TRACE_LEVEL_ERROR,
6058 "%s: Invalid frag_threshold value %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07006059 frag_threshold);
6060 return -EINVAL;
6061 }
6062
6063 if (0 != ccmCfgSetInt(hHal, WNI_CFG_FRAGMENTATION_THRESHOLD,
6064 frag_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306065 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -07006066 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306067 hddLog(VOS_TRACE_LEVEL_ERROR,
6068 "%s: ccmCfgSetInt failed for frag_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07006069 __func__, frag_threshold);
6070 return -EIO;
6071 }
6072
6073 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set frag threshold %hu", __func__,
6074 frag_threshold);
6075 }
6076
6077 if ((changed & WIPHY_PARAM_RETRY_SHORT)
6078 || (changed & WIPHY_PARAM_RETRY_LONG))
6079 {
6080 u8 retry_value = (changed & WIPHY_PARAM_RETRY_SHORT) ?
6081 wiphy->retry_short :
6082 wiphy->retry_long;
6083
6084 if ((WNI_CFG_LONG_RETRY_LIMIT_STAMIN > retry_value) ||
6085 (WNI_CFG_LONG_RETRY_LIMIT_STAMAX < retry_value))
6086 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306087 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07006088 __func__, retry_value);
6089 return -EINVAL;
6090 }
6091
6092 if (changed & WIPHY_PARAM_RETRY_SHORT)
6093 {
6094 if (0 != ccmCfgSetInt(hHal, WNI_CFG_LONG_RETRY_LIMIT,
6095 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306096 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -07006097 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306098 hddLog(VOS_TRACE_LEVEL_ERROR,
6099 "%s: ccmCfgSetInt failed for long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07006100 __func__, retry_value);
6101 return -EIO;
6102 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306103 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07006104 __func__, retry_value);
6105 }
6106 else if (changed & WIPHY_PARAM_RETRY_SHORT)
6107 {
6108 if (0 != ccmCfgSetInt(hHal, WNI_CFG_SHORT_RETRY_LIMIT,
6109 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306110 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -07006111 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306112 hddLog(VOS_TRACE_LEVEL_ERROR,
6113 "%s: ccmCfgSetInt failed for short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07006114 __func__, retry_value);
6115 return -EIO;
6116 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306117 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07006118 __func__, retry_value);
6119 }
6120 }
6121
6122 return 0;
6123}
6124
6125/*
6126 * FUNCTION: wlan_hdd_cfg80211_set_txpower
6127 * This function is used to set the txpower
6128 */
6129static int wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
6130#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306131 enum tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -07006132#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306133 enum nl80211_tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -07006134#endif
6135 int dbm)
6136{
6137 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
6138 tHalHandle hHal = pHddCtx->hHal;
6139 tSirMacAddr bssid = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
6140 tSirMacAddr selfMac = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
6141
6142 ENTER();
6143
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306144 if (0 != ccmCfgSetInt(hHal, WNI_CFG_CURRENT_TX_POWER_LEVEL,
6145 dbm, ccmCfgSetCallback,
6146 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -07006147 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306148 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07006149 "%s: ccmCfgSetInt failed for tx power %hu", __func__, dbm);
6150 return -EIO;
6151 }
6152
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006153 if ( pHddCtx->isLogpInProgress )
6154 {
6155 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6156 "%s:LOGP in Progress. Ignore!!!", __func__);
6157 return -EAGAIN;
6158 }
6159
Jeff Johnson295189b2012-06-20 16:38:30 -07006160 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set tx power level %d dbm", __func__,
6161 dbm);
6162
6163 switch(type)
6164 {
6165 case NL80211_TX_POWER_AUTOMATIC: /*automatically determine transmit power*/
6166 /* Fall through */
6167 case NL80211_TX_POWER_LIMITED: /*limit TX power by the mBm parameter*/
6168 if( sme_SetMaxTxPower(hHal, bssid, selfMac, dbm) != eHAL_STATUS_SUCCESS )
6169 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306170 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Setting maximum tx power failed",
6171 __func__);
6172 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -07006173 }
6174 break;
6175 case NL80211_TX_POWER_FIXED: /*fix TX power to the mBm parameter*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306176 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: NL80211_TX_POWER_FIXED not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -07006177 __func__);
6178 return -EOPNOTSUPP;
6179 break;
6180 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306181 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid power setting type %d",
6182 __func__, type);
Jeff Johnson295189b2012-06-20 16:38:30 -07006183 return -EIO;
6184 }
6185
6186 return 0;
6187}
6188
6189/*
6190 * FUNCTION: wlan_hdd_cfg80211_get_txpower
6191 * This function is used to read the txpower
6192 */
6193static int wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy, int *dbm)
6194{
6195
6196 hdd_adapter_t *pAdapter;
6197 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
6198
Jeff Johnsone7245742012-09-05 17:12:55 -07006199 ENTER();
6200
Jeff Johnson295189b2012-06-20 16:38:30 -07006201 if (NULL == pHddCtx)
6202 {
6203 hddLog(VOS_TRACE_LEVEL_FATAL,"%s: HDD context is Null",__func__);
6204 *dbm = 0;
6205 return -ENOENT;
6206 }
6207
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006208 if ( pHddCtx->isLogpInProgress )
6209 {
6210 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6211 "%s:LOGP in Progress. Ignore!!!", __func__);
6212 return -EAGAIN;
6213 }
6214
Jeff Johnson295189b2012-06-20 16:38:30 -07006215 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
6216 if (NULL == pAdapter)
6217 {
6218 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Not in station context " ,__func__);
6219 return -ENOENT;
6220 }
6221
6222 wlan_hdd_get_classAstats(pAdapter);
6223 *dbm = pAdapter->hdd_stats.ClassA_stat.max_pwr;
6224
Jeff Johnsone7245742012-09-05 17:12:55 -07006225 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07006226 return 0;
6227}
6228
6229static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
6230 u8* mac, struct station_info *sinfo)
6231{
6232 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
6233 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6234 int ssidlen = pHddStaCtx->conn_info.SSID.SSID.length;
6235 tANI_U8 rate_flags;
6236
6237 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
6238 hdd_config_t *pCfg = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -07006239
6240 tANI_U8 OperationalRates[CSR_DOT11_SUPPORTED_RATES_MAX];
6241 tANI_U32 ORLeng = CSR_DOT11_SUPPORTED_RATES_MAX;
6242 tANI_U8 ExtendedRates[CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX];
6243 tANI_U32 ERLeng = CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX;
6244 tANI_U8 MCSRates[SIZE_OF_BASIC_MCS_SET];
6245 tANI_U32 MCSLeng = SIZE_OF_BASIC_MCS_SET;
6246 tANI_U16 maxRate = 0;
6247 tANI_U16 myRate;
6248 tANI_U16 currentRate = 0;
6249 tANI_U8 maxSpeedMCS = 0;
6250 tANI_U8 maxMCSIdx = 0;
6251 tANI_U8 rateFlag = 1;
6252 tANI_U8 i, j, rssidx;
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07006253 tANI_U16 temp;
Jeff Johnson295189b2012-06-20 16:38:30 -07006254
Leo Chang6f8870f2013-03-26 18:11:36 -07006255#ifdef WLAN_FEATURE_11AC
6256 tANI_U32 vht_mcs_map;
6257 eDataRate11ACMaxMcs vhtMaxMcs;
6258#endif /* WLAN_FEATURE_11AC */
6259
Jeff Johnsone7245742012-09-05 17:12:55 -07006260 ENTER();
6261
Jeff Johnson295189b2012-06-20 16:38:30 -07006262 if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) ||
6263 (0 == ssidlen))
6264 {
6265 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Not associated or"
6266 " Invalid ssidlen, %d", __func__, ssidlen);
6267 /*To keep GUI happy*/
6268 return 0;
6269 }
6270
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006271 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
6272 {
6273 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6274 "%s:LOGP in Progress. Ignore!!!", __func__);
6275 return -EAGAIN;
6276 }
6277
Jeff Johnson295189b2012-06-20 16:38:30 -07006278 wlan_hdd_get_rssi(pAdapter, &sinfo->signal);
6279 sinfo->filled |= STATION_INFO_SIGNAL;
6280
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -07006281 wlan_hdd_get_station_stats(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07006282 rate_flags = pAdapter->hdd_stats.ClassA_stat.tx_rate_flags;
6283
6284 //convert to the UI units of 100kbps
6285 myRate = pAdapter->hdd_stats.ClassA_stat.tx_rate * 5;
6286
6287#ifdef LINKSPEED_DEBUG_ENABLED
Leo Chang6f8870f2013-03-26 18:11:36 -07006288 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 -07006289 sinfo->signal,
6290 pCfg->reportMaxLinkSpeed,
6291 myRate,
6292 (int) pCfg->linkSpeedRssiHigh,
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07006293 (int) pCfg->linkSpeedRssiMid,
6294 (int) pCfg->linkSpeedRssiLow,
Leo Chang6f8870f2013-03-26 18:11:36 -07006295 (int) rate_flags,
6296 (int) pAdapter->hdd_stats.ClassA_stat.mcs_index);
Jeff Johnson295189b2012-06-20 16:38:30 -07006297#endif //LINKSPEED_DEBUG_ENABLED
6298
6299 if (eHDD_LINK_SPEED_REPORT_ACTUAL != pCfg->reportMaxLinkSpeed)
6300 {
6301 // we do not want to necessarily report the current speed
6302 if (eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed)
6303 {
6304 // report the max possible speed
6305 rssidx = 0;
6306 }
6307 else if (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed)
6308 {
6309 // report the max possible speed with RSSI scaling
6310 if (sinfo->signal >= pCfg->linkSpeedRssiHigh)
6311 {
6312 // report the max possible speed
6313 rssidx = 0;
6314 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07006315 else if (sinfo->signal >= pCfg->linkSpeedRssiMid)
Jeff Johnson295189b2012-06-20 16:38:30 -07006316 {
6317 // report middle speed
6318 rssidx = 1;
6319 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07006320 else if (sinfo->signal >= pCfg->linkSpeedRssiLow)
6321 {
6322 // report middle speed
6323 rssidx = 2;
6324 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006325 else
6326 {
6327 // report actual speed
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07006328 rssidx = 3;
Jeff Johnson295189b2012-06-20 16:38:30 -07006329 }
6330 }
6331 else
6332 {
6333 // unknown, treat as eHDD_LINK_SPEED_REPORT_MAX
6334 hddLog(VOS_TRACE_LEVEL_ERROR,
6335 "%s: Invalid value for reportMaxLinkSpeed: %u",
6336 __func__, pCfg->reportMaxLinkSpeed);
6337 rssidx = 0;
6338 }
6339
6340 maxRate = 0;
6341
6342 /* Get Basic Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +05306343 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_OPERATIONAL_RATE_SET,
6344 OperationalRates, &ORLeng))
6345 {
6346 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
6347 /*To keep GUI happy*/
6348 return 0;
6349 }
6350
Jeff Johnson295189b2012-06-20 16:38:30 -07006351 for (i = 0; i < ORLeng; i++)
6352 {
Jeff Johnsone7245742012-09-05 17:12:55 -07006353 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -07006354 {
6355 /* Validate Rate Set */
6356 if (supported_data_rate[j].beacon_rate_index == (OperationalRates[i] & 0x7F))
6357 {
6358 currentRate = supported_data_rate[j].supported_rate[rssidx];
6359 break;
6360 }
6361 }
6362 /* Update MAX rate */
6363 maxRate = (currentRate > maxRate)?currentRate:maxRate;
6364 }
6365
6366 /* Get Extended Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +05306367 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET,
6368 ExtendedRates, &ERLeng))
6369 {
6370 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
6371 /*To keep GUI happy*/
6372 return 0;
6373 }
6374
Jeff Johnson295189b2012-06-20 16:38:30 -07006375 for (i = 0; i < ERLeng; i++)
6376 {
Jeff Johnsone7245742012-09-05 17:12:55 -07006377 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -07006378 {
6379 if (supported_data_rate[j].beacon_rate_index == (ExtendedRates[i] & 0x7F))
6380 {
6381 currentRate = supported_data_rate[j].supported_rate[rssidx];
6382 break;
6383 }
6384 }
6385 /* Update MAX rate */
6386 maxRate = (currentRate > maxRate)?currentRate:maxRate;
6387 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006388 /* Get MCS Rate Set -- but only if we are connected at MCS
6389 rates or if we are always reporting max speed or if we have
6390 good rssi */
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07006391 if ((0 == rssidx) && !(rate_flags & eHAL_TX_RATE_LEGACY))
Jeff Johnson295189b2012-06-20 16:38:30 -07006392 {
Gopichand Nakkala05ab1322013-02-15 11:28:38 +05306393 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_CURRENT_MCS_SET,
6394 MCSRates, &MCSLeng))
6395 {
6396 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
6397 /*To keep GUI happy*/
6398 return 0;
6399 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006400 rateFlag = 0;
Leo Chang6f8870f2013-03-26 18:11:36 -07006401#ifdef WLAN_FEATURE_11AC
6402 /* VHT80 rate has seperate rate table */
Gopichand Nakkala4c705372013-04-24 13:20:33 +05306403 if (rate_flags & (eHAL_TX_RATE_VHT20|eHAL_TX_RATE_VHT40|eHAL_TX_RATE_VHT80))
Jeff Johnson295189b2012-06-20 16:38:30 -07006404 {
Leo Chang6f8870f2013-03-26 18:11:36 -07006405 ccmCfgGetInt(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_VHT_TX_MCS_MAP, &vht_mcs_map);
Gopichand Nakkala4c705372013-04-24 13:20:33 +05306406 vhtMaxMcs = (eDataRate11ACMaxMcs)(vht_mcs_map & DATA_RATE_11AC_MCS_MASK );
Leo Chang6f8870f2013-03-26 18:11:36 -07006407 if (rate_flags & eHAL_TX_RATE_SGI)
Jeff Johnson295189b2012-06-20 16:38:30 -07006408 {
Leo Chang6f8870f2013-03-26 18:11:36 -07006409 rateFlag |= 1;
Jeff Johnson295189b2012-06-20 16:38:30 -07006410 }
Leo Chang6f8870f2013-03-26 18:11:36 -07006411 if (DATA_RATE_11AC_MAX_MCS_7 == vhtMaxMcs)
Jeff Johnson295189b2012-06-20 16:38:30 -07006412 {
Leo Chang6f8870f2013-03-26 18:11:36 -07006413 maxMCSIdx = 7;
6414 }
6415 else if (DATA_RATE_11AC_MAX_MCS_8 == vhtMaxMcs)
6416 {
6417 maxMCSIdx = 8;
6418 }
6419 else if (DATA_RATE_11AC_MAX_MCS_9 == vhtMaxMcs)
6420 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +05306421 //VHT20 is supporting 0~8
6422 if (rate_flags & eHAL_TX_RATE_VHT20)
6423 maxMCSIdx = 8;
6424 else
6425 maxMCSIdx = 9;
Leo Chang6f8870f2013-03-26 18:11:36 -07006426 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +05306427
6428 if (rate_flags & eHAL_TX_RATE_VHT80)
6429 {
6430 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT80_rate[rateFlag];
6431 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT80_rate[rateFlag];
6432 }
6433 else if (rate_flags & eHAL_TX_RATE_VHT40)
6434 {
6435 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT40_rate[rateFlag];
6436 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT40_rate[rateFlag];
6437 }
6438 else if (rate_flags & eHAL_TX_RATE_VHT20)
6439 {
6440 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT20_rate[rateFlag];
6441 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT20_rate[rateFlag];
6442 }
6443
Leo Chang6f8870f2013-03-26 18:11:36 -07006444 maxSpeedMCS = 1;
6445 if (currentRate > maxRate)
6446 {
6447 maxRate = currentRate;
6448 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +05306449
Leo Chang6f8870f2013-03-26 18:11:36 -07006450 }
6451 else
6452#endif /* WLAN_FEATURE_11AC */
6453 {
6454 if (rate_flags & eHAL_TX_RATE_HT40)
6455 {
6456 rateFlag |= 1;
6457 }
6458 if (rate_flags & eHAL_TX_RATE_SGI)
6459 {
6460 rateFlag |= 2;
6461 }
6462
6463 for (i = 0; i < MCSLeng; i++)
6464 {
6465 temp = sizeof(supported_mcs_rate) / sizeof(supported_mcs_rate[0]);
6466 for (j = 0; j < temp; j++)
6467 {
6468 if (supported_mcs_rate[j].beacon_rate_index == MCSRates[i])
6469 {
6470 currentRate = supported_mcs_rate[j].supported_rate[rateFlag];
6471 break;
6472 }
6473 }
6474 if ((j < temp) && (currentRate > maxRate))
6475 {
6476 maxRate = currentRate;
6477 maxSpeedMCS = 1;
6478 maxMCSIdx = supported_mcs_rate[j].beacon_rate_index;
6479 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006480 }
6481 }
6482 }
6483
Gopichand Nakkala4c705372013-04-24 13:20:33 +05306484 else if (!(rate_flags & eHAL_TX_RATE_LEGACY))
6485 {
6486 maxRate = myRate;
6487 maxSpeedMCS = 1;
6488 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
6489 }
6490
Jeff Johnson295189b2012-06-20 16:38:30 -07006491 // make sure we report a value at least as big as our current rate
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07006492 if (((maxRate < myRate) && (0 == rssidx)) ||
6493 (0 == maxRate))
Jeff Johnson295189b2012-06-20 16:38:30 -07006494 {
6495 maxRate = myRate;
6496 if (rate_flags & eHAL_TX_RATE_LEGACY)
6497 {
6498 maxSpeedMCS = 0;
6499 }
6500 else
6501 {
6502 maxSpeedMCS = 1;
6503 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
6504 }
6505 }
6506
Gopichand Nakkala4c705372013-04-24 13:20:33 +05306507 if (rate_flags & eHAL_TX_RATE_LEGACY)
Jeff Johnson295189b2012-06-20 16:38:30 -07006508 {
6509 sinfo->txrate.legacy = maxRate;
6510#ifdef LINKSPEED_DEBUG_ENABLED
6511 pr_info("Reporting legacy rate %d\n", sinfo->txrate.legacy);
6512#endif //LINKSPEED_DEBUG_ENABLED
6513 }
6514 else
6515 {
6516 sinfo->txrate.mcs = maxMCSIdx;
Leo Chang6f8870f2013-03-26 18:11:36 -07006517#ifdef WLAN_FEATURE_11AC
6518 sinfo->txrate.nss = 1;
6519 if (rate_flags & eHAL_TX_RATE_VHT80)
6520 {
6521 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
Gopichand Nakkala4c705372013-04-24 13:20:33 +05306522 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
Leo Chang6f8870f2013-03-26 18:11:36 -07006523 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +05306524 else if (rate_flags & eHAL_TX_RATE_VHT40)
Leo Chang6f8870f2013-03-26 18:11:36 -07006525 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +05306526 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
6527 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
6528 }
6529 else if (rate_flags & eHAL_TX_RATE_VHT20)
6530 {
6531 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
6532 }
6533#endif /* WLAN_FEATURE_11AC */
6534 if (rate_flags & (eHAL_TX_RATE_HT20 | eHAL_TX_RATE_HT40))
6535 {
6536 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
6537 if (rate_flags & eHAL_TX_RATE_HT40)
6538 {
6539 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
6540 }
Leo Chang6f8870f2013-03-26 18:11:36 -07006541 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006542 if (rate_flags & eHAL_TX_RATE_SGI)
6543 {
6544 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
6545 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +05306546
Jeff Johnson295189b2012-06-20 16:38:30 -07006547#ifdef LINKSPEED_DEBUG_ENABLED
6548 pr_info("Reporting MCS rate %d flags %x\n",
6549 sinfo->txrate.mcs,
6550 sinfo->txrate.flags );
6551#endif //LINKSPEED_DEBUG_ENABLED
6552 }
6553 }
6554 else
6555 {
6556 // report current rate instead of max rate
6557
6558 if (rate_flags & eHAL_TX_RATE_LEGACY)
6559 {
6560 //provide to the UI in units of 100kbps
6561 sinfo->txrate.legacy = myRate;
6562#ifdef LINKSPEED_DEBUG_ENABLED
6563 pr_info("Reporting actual legacy rate %d\n", sinfo->txrate.legacy);
6564#endif //LINKSPEED_DEBUG_ENABLED
6565 }
6566 else
6567 {
6568 //must be MCS
6569 sinfo->txrate.mcs = pAdapter->hdd_stats.ClassA_stat.mcs_index;
Leo Chang6f8870f2013-03-26 18:11:36 -07006570#ifdef WLAN_FEATURE_11AC
6571 sinfo->txrate.nss = 1;
6572 if (rate_flags & eHAL_TX_RATE_VHT80)
6573 {
6574 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
6575 }
6576 else
6577#endif /* WLAN_FEATURE_11AC */
6578 {
6579 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
6580 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006581 if (rate_flags & eHAL_TX_RATE_SGI)
6582 {
6583 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
6584 }
6585 if (rate_flags & eHAL_TX_RATE_HT40)
6586 {
6587 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
6588 }
Leo Chang6f8870f2013-03-26 18:11:36 -07006589#ifdef WLAN_FEATURE_11AC
6590 else if (rate_flags & eHAL_TX_RATE_VHT80)
6591 {
6592 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
6593 }
6594#endif /* WLAN_FEATURE_11AC */
Jeff Johnson295189b2012-06-20 16:38:30 -07006595#ifdef LINKSPEED_DEBUG_ENABLED
6596 pr_info("Reporting actual MCS rate %d flags %x\n",
6597 sinfo->txrate.mcs,
6598 sinfo->txrate.flags );
6599#endif //LINKSPEED_DEBUG_ENABLED
6600 }
6601 }
6602 sinfo->filled |= STATION_INFO_TX_BITRATE;
6603
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -07006604 sinfo->tx_packets =
6605 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[0] +
6606 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[1] +
6607 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[2] +
6608 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[3];
6609
6610 sinfo->tx_retries =
6611 pAdapter->hdd_stats.summary_stat.retry_cnt[0] +
6612 pAdapter->hdd_stats.summary_stat.retry_cnt[1] +
6613 pAdapter->hdd_stats.summary_stat.retry_cnt[2] +
6614 pAdapter->hdd_stats.summary_stat.retry_cnt[3];
6615
6616 sinfo->tx_failed =
6617 pAdapter->hdd_stats.summary_stat.fail_cnt[0] +
6618 pAdapter->hdd_stats.summary_stat.fail_cnt[1] +
6619 pAdapter->hdd_stats.summary_stat.fail_cnt[2] +
6620 pAdapter->hdd_stats.summary_stat.fail_cnt[3];
6621
6622 sinfo->filled |=
6623 STATION_INFO_TX_PACKETS |
6624 STATION_INFO_TX_RETRIES |
6625 STATION_INFO_TX_FAILED;
6626
6627 EXIT();
6628 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07006629}
6630
6631static int wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
6632 struct net_device *dev, bool mode, v_SINT_t timeout)
6633{
6634 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +05306635 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07006636 VOS_STATUS vos_status;
6637
Jeff Johnsone7245742012-09-05 17:12:55 -07006638 ENTER();
6639
Jeff Johnson295189b2012-06-20 16:38:30 -07006640 if (NULL == pAdapter)
6641 {
6642 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL\n", __func__);
6643 return -ENODEV;
6644 }
6645
Gopichand Nakkala20c4c042013-04-19 22:08:55 +05306646 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
6647 if (NULL == pHddCtx)
6648 {
6649 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: HDD context is NULL\n", __func__);
6650 return -ENODEV;
6651 }
6652
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306653 if ( pHddCtx->isLogpInProgress )
6654 {
6655 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6656 "%s:LOGP in Progress. Ignore!!!", __func__);
6657 return -EAGAIN;
6658 }
6659
Gopichand Nakkala20c4c042013-04-19 22:08:55 +05306660 if ((DRIVER_POWER_MODE_AUTO == !mode) &&
6661 (TRUE == pHddCtx->hdd_wlan_suspended) &&
6662 (pHddCtx->cfg_ini->fhostArpOffload) &&
6663 (eConnectionState_Associated ==
6664 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
6665 {
6666 vos_status = hdd_conf_hostarpoffload(pAdapter, TRUE);
6667 if (!VOS_IS_STATUS_SUCCESS(vos_status))
6668 {
6669 hddLog(VOS_TRACE_LEVEL_INFO,
6670 "%s:Failed to enable ARPOFFLOAD Feature %d\n",
6671 __func__, vos_status);
6672 }
6673 }
6674
Jeff Johnson295189b2012-06-20 16:38:30 -07006675 /**The get power cmd from the supplicant gets updated by the nl only
6676 *on successful execution of the function call
6677 *we are oppositely mapped w.r.t mode in the driver
6678 **/
6679 vos_status = wlan_hdd_enter_bmps(pAdapter, !mode);
6680
Jeff Johnsone7245742012-09-05 17:12:55 -07006681 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07006682 if (VOS_STATUS_E_FAILURE == vos_status)
6683 {
6684 return -EINVAL;
6685 }
6686 return 0;
6687}
6688
6689
6690#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
6691static int wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
6692 struct net_device *netdev,
6693 u8 key_index)
6694{
Jeff Johnsone7245742012-09-05 17:12:55 -07006695 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07006696 return 0;
6697}
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306698#endif //LINUX_VERSION_CODE
Jeff Johnson295189b2012-06-20 16:38:30 -07006699
6700#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
6701static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
6702 struct net_device *dev,
6703 struct ieee80211_txq_params *params)
6704{
Jeff Johnsone7245742012-09-05 17:12:55 -07006705 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07006706 return 0;
6707}
6708#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
6709static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
6710 struct ieee80211_txq_params *params)
6711{
Jeff Johnsone7245742012-09-05 17:12:55 -07006712 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07006713 return 0;
6714}
6715#endif //LINUX_VERSION_CODE
6716
6717static int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
6718 struct net_device *dev, u8 *mac)
6719{
6720 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08006721 VOS_STATUS vos_status;
6722 v_U8_t staId;
Jeff Johnson295189b2012-06-20 16:38:30 -07006723
Jeff Johnsone7245742012-09-05 17:12:55 -07006724 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07006725 if ( NULL == pAdapter || NULL == pAdapter->pHddCtx)
6726 {
6727 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Invalid Adapter or HDD Context " ,__func__);
6728 return -EINVAL;
6729 }
6730
6731 if (((hdd_context_t*)pAdapter->pHddCtx)->isLoadUnloadInProgress)
6732 {
6733 hddLog( LOGE,
6734 "%s: Wlan Load/Unload is in progress", __func__);
6735 return -EBUSY;
6736 }
6737
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006738 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
6739 {
6740 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6741 "%s:LOGP in Progress. Ignore!!!", __func__);
6742 return -EAGAIN;
6743 }
6744
Jeff Johnson295189b2012-06-20 16:38:30 -07006745 if ( (WLAN_HDD_SOFTAP == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -07006746 || (WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -07006747 )
6748 {
6749 if( NULL == mac )
6750 {
6751 v_U16_t i;
6752 for(i = 0; i < WLAN_MAX_STA_COUNT; i++)
6753 {
6754 if(pAdapter->aStaInfo[i].isUsed)
6755 {
6756 u8 *macAddr = pAdapter->aStaInfo[i].macAddrSTA.bytes;
6757 hddLog(VOS_TRACE_LEVEL_INFO,
6758 "%s: Delete STA with MAC::"
6759 "%02x:%02x:%02x:%02x:%02x:%02x",
6760 __func__,
6761 macAddr[0], macAddr[1], macAddr[2],
6762 macAddr[3], macAddr[4], macAddr[5]);
6763 hdd_softap_sta_deauth(pAdapter, macAddr);
6764 }
6765 }
6766 }
6767 else
6768 {
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08006769
6770 vos_status = hdd_softap_GetStaId(pAdapter,(v_MACADDR_t *)mac, &staId);
6771 if (!VOS_IS_STATUS_SUCCESS(vos_status))
6772 {
6773 hddLog(VOS_TRACE_LEVEL_INFO,
6774 "%s: Skip this DEL STA as this is not used::"
6775 "%02x:%02x:%02x:%02x:%02x:%02x",
6776 __func__,
6777 mac[0], mac[1], mac[2],
6778 mac[3], mac[4], mac[5]);
6779 return -ENOENT;
6780 }
6781
6782 if( pAdapter->aStaInfo[staId].isDeauthInProgress == TRUE)
6783 {
6784 hddLog(VOS_TRACE_LEVEL_INFO,
6785 "%s: Skip this DEL STA as deauth is in progress::"
6786 "%02x:%02x:%02x:%02x:%02x:%02x",
6787 __func__,
6788 mac[0], mac[1], mac[2],
6789 mac[3], mac[4], mac[5]);
6790 return -ENOENT;
6791 }
6792
6793 pAdapter->aStaInfo[staId].isDeauthInProgress = TRUE;
6794
Jeff Johnson295189b2012-06-20 16:38:30 -07006795 hddLog(VOS_TRACE_LEVEL_INFO,
6796 "%s: Delete STA with MAC::"
6797 "%02x:%02x:%02x:%02x:%02x:%02x",
6798 __func__,
6799 mac[0], mac[1], mac[2],
6800 mac[3], mac[4], mac[5]);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08006801
6802 vos_status = hdd_softap_sta_deauth(pAdapter, mac);
6803 if (!VOS_IS_STATUS_SUCCESS(vos_status))
6804 {
6805 pAdapter->aStaInfo[staId].isDeauthInProgress = FALSE;
6806 hddLog(VOS_TRACE_LEVEL_INFO,
6807 "%s: STA removal failed for ::"
6808 "%02x:%02x:%02x:%02x:%02x:%02x",
6809 __func__,
6810 mac[0], mac[1], mac[2],
6811 mac[3], mac[4], mac[5]);
6812 return -ENOENT;
6813 }
6814
Jeff Johnson295189b2012-06-20 16:38:30 -07006815 }
6816 }
6817
6818 EXIT();
6819
6820 return 0;
6821}
6822
Hoonki Lee11f7dda2013-02-14 16:55:44 -08006823static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
6824 struct net_device *dev, u8 *mac, struct station_parameters *params)
6825{
Gopichand Nakkalab977a972013-02-18 19:15:09 -08006826 int status = -EPERM;
Hoonki Lee11f7dda2013-02-14 16:55:44 -08006827#ifdef FEATURE_WLAN_TDLS
6828 u32 mask, set;
Hoonki Lee11f7dda2013-02-14 16:55:44 -08006829 ENTER();
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006830 mask = params->sta_flags_mask;
6831
6832 set = params->sta_flags_set;
6833
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07006834#ifdef WLAN_FEATURE_TDLS_DEBUG
6835 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6836 "%s: mask 0x%x set 0x%x " MAC_ADDRESS_STR,
6837 __func__, mask, set, MAC_ADDR_ARRAY(mac));
6838#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006839
6840 if (mask & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
6841 if (set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
Gopichand Nakkala681989c2013-03-06 22:27:48 -08006842 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 0, NULL);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006843 }
6844 }
6845#endif
Gopichand Nakkalab977a972013-02-18 19:15:09 -08006846 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -07006847}
6848
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006849
6850#ifdef FEATURE_WLAN_LFR
6851static int wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
Jeff Johnsond13512a2012-07-17 11:42:19 -07006852 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006853{
6854#define MAX_PMKSAIDS_IN_CACHE 8
6855 static tPmkidCacheInfo PMKIDCache[MAX_PMKSAIDS_IN_CACHE]; // HDD Local cache
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306856 static tANI_U32 i; // HDD Local Cache index
6857 tANI_U32 j=0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006858 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6859 tHalHandle halHandle;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306860 eHalStatus result;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006861 tANI_U8 BSSIDMatched = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306862
Jeff Johnsone7245742012-09-05 17:12:55 -07006863 ENTER();
6864
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306865 // Validate pAdapter
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006866 if ( NULL == pAdapter || NULL == pAdapter->pHddCtx)
6867 {
6868 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Invalid Adapter or HDD Context " ,__func__);
6869 return -EINVAL;
6870 }
6871
6872 if (((hdd_context_t*)pAdapter->pHddCtx)->isLoadUnloadInProgress)
6873 {
6874 hddLog( LOGE,
6875 "%s: Wlan Load/Unload is in progress", __func__);
6876 return -EBUSY;
6877 }
6878
6879 if ( (WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress )
6880 {
6881 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6882 "%s:LOGP in Progress. Ignore!!!", __func__);
6883 return -EAGAIN;
6884 }
6885
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306886 // Retrieve halHandle
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006887 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
6888
6889 for (j = 0; j < i; j++)
6890 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306891 if(vos_mem_compare(PMKIDCache[j].BSSID,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006892 pmksa->bssid, WNI_CFG_BSSID_LEN))
6893 {
6894 /* BSSID matched previous entry. Overwrite it. */
6895 BSSIDMatched = 1;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306896 vos_mem_copy(PMKIDCache[j].BSSID,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006897 pmksa->bssid, WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306898 vos_mem_copy(PMKIDCache[j].PMKID,
6899 pmksa->pmkid,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006900 CSR_RSN_PMKID_SIZE);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306901 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Reusing cache entry %d.",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006902 __func__, j );
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006903 dump_bssid(pmksa->bssid);
6904 dump_pmkid(halHandle, pmksa->pmkid);
6905 break;
6906 }
6907 }
6908
Madan Mohan Koyyalamudic4b317d2012-10-18 19:43:08 -07006909 /* Check we compared all entries,if then take the first slot now */
6910 if(j == MAX_PMKSAIDS_IN_CACHE) i=0;
6911
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006912 if (!BSSIDMatched)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306913 {
6914 // Now, we DON'T have a BSSID match, so take a new entry in the cache.
6915 vos_mem_copy(PMKIDCache[i].BSSID,
6916 pmksa->bssid, ETHER_ADDR_LEN);
6917 vos_mem_copy(PMKIDCache[i].PMKID,
6918 pmksa->pmkid,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006919 CSR_RSN_PMKID_SIZE);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306920 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Adding a new cache entry %d.",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006921 __func__, i );
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006922 dump_bssid(pmksa->bssid);
6923 dump_pmkid(halHandle, pmksa->pmkid);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306924 // Increment the HDD Local Cache index
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006925 // The "i=0" doesn't work for the call to sme_RoamSetPMKIDCache() - LFR FIXME
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306926 if (i<=(MAX_PMKSAIDS_IN_CACHE-1)) i++; else i=0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006927 }
6928
6929
6930 // Calling csrRoamSetPMKIDCache to configure the PMKIDs into the cache
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306931 //hddLog(LOG1, FL("%s: Calling csrRoamSetPMKIDCache with %d cache entries."),
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006932 // __func__, i );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306933 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Calling csrRoamSetPMKIDCache with %d cache entries.",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006934 __func__, i );
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006935 // Finally set the PMKSA ID Cache in CSR
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306936 result = sme_RoamSetPMKIDCache(halHandle,pAdapter->sessionId,
6937 PMKIDCache,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006938 i );
6939 return 0;
6940}
6941
6942
6943static int wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
Jeff Johnsond13512a2012-07-17 11:42:19 -07006944 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006945{
Jeff Johnsone7245742012-09-05 17:12:55 -07006946 ENTER();
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006947 // TODO: Implement this later.
6948 return 0;
6949}
6950
6951static int wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
6952{
Jeff Johnsone7245742012-09-05 17:12:55 -07006953 ENTER();
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006954 // TODO: Implement this later.
6955 return 0;
6956}
6957#endif
6958
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07006959#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306960static int wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07006961 struct net_device *dev, struct cfg80211_update_ft_ies_params *ftie)
6962{
6963 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6964 hdd_station_ctx_t *pHddStaCtx;
6965
6966 if (NULL == pAdapter)
6967 {
6968 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL\n", __func__);
6969 return -ENODEV;
6970 }
6971
6972 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6973
6974 // Added for debug on reception of Re-assoc Req.
6975 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
6976 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306977 hddLog(LOGE, FL("Called with Ie of length = %d when not associated\n"),
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07006978 ftie->ie_len);
6979 hddLog(LOGE, FL("Should be Re-assoc Req IEs\n"));
6980 }
6981
6982#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306983 hddLog(LOGE, FL("%s called with Ie of length = %d\n"), __func__,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07006984 ftie->ie_len);
6985#endif
6986
6987 // Pass the received FT IEs to SME
Gopichand Nakkala356fb102013-03-06 12:34:04 +05306988 sme_SetFTIEs( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
6989 (const u8 *)ftie->ie,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07006990 ftie->ie_len);
6991 return 0;
6992}
6993#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006994
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05306995#ifdef FEATURE_WLAN_SCAN_PNO
6996
6997void hdd_cfg80211_sched_scan_done_callback(void *callbackContext,
6998 tSirPrefNetworkFoundInd *pPrefNetworkFoundInd)
6999{
7000 int ret;
7001 hdd_adapter_t* pAdapter = (hdd_adapter_t*)callbackContext;
7002 hdd_context_t *pHddCtx;
7003
7004 if (NULL == pAdapter)
7005 {
7006 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
7007 "%s: HDD adapter is Null", __func__);
7008 return ;
7009 }
7010
7011 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7012 if (NULL == pHddCtx)
7013 {
7014 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7015 "%s: HDD context is Null!!!", __func__);
7016 return ;
7017 }
7018
7019 ret = wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter);
7020
7021 if (0 > ret)
7022 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
7023
7024 cfg80211_sched_scan_results(pHddCtx->wiphy);
7025}
7026
7027/*
7028 * FUNCTION: wlan_hdd_cfg80211_sched_scan_start
7029 * NL interface to enable PNO
7030 */
7031static int wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
7032 struct net_device *dev, struct cfg80211_sched_scan_request *request)
7033{
7034 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
7035 tpSirPNOScanReq pPnoRequest = NULL;
7036 hdd_context_t *pHddCtx;
7037 tHalHandle hHal;
7038 v_U32_t i, indx, num_ch;
7039 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN];
7040 u8 channels_allowed[WNI_CFG_VALID_CHANNEL_LIST_LEN];
7041 v_U32_t num_channels_allowed = WNI_CFG_VALID_CHANNEL_LIST_LEN;
7042 eHalStatus status = eHAL_STATUS_FAILURE;
7043
7044 if (NULL == pAdapter)
7045 {
7046 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
7047 "%s: HDD adapter is Null", __func__);
7048 return -ENODEV;
7049 }
7050
7051 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7052 if (NULL == pHddCtx)
7053 {
7054 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7055 "%s: HDD context is Null!!!", __func__);
7056 return -ENODEV;
7057 }
7058
7059 if (pHddCtx->isLogpInProgress)
7060 {
7061 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
7062 "%s: LOGP in Progress. Ignore!!!", __func__);
7063 return -EAGAIN;
7064 }
7065
7066 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
7067 if (NULL == hHal)
7068 {
7069 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7070 "%s: HAL context is Null!!!", __func__);
7071 return -EAGAIN;
7072 }
7073
7074 pPnoRequest = (tpSirPNOScanReq) vos_mem_malloc(sizeof (tSirPNOScanReq));
7075 if (NULL == pPnoRequest)
7076 {
7077 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
7078 "%s: vos_mem_malloc failed", __func__);
7079 return -ENODEV;
7080 }
7081
7082 pPnoRequest->enable = 1; /*Enable PNO */
7083 pPnoRequest->ucNetworksCount = request->n_match_sets;
7084
7085 if (( !pPnoRequest->ucNetworksCount ) ||
7086 ( pPnoRequest->ucNetworksCount > SIR_PNO_MAX_SUPP_NETWORKS ))
7087 {
7088 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7089 "Network input is not correct");
7090 goto error;
7091 }
7092
7093 if ( SIR_PNO_MAX_NETW_CHANNELS_EX < request->n_channels )
7094 {
7095 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7096 "Incorrect number of channels");
7097 goto error;
7098 }
7099
7100 /* Framework provides one set of channels(all)
7101 * common for all saved profile */
7102 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
7103 channels_allowed, &num_channels_allowed))
7104 {
7105 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7106 "%s: failed to get valid channel list", __func__);
7107 goto error;
7108 }
7109 /* Checking each channel against allowed channel list */
7110 num_ch = 0;
7111 for (i = 0; i < request->n_channels; i++)
7112 {
7113 for (indx = 0; indx < num_channels_allowed; indx++)
7114 {
7115 if (request->channels[i]->hw_value == channels_allowed[indx])
7116 {
7117 valid_ch[num_ch++] = request->channels[i]->hw_value;
7118 break ;
7119 }
7120 }
7121 }
7122
7123 /* Filling per profile params */
7124 for (i = 0; i < pPnoRequest->ucNetworksCount; i++)
7125 {
7126 pPnoRequest->aNetworks[i].ssId.length =
7127 request->match_sets[i].ssid.ssid_len;
7128
7129 if (( 0 == pPnoRequest->aNetworks[i].ssId.length ) ||
7130 ( pPnoRequest->aNetworks[i].ssId.length > 32 ) )
7131 {
7132 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7133 "SSID Len %d is not correct for network %d",
7134 pPnoRequest->aNetworks[i].ssId.length, i);
7135 goto error;
7136 }
7137
7138 memcpy(pPnoRequest->aNetworks[i].ssId.ssId,
7139 request->match_sets[i].ssid.ssid,
7140 request->match_sets[i].ssid.ssid_len);
7141 pPnoRequest->aNetworks[i].authentication = 0; /*eAUTH_TYPE_ANY*/
7142 pPnoRequest->aNetworks[i].encryption = 0; /*eED_ANY*/
7143 pPnoRequest->aNetworks[i].bcastNetwType = 0; /*eBCAST_UNKNOWN*/
7144
7145 /*Copying list of valid channel into request */
7146 memcpy(pPnoRequest->aNetworks[i].aChannels, valid_ch, num_ch);
7147 pPnoRequest->aNetworks[i].ucChannelCount = num_ch;
7148
7149 pPnoRequest->aNetworks[i].rssiThreshold = 0; //Default value
7150 }
7151
7152 /* framework provides interval in ms */
7153 pPnoRequest->scanTimers.ucScanTimersCount = 1;
7154 pPnoRequest->scanTimers.aTimerValues[0].uTimerValue =
7155 (request->interval)/1000;
7156 pPnoRequest->scanTimers.aTimerValues[0].uTimerRepeat = 0;
7157 pPnoRequest->modePNO = SIR_PNO_MODE_ON_SUSPEND;
7158
7159 status = sme_SetPreferredNetworkList(WLAN_HDD_GET_HAL_CTX(pAdapter),
7160 pPnoRequest, pAdapter->sessionId,
7161 hdd_cfg80211_sched_scan_done_callback, pAdapter);
7162 if (eHAL_STATUS_SUCCESS != status)
7163 {
7164 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7165 "Failed to enable PNO");
7166 goto error;
7167 }
7168
7169error:
7170 vos_mem_free(pPnoRequest);
7171 return status;
7172}
7173
7174/*
7175 * FUNCTION: wlan_hdd_cfg80211_sched_scan_stop
7176 * NL interface to disable PNO
7177 */
7178static int wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
7179 struct net_device *dev)
7180{
7181 eHalStatus status = eHAL_STATUS_FAILURE;
7182 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
7183 hdd_context_t *pHddCtx;
7184 tHalHandle hHal;
7185 tpSirPNOScanReq pPnoRequest = NULL;
7186
7187 ENTER();
7188
7189 if (NULL == pAdapter)
7190 {
7191 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
7192 "%s: HDD adapter is Null", __func__);
7193 return -ENODEV;
7194 }
7195
7196 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7197 if (NULL == pHddCtx)
7198 {
7199 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7200 "%s: HDD context is Null!!!", __func__);
7201 return -ENODEV;
7202 }
7203
7204 if (pHddCtx->isLogpInProgress)
7205 {
7206 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
7207 "%s: LOGP in Progress. Ignore!!!", __func__);
7208 return -EAGAIN;
7209 }
7210
7211 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
7212 if (NULL == hHal)
7213 {
7214 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7215 "%s: HAL context is Null!!!", __func__);
7216 return -EAGAIN;
7217 }
7218
7219 pPnoRequest = (tpSirPNOScanReq) vos_mem_malloc(sizeof (tSirPNOScanReq));
7220 if (NULL == pPnoRequest)
7221 {
7222 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
7223 "%s: vos_mem_malloc failed", __func__);
7224 return -ENODEV;
7225 }
7226
7227 memset(pPnoRequest, 0, sizeof (tSirPNOScanReq));
7228 pPnoRequest->enable = 0; /* Disable PNO */
7229 pPnoRequest->ucNetworksCount = 0;
7230
7231 status = sme_SetPreferredNetworkList(hHal, pPnoRequest,
7232 pAdapter->sessionId,
7233 NULL, pAdapter);
7234 if (eHAL_STATUS_SUCCESS != status)
7235 {
7236 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7237 "Failed to disabled PNO");
7238 }
7239
7240 vos_mem_free(pPnoRequest);
7241
7242 EXIT();
7243 return status;
7244}
7245
7246#endif /*FEATURE_WLAN_SCAN_PNO*/
7247
7248
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007249#ifdef FEATURE_WLAN_TDLS
7250static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
7251 u8 *peer, u8 action_code, u8 dialog_token,
7252 u16 status_code, const u8 *buf, size_t len)
7253{
7254
7255 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
7256 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007257 u8 peerMac[6];
7258 VOS_STATUS status;
Gopichand Nakkala05922802013-03-14 12:23:19 -07007259 int max_sta_failed = 0;
Hoonki Leea34dd892013-02-05 22:56:02 -08007260 int responder;
Hoonki Leed37cbb32013-04-20 00:31:14 -07007261 long rc;
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007262
Hoonki Lee11f7dda2013-02-14 16:55:44 -08007263 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007264 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307265 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007266 "Invalid arguments");
7267 return -EINVAL;
7268 }
7269
Sameer Thalappil75ea31a2013-02-21 19:38:16 -08007270 if (pHddCtx->isLogpInProgress)
7271 {
7272 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7273 "%s:LOGP in Progress. Ignore!!!", __func__);
Gopichand Nakkala05922802013-03-14 12:23:19 -07007274 wlan_hdd_tdls_set_link_status(pAdapter, peer, eTDLS_LINK_IDLE);
Sameer Thalappil75ea31a2013-02-21 19:38:16 -08007275 return -EBUSY;
7276 }
7277
Hoonki Lee27511902013-03-14 18:19:06 -07007278 if (eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode)
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007279 {
Hoonki Lee27511902013-03-14 18:19:06 -07007280 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
7281 "%s: TDLS mode is disabled OR not enabled in FW."
7282 MAC_ADDRESS_STR " action %d declined.",
7283 __func__, MAC_ADDR_ARRAY(peer), action_code);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007284 return -ENOTSUPP;
7285 }
Lee Hoonkic1262f22013-01-24 21:59:00 -08007286
Hoonki Lee27511902013-03-14 18:19:06 -07007287 /* other than teardown frame, other mgmt frames are not sent if disabled */
7288 if (SIR_MAC_TDLS_TEARDOWN != action_code)
7289 {
7290 /* if tdls_mode is disabled to respond to peer's request */
7291 if (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode)
7292 {
7293 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
7294 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07007295 " TDLS mode is disabled. action %d declined.",
7296 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee27511902013-03-14 18:19:06 -07007297
7298 return -ENOTSUPP;
7299 }
7300 }
7301
Gopichand Nakkalab977a972013-02-18 19:15:09 -08007302 if (WLAN_IS_TDLS_SETUP_ACTION(action_code))
7303 {
Hoonki Leefb8df672013-04-10 18:20:34 -07007304 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, peer, TRUE, TRUE))
Gopichand Nakkalab977a972013-02-18 19:15:09 -08007305 {
7306 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007307 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07007308 " TDLS setup is ongoing. action %d declined.",
7309 __func__, MAC_ADDR_ARRAY(peer), action_code);
7310 return -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -08007311 }
7312 }
7313
Hoonki Lee11f7dda2013-02-14 16:55:44 -08007314 if (SIR_MAC_TDLS_SETUP_REQ == action_code ||
7315 SIR_MAC_TDLS_SETUP_RSP == action_code )
Lee Hoonkic1262f22013-01-24 21:59:00 -08007316 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -08007317 if (HDD_MAX_NUM_TDLS_STA <= wlan_hdd_tdlsConnectedPeers(pAdapter))
Lee Hoonkic1262f22013-01-24 21:59:00 -08007318 {
7319 /* supplicant still sends tdls_mgmt(SETUP_REQ) even after
7320 we return error code at 'add_station()'. Hence we have this
7321 check again in addtion to add_station().
7322 Anyway, there is no hard to double-check. */
Hoonki Lee11f7dda2013-02-14 16:55:44 -08007323 if (SIR_MAC_TDLS_SETUP_REQ == action_code)
Lee Hoonkic1262f22013-01-24 21:59:00 -08007324 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007325 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7326 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07007327 " TDLS Max peer already connected. action %d declined.",
7328 __func__, MAC_ADDR_ARRAY(peer), action_code);
Gopichand Nakkala05922802013-03-14 12:23:19 -07007329 goto error;
Lee Hoonkic1262f22013-01-24 21:59:00 -08007330 }
7331 else
7332 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -08007333 /* maximum reached. tweak to send error code to peer and return
7334 error code to supplicant */
Lee Hoonkic1262f22013-01-24 21:59:00 -08007335 status_code = eSIR_MAC_UNSPEC_FAILURE_STATUS;
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007336 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7337 "%s: " MAC_ADDRESS_STR
7338 " TDLS Max peer already connected send response status %d",
7339 __func__, MAC_ADDR_ARRAY(peer), status_code);
Gopichand Nakkala05922802013-03-14 12:23:19 -07007340 max_sta_failed = -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -08007341 /* fall through to send setup resp with failure status
7342 code */
Lee Hoonkic1262f22013-01-24 21:59:00 -08007343 }
7344 }
Hoonki Lee11f7dda2013-02-14 16:55:44 -08007345 else
7346 {
7347 hddTdlsPeer_t *pTdlsPeer;
Gopichand Nakkala4327a152013-03-04 23:22:42 -08007348 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007349 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Hoonki Lee11f7dda2013-02-14 16:55:44 -08007350 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007351 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07007352 "%s:" MAC_ADDRESS_STR " already connected. action %d declined.",
7353 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee11f7dda2013-02-14 16:55:44 -08007354 return -EPERM;
7355 }
7356 }
Lee Hoonkic1262f22013-01-24 21:59:00 -08007357 }
Hoonki Lee11f7dda2013-02-14 16:55:44 -08007358 vos_mem_copy(peerMac, peer, 6);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007359
Hoonki Lee1090c6a2013-01-16 17:40:54 -08007360#ifdef WLAN_FEATURE_TDLS_DEBUG
7361 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007362 "%s: " MAC_ADDRESS_STR " action %d, dialog_token %d status %d, len = %d",
7363 "tdls_mgmt", MAC_ADDR_ARRAY(peer),
7364 action_code, dialog_token, status_code, len);
Hoonki Lee1090c6a2013-01-16 17:40:54 -08007365#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007366
Hoonki Leea34dd892013-02-05 22:56:02 -08007367 /*Except teardown responder will not be used so just make 0*/
7368 responder = 0;
Hoonki Lee11f7dda2013-02-14 16:55:44 -08007369 if (SIR_MAC_TDLS_TEARDOWN == action_code)
Hoonki Leea34dd892013-02-05 22:56:02 -08007370 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -07007371
7372 hddTdlsPeer_t *pTdlsPeer;
7373 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peerMac);
7374
7375 if(pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
7376 responder = pTdlsPeer->is_responder;
7377 else
Hoonki Leea34dd892013-02-05 22:56:02 -08007378 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -07007379 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7380 "%s: " MAC_ADDRESS_STR " peer doesn't exist or not connected %d dialog_token %d status %d, len = %d",
7381 __func__, MAC_ADDR_ARRAY(peer), (NULL == pTdlsPeer) ? -1 : pTdlsPeer->link_status,
7382 dialog_token, status_code, len);
7383 return -EPERM;
Hoonki Leea34dd892013-02-05 22:56:02 -08007384 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007385 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007386
Hoonki Lee14621352013-04-16 17:51:19 -07007387 if ((SIR_MAC_TDLS_SETUP_RSP == action_code) ||
7388 (SIR_MAC_TDLS_DIS_RSP == action_code))
7389 {
7390 if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter)))
7391 {
7392 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
7393 "%s: Sending Disc/Setup Rsp Frame.Disable BMPS", __func__);
7394 hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
7395 }
7396 wlan_hdd_tdls_set_cap(pAdapter, peerMac, eTDLS_CAP_SUPPORTED);
7397 }
7398
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007399 /* make sure doesn't call send_mgmt() while it is pending */
7400 if (TDLS_CTX_MAGIC == pAdapter->mgmtTxCompletionStatus)
7401 {
7402 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7403 "%s: " MAC_ADDRESS_STR " action %d couldn't sent, as one is pending. return EBUSY\n",
7404 __func__, MAC_ADDR_ARRAY(peer), action_code);
7405 return -EBUSY;
7406 }
7407
7408 pAdapter->mgmtTxCompletionStatus = TDLS_CTX_MAGIC;
Gopichand Nakkalab977a972013-02-18 19:15:09 -08007409 INIT_COMPLETION(pAdapter->tdls_mgmt_comp);
7410
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007411 status = sme_SendTdlsMgmtFrame(WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
Hoonki Leea34dd892013-02-05 22:56:02 -08007412 peerMac, action_code, dialog_token, status_code, (tANI_U8 *)buf, len, responder);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007413
Gopichand Nakkalab977a972013-02-18 19:15:09 -08007414 if (VOS_STATUS_SUCCESS != status)
7415 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007416 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7417 "%s: sme_SendTdlsMgmtFrame failed!", __func__);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007418 pAdapter->mgmtTxCompletionStatus = FALSE;
Hoonki Lee14621352013-04-16 17:51:19 -07007419 wlan_hdd_tdls_check_bmps(pAdapter);
7420 goto error;
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007421 }
7422
Hoonki Leed37cbb32013-04-20 00:31:14 -07007423 rc = wait_for_completion_interruptible_timeout(&pAdapter->tdls_mgmt_comp,
7424 msecs_to_jiffies(WAIT_TIME_TDLS_MGMT));
7425
7426 if ((rc <= 0) || (TRUE != pAdapter->mgmtTxCompletionStatus))
Gopichand Nakkalab977a972013-02-18 19:15:09 -08007427 {
Hoonki Leed37cbb32013-04-20 00:31:14 -07007428 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7429 "%s: Mgmt Tx Completion failed status %ld TxCompletion %lu",
7430 __func__, rc, pAdapter->mgmtTxCompletionStatus);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007431 pAdapter->mgmtTxCompletionStatus = FALSE;
Hoonki Leed37cbb32013-04-20 00:31:14 -07007432 wlan_hdd_tdls_check_bmps(pAdapter);
7433 goto error;
Gopichand Nakkalab977a972013-02-18 19:15:09 -08007434 }
7435
Gopichand Nakkala05922802013-03-14 12:23:19 -07007436 if (max_sta_failed)
Hoonki Lee14621352013-04-16 17:51:19 -07007437 {
7438 wlan_hdd_tdls_check_bmps(pAdapter);
Gopichand Nakkala05922802013-03-14 12:23:19 -07007439 return max_sta_failed;
Hoonki Lee14621352013-04-16 17:51:19 -07007440 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -08007441
Hoonki Leea34dd892013-02-05 22:56:02 -08007442 if (SIR_MAC_TDLS_SETUP_RSP == action_code)
7443 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -08007444 wlan_hdd_tdls_set_responder(pAdapter, peerMac, TRUE);
Hoonki Leea34dd892013-02-05 22:56:02 -08007445 }
7446 else if (SIR_MAC_TDLS_SETUP_CNF == action_code)
7447 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -08007448 wlan_hdd_tdls_set_responder(pAdapter, peerMac, FALSE);
Hoonki Leea34dd892013-02-05 22:56:02 -08007449 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007450
7451 return 0;
Gopichand Nakkala05922802013-03-14 12:23:19 -07007452error:
7453 /* max_sta_failed ; we didn't set to CONNECTING for this case,
7454 because we already know that this transaction will be failed,
7455 but we weren't sure if supplicant call DISABLE_LINK or not. So,
7456 to be safe, do not change the state mahine.
7457 */
7458 if(max_sta_failed == 0 &&
7459 (WLAN_IS_TDLS_SETUP_ACTION(action_code)))
7460 wlan_hdd_tdls_set_link_status(pAdapter, peerMac, eTDLS_LINK_IDLE);
7461 return -EPERM;
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007462}
7463
7464static int wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
7465 u8 *peer, enum nl80211_tdls_operation oper)
7466{
7467 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
7468 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05307469#ifdef FEATURE_WLAN_TDLS_OXYGEN_DISAPPEAR_AP
7470 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7471 int status = 0;
7472 tANI_U8 staIdx;
7473#endif
Hoonki Lee1090c6a2013-01-16 17:40:54 -08007474#ifdef WLAN_FEATURE_TDLS_DEBUG
7475 const char *tdls_oper_str[]= {
7476 "NL80211_TDLS_DISCOVERY_REQ",
7477 "NL80211_TDLS_SETUP",
7478 "NL80211_TDLS_TEARDOWN",
7479 "NL80211_TDLS_ENABLE_LINK",
7480 "NL80211_TDLS_DISABLE_LINK",
7481 "NL80211_TDLS_UNKONW_OPER"};
7482#endif
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007483 hddTdlsPeer_t *pTdlsPeer;
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007484
Chilam Ngc4244af2013-04-01 15:37:32 -07007485 if ( NULL == pHddCtx || NULL == pHddCtx->cfg_ini || NULL == peer )
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007486 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -08007487 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chilam Ngc4244af2013-04-01 15:37:32 -07007488 "%s: Invalid arguments", __func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007489 return -EINVAL;
7490 }
Hoonki Lee1090c6a2013-01-16 17:40:54 -08007491
Sameer Thalappil75ea31a2013-02-21 19:38:16 -08007492 if (pHddCtx->isLogpInProgress)
7493 {
7494 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7495 "%s:LOGP in Progress. Ignore!!!", __func__);
7496 return -EBUSY;
7497 }
7498
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007499 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer);
7500
7501 if ( NULL == pTdlsPeer ) {
7502 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR " (oper %d) not exsting. ignored",
7503 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
7504 return -EINVAL;
7505 }
7506
Hoonki Lee1090c6a2013-01-16 17:40:54 -08007507#ifdef WLAN_FEATURE_TDLS_DEBUG
7508 if((int)oper > 4)
7509 oper = 5;
7510
7511 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007512 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
7513 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007514 tdls_oper_str[(int)oper]);
Hoonki Lee1090c6a2013-01-16 17:40:54 -08007515#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007516
7517 if( FALSE == pHddCtx->cfg_ini->fEnableTDLSSupport ||
Hoonki Lee1090c6a2013-01-16 17:40:54 -08007518 FALSE == sme_IsFeatureSupportedByFW(TDLS))
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007519 {
Hoonki Lee1090c6a2013-01-16 17:40:54 -08007520 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chilam Ngc4244af2013-04-01 15:37:32 -07007521 "TDLS Disabled in INI OR not enabled in FW. "
7522 "Cannot process TDLS commands");
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007523 return -ENOTSUPP;
7524 }
7525
7526 switch (oper) {
7527 case NL80211_TDLS_ENABLE_LINK:
7528 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007529 VOS_STATUS status;
7530
Gopichand Nakkala2f4a2822013-04-17 11:22:01 -07007531 if (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
7532 {
7533 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Staion Index %u "
7534 MAC_ADDRESS_STR " failed",
7535 __func__, pTdlsPeer->staId, MAC_ADDR_ARRAY(peer));
7536 return -EINVAL;
7537 }
7538
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007539 if (eTDLS_LINK_CONNECTED != pTdlsPeer->link_status)
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007540 {
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -07007541 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer, eTDLS_LINK_CONNECTED);
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007542 /* start TDLS client registration with TL */
7543 status = hdd_roamRegisterTDLSSTA( pAdapter, peer, pTdlsPeer->staId, pTdlsPeer->signature);
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -07007544 if (VOS_STATUS_SUCCESS == status)
7545 {
Hoonki Lee14621352013-04-16 17:51:19 -07007546 if (pTdlsPeer->is_responder == 0)
7547 {
7548 v_U8_t staId = (v_U8_t)pTdlsPeer->staId;
7549
7550 wlan_hdd_tdls_timer_restart(pAdapter,
7551 &pTdlsPeer->initiatorWaitTimeoutTimer,
7552 WAIT_TIME_TDLS_INITIATOR);
7553 /* suspend initiator TX until it receives direct packet from the
7554 reponder or WAIT_TIME_TDLS_INITIATOR timer expires */
7555 WLANTL_SuspendDataTx( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
7556 &staId, NULL);
7557 }
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -07007558 wlan_hdd_tdls_increment_peer_count(pAdapter);
7559 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007560 wlan_hdd_tdls_check_bmps(pAdapter);
7561 }
7562
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007563 }
7564 break;
7565 case NL80211_TDLS_DISABLE_LINK:
Lee Hoonkic1262f22013-01-24 21:59:00 -08007566 {
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007567 if(TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
Lee Hoonkic1262f22013-01-24 21:59:00 -08007568 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007569 long status;
7570
7571 INIT_COMPLETION(pAdapter->tdls_del_station_comp);
7572
Lee Hoonkic1262f22013-01-24 21:59:00 -08007573 sme_DeleteTdlsPeerSta( WLAN_HDD_GET_HAL_CTX(pAdapter),
7574 pAdapter->sessionId, peer );
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007575
7576 status = wait_for_completion_interruptible_timeout(&pAdapter->tdls_del_station_comp,
7577 msecs_to_jiffies(WAIT_TIME_TDLS_DEL_STA));
7578 if (status <= 0)
7579 {
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007580 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer, eTDLS_LINK_IDLE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07007581 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7582 "%s: Del station failed status %ld",
7583 __func__, status);
7584 return -EPERM;
7585 }
Hoonki Lee5305c3a2013-04-29 23:28:59 -07007586 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer, eTDLS_LINK_IDLE);
Lee Hoonkic1262f22013-01-24 21:59:00 -08007587 }
7588 else
7589 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007590 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7591 "%s: TDLS Peer Station doesn't exist.", __func__);
Lee Hoonkic1262f22013-01-24 21:59:00 -08007592 }
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05307593#ifdef FEATURE_WLAN_TDLS_OXYGEN_DISAPPEAR_AP
7594 if (pHddTdlsCtx->defer_link_lost_indication)
7595 {
7596 if (( TRUE == pHddCtx->cfg_ini->fEnableTDLSOxygenSupport ) &&
7597 (wlan_hdd_tdlsConnectedPeers(pAdapter) == 0))
7598 {
7599 status = wlan_hdd_disconnect(pAdapter, eCSR_DISCONNECT_REASON_UNSPECIFIED);
7600 if ( 0 != status)
7601 {
7602 hddLog(VOS_TRACE_LEVEL_ERROR,
7603 "%s wlan_hdd_disconnect failure, returned %d \n",
7604 __func__, (int)status );
7605 return -EINVAL;
7606 }
7607 }
7608 }
7609#endif
Lee Hoonkic1262f22013-01-24 21:59:00 -08007610 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007611 break;
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007612 case NL80211_TDLS_TEARDOWN:
7613 case NL80211_TDLS_SETUP:
7614 case NL80211_TDLS_DISCOVERY_REQ:
7615 /* We don't support in-driver setup/teardown/discovery */
7616 return -ENOTSUPP;
7617 default:
7618 return -ENOTSUPP;
7619 }
7620 return 0;
7621}
Chilam NG571c65a2013-01-19 12:27:36 +05307622
7623int wlan_hdd_cfg80211_send_tdls_discover_req(struct wiphy *wiphy,
7624 struct net_device *dev, u8 *peer)
7625{
7626 hddLog(VOS_TRACE_LEVEL_INFO, "tdls send discover req: %x %x %x %x %x %x",
7627 peer[0], peer[1], peer[2], peer[3], peer[4], peer[5]);
7628
7629 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
7630 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, NULL, 0);
7631}
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007632#endif
7633
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05307634#ifdef WLAN_FEATURE_GTK_OFFLOAD
7635/*
7636 * FUNCTION: wlan_hdd_cfg80211_update_replayCounterCallback
7637 * Callback rountine called upon receiving response for
7638 * get offload info
7639 */
7640void wlan_hdd_cfg80211_update_replayCounterCallback(void *callbackContext,
7641 tpSirGtkOffloadGetInfoRspParams pGtkOffloadGetInfoRsp)
7642{
7643
7644 hdd_adapter_t *pAdapter = (hdd_adapter_t *)callbackContext;
7645
7646 ENTER();
7647
7648 if (NULL == pAdapter)
7649 {
7650 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
7651 "%s: HDD adapter is Null", __func__);
7652 return ;
7653 }
7654
7655 if (NULL == pGtkOffloadGetInfoRsp)
7656 {
7657 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7658 "%s: pGtkOffloadGetInfoRsp is Null", __func__);
7659 return ;
7660 }
7661
7662 if (VOS_STATUS_SUCCESS != pGtkOffloadGetInfoRsp->ulStatus)
7663 {
7664 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7665 "%s: wlan Failed to get replay counter value",
7666 __func__);
7667 return ;
7668 }
7669
7670 /* Update replay counter to NL */
7671 cfg80211_gtk_rekey_notify(pAdapter->dev, pGtkOffloadGetInfoRsp->bssId,
7672 (tANI_U8 *)&pGtkOffloadGetInfoRsp->ullKeyReplayCounter, GFP_KERNEL);
7673}
7674
7675/*
7676 * FUNCTION: wlan_hdd_cfg80211_set_rekey_data
7677 * This function is used to offload GTK rekeying job to the firmware.
7678 */
7679int wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
7680 struct cfg80211_gtk_rekey_data *data)
7681{
7682 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
7683 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
7684 hdd_station_ctx_t *pHddStaCtx;
7685 tHalHandle hHal;
7686 tpSirGtkOffloadParams pGtkOffloadReqParams;
7687 eHalStatus status = eHAL_STATUS_FAILURE;
7688
7689 ENTER();
7690
7691 if (NULL == pAdapter)
7692 {
7693 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
7694 "%s: HDD adapter is Null", __func__);
7695 return -ENODEV;
7696 }
7697
7698 if (NULL == pHddCtx)
7699 {
7700 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7701 "%s: HDD context is Null!!!", __func__);
7702 return -ENODEV;
7703 }
7704
7705 if (pHddCtx->isLogpInProgress)
7706 {
7707 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
7708 "%s: LOGP in Progress. Ignore!!!", __func__);
7709 return -EAGAIN;
7710 }
7711
7712 if (pHddCtx->isLoadUnloadInProgress)
7713 {
7714 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
7715 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
7716 return -EAGAIN;
7717 }
7718
7719 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7720 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
7721 if (NULL == hHal)
7722 {
7723 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7724 "%s: HAL context is Null!!!", __func__);
7725 return -EAGAIN;
7726 }
7727
7728 pGtkOffloadReqParams =
7729 &pHddStaCtx->gtkOffloadRequestParams.gtkOffloadReqParams;
7730
7731 pGtkOffloadReqParams->ulFlags = GTK_OFFLOAD_ENABLE;
7732 memcpy(pGtkOffloadReqParams->aKCK, data->kck, NL80211_KCK_LEN);
7733 memcpy(pGtkOffloadReqParams->aKEK, data->kek, NL80211_KEK_LEN);
7734 memcpy(pGtkOffloadReqParams->bssId, &pHddStaCtx->conn_info.bssId,
7735 WNI_CFG_BSSID_LEN);
7736 memcpy(&pGtkOffloadReqParams->ullKeyReplayCounter, &data->replay_ctr,
7737 sizeof (tANI_U64));
7738
7739 if (TRUE == pHddCtx->hdd_wlan_suspended)
7740 {
7741 /* if wlan is suspended, enable GTK offload directly from here */
7742 status = sme_SetGTKOffload(hHal, pGtkOffloadReqParams,
7743 pAdapter->sessionId);
7744
7745 if (eHAL_STATUS_SUCCESS != status)
7746 {
7747 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7748 "%s: sme_SetGTKOffload failed, returned %d",
7749 __func__, status);
7750 return status;
7751 }
7752 pHddStaCtx->gtkOffloadRequestParams.requested = FALSE;
7753 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
7754 "%s: sme_SetGTKOffload successfull", __func__);
7755 }
7756 else
7757 {
7758 pHddStaCtx->gtkOffloadRequestParams.requested = TRUE;
7759 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
7760 "%s: wlan not suspended GTKOffload request is stored",
7761 __func__);
7762 return eHAL_STATUS_SUCCESS;
7763 }
7764 return status;
7765}
7766#endif /*WLAN_FEATURE_GTK_OFFLOAD*/
7767
Jeff Johnson295189b2012-06-20 16:38:30 -07007768/* cfg80211_ops */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307769static struct cfg80211_ops wlan_hdd_cfg80211_ops =
Jeff Johnson295189b2012-06-20 16:38:30 -07007770{
7771 .add_virtual_intf = wlan_hdd_add_virtual_intf,
7772 .del_virtual_intf = wlan_hdd_del_virtual_intf,
7773 .change_virtual_intf = wlan_hdd_cfg80211_change_iface,
7774 .change_station = wlan_hdd_change_station,
7775#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
7776 .add_beacon = wlan_hdd_cfg80211_add_beacon,
7777 .del_beacon = wlan_hdd_cfg80211_del_beacon,
7778 .set_beacon = wlan_hdd_cfg80211_set_beacon,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007779#else
7780 .start_ap = wlan_hdd_cfg80211_start_ap,
7781 .change_beacon = wlan_hdd_cfg80211_change_beacon,
7782 .stop_ap = wlan_hdd_cfg80211_stop_ap,
Jeff Johnson295189b2012-06-20 16:38:30 -07007783#endif
7784 .change_bss = wlan_hdd_cfg80211_change_bss,
7785 .add_key = wlan_hdd_cfg80211_add_key,
7786 .get_key = wlan_hdd_cfg80211_get_key,
7787 .del_key = wlan_hdd_cfg80211_del_key,
7788 .set_default_key = wlan_hdd_cfg80211_set_default_key,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -08007789#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07007790 .set_channel = wlan_hdd_cfg80211_set_channel,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -08007791#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007792 .scan = wlan_hdd_cfg80211_scan,
7793 .connect = wlan_hdd_cfg80211_connect,
7794 .disconnect = wlan_hdd_cfg80211_disconnect,
7795 .join_ibss = wlan_hdd_cfg80211_join_ibss,
7796 .leave_ibss = wlan_hdd_cfg80211_leave_ibss,
7797 .set_wiphy_params = wlan_hdd_cfg80211_set_wiphy_params,
7798 .set_tx_power = wlan_hdd_cfg80211_set_txpower,
7799 .get_tx_power = wlan_hdd_cfg80211_get_txpower,
Jeff Johnson295189b2012-06-20 16:38:30 -07007800 .remain_on_channel = wlan_hdd_cfg80211_remain_on_channel,
7801 .cancel_remain_on_channel = wlan_hdd_cfg80211_cancel_remain_on_channel,
7802 .mgmt_tx = wlan_hdd_action,
7803#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
7804 .mgmt_tx_cancel_wait = wlan_hdd_cfg80211_mgmt_tx_cancel_wait,
7805 .set_default_mgmt_key = wlan_hdd_set_default_mgmt_key,
7806 .set_txq_params = wlan_hdd_set_txq_params,
7807#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007808 .get_station = wlan_hdd_cfg80211_get_station,
7809 .set_power_mgmt = wlan_hdd_cfg80211_set_power_mgmt,
7810 .del_station = wlan_hdd_cfg80211_del_station,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007811 .add_station = wlan_hdd_cfg80211_add_station,
7812#ifdef FEATURE_WLAN_LFR
7813 .set_pmksa = wlan_hdd_cfg80211_set_pmksa,
7814 .del_pmksa = wlan_hdd_cfg80211_del_pmksa,
7815 .flush_pmksa = wlan_hdd_cfg80211_flush_pmksa,
7816#endif
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07007817#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
7818 .update_ft_ies = wlan_hdd_cfg80211_update_ft_ies,
7819#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007820#ifdef FEATURE_WLAN_TDLS
7821 .tdls_mgmt = wlan_hdd_cfg80211_tdls_mgmt,
7822 .tdls_oper = wlan_hdd_cfg80211_tdls_oper,
7823#endif
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05307824#ifdef WLAN_FEATURE_GTK_OFFLOAD
7825 .set_rekey_data = wlan_hdd_cfg80211_set_rekey_data,
7826#endif /* WLAN_FEATURE_GTK_OFFLOAD */
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05307827#ifdef FEATURE_WLAN_SCAN_PNO
7828 .sched_scan_start = wlan_hdd_cfg80211_sched_scan_start,
7829 .sched_scan_stop = wlan_hdd_cfg80211_sched_scan_stop,
7830#endif /*FEATURE_WLAN_SCAN_PNO */
Jeff Johnson295189b2012-06-20 16:38:30 -07007831};
7832